/// <summary> /// Check neighbours and add them to OpenSet if: /// <para>- met them for the first time</para> /// <para>- found bettter way to this cell</para> /// </summary> /// <param name="currentCell">The cell which heighbour should be checked</param> private void Explore(ACell currentCell) { // for each neighbours (event current), which are not in the ClosedSet(aka Visited) foreach (Cell neighbour in maze.GetNeighbours(currentCell.Cell, (cell) => cell.Type != CellType.Visited)) { double WayFromStartToThisNeighbour = currentCell.WayFromStartToThisCell + 1; // check if neighbour is in OpenSet ACell aNeighbourInOpen = openSet.FirstOrDefault(acell => acell.Cell == neighbour); // if neighbour is not in OpenSet or his Way value is worse that we found... if (aNeighbourInOpen == null || aNeighbourInOpen.WayFromStartToThisCell > WayFromStartToThisNeighbour) { aNeighbourInOpen = aNeighbourInOpen ?? new ACell(neighbour); // create new if needed openSet.Add(aNeighbourInOpen); // add if needed // update values aNeighbourInOpen.Cell.Type = CellType.Current; aNeighbourInOpen.WayFromStartToThisCell = WayFromStartToThisNeighbour; aNeighbourInOpen.ShortestWay = aNeighbourInOpen.WayFromStartToThisCell + CalcWayToEnd(aNeighbourInOpen.Cell); aNeighbourInOpen.Cell.Previous = currentCell.Cell; System.Threading.Thread.Sleep(delay); } } }
public void RefreshBoardData(AGoose goose, ACell destCell) { //Refresh goose and board data Cells[goose.CurrentCellIndex].Occupant = null; goose.CurrentCellIndex = destCell.Index; destCell.Occupant = goose; }
// METHODS public override bool Search() { this.Clear(); this.openSet.Add(new ACell(start)); // while there are known cells ... while (openSet.Count != 0) { // ... get cell with shortest way ACell shortest = openSet.Min(); // if it is goal... if (shortest.Cell == goal) { // ... the path has been found lastPos = shortest.Cell; return(true); } // if it is not goal, explore this cell Explore(shortest); // cell fully explored, move it from OpenSet to ClosedSet shortest.Cell.Type = CellType.Visited; openSet.Remove(shortest); closedSet.Add(shortest.Cell); } // no valid path return(false); }
private void Cell_PropertyChanged(object sender, PropertyChangedEventArgs e) // when ACell property is changed, this even is triggered { if (e.PropertyName == "Text") // If property changed was Text { (sender as Cell).EditValue = evaluateText((sender as Cell).Text); // Evaluate new Text value to new Value value changed = (sender as Cell); // Update current cell changed CellPropertyChanged(this, new PropertyChangedEventArgs("Text")); // Trigger event for UI } }
public IEnumerator MoveRoutine(AGoose goose, int nbCells) { //Init variable used for all the move currentTransform = goose.Transform; int it = (int)Mathf.Sign(nbCells); ACell currentCell = BoardManager.Cells[goose.CurrentCellIndex]; //Put after mustMove to prevent wrong first time direction partialDestPosition = BoardManager.Cells[currentCell.Index + it].Waypoint.position; dir = (partialDestPosition - currentCell.Waypoint.position).normalized; mustMove = true; while (mustMove) { //Verify if the destination is after the last cell int partialDestIndex = currentCell.Index + it; if (partialDestIndex >= BoardManager.NB_CELLS) { it = -it; //Move to the other direction nbCells = -nbCells; //Move to the other direction partialDestIndex += 2 * it; //Compensation for the previous add } //Refresh partialDestPosition and dir ACell partialDestCell = BoardManager.Cells[partialDestIndex]; partialDestPosition = partialDestCell.Waypoint.position; dir = (partialDestPosition - currentCell.Waypoint.position).normalized; //Wait until partial move is done yield return(new WaitUntil(() => donePartialMove)); donePartialMove = false; //partial move is not done anymore nbCells -= it; //Remove nb cell to move by 1 //Move done verification currentCell = partialDestCell; if (nbCells == 0) { mustMove = false; } } //Is there an other goose at destination ? if (currentCell.Occupied()) { Move(currentCell.Occupant, -1); } else { currentCell.TryEndTurn(goose); } OnMoved(goose, currentCell); currentCell.OnMoved(goose); currentCell.PlayOnMovedSound(); }
public bool canAccess(ACell _cell) { Way way = whichNeighbor(_cell); if (way == Way.None) { return(false); } switch (way) { case Way.North: if (m_wallN != null || _cell.m_wallS) { return(false); } else { return(true); } case Way.East: if (m_wallE != null || _cell.m_wallW) { return(false); } else { return(true); } case Way.South: if (m_wallS != null || _cell.m_wallN) { return(false); } else { return(true); } case Way.West: if (m_wallW != null || _cell.m_wallE) { return(false); } else { return(true); } } return(false); }
public IEnumerator hunt() { m_state = State.CreatingPath; while (m_state == State.CreatingPath) { WaitForSeconds delay = new WaitForSeconds(huntDelay); ACell cell = m_stack.Peek() as ACell; cell.Visited = true; if (AllVisited()) { m_state = State.Finished; yield break; } List <ACell> possibleCell = new List <ACell>(); possibleCell = cell.NeighborList; bool again; do { again = false; foreach (StandardCell neighbor in possibleCell) { if (neighbor.Visited) { possibleCell.Remove(neighbor); again = true; break; } } } while (again); // Debug.Log("-->nb dans la stack: " + m_stack.Count); if (possibleCell.Count <= 0) { m_stack.Pop(); } else { int nextCell = Random.Range(0, possibleCell.Count); //Debug.Log(">next cell: " + possibleCell[nextCell].name); cell.PathTo(possibleCell[nextCell]); m_stack.Push(possibleCell[nextCell]); } yield return(delay); } }
public override bool Equals(object obj) { if (obj.GetType().Equals(typeof(Cell))) { Cell a = (Cell)obj; return(Equals(a)); } else if (obj.GetType().Equals(typeof(ACell))) { ACell o = (ACell)obj; return(this.main.worldPosition == o.main.worldPosition); } else { return(false); } }
public void FindNeighbors() { GameObject[] _cells = GameObject.FindGameObjectsWithTag("CellShell"); m_neighbors = new Hashtable(); for (int i = 0; i < _cells.Length; i++) { ACell cell = _cells[i].GetComponent <ACell>(); float distance = Vector3.Distance(transform.position, cell.transform.position); //Si la distance == floor.transforme.scale.x/z alors c'est un voisin direct (ligne droite) if (distance == m_floor.transform.localScale.x) { if (cell.transform.position.x == transform.position.x + m_floor.transform.localScale.x && cell.transform.position.z == transform.position.z) { m_neighbors.Add("North", cell); } if (cell.transform.position.x == transform.position.x && cell.transform.position.z == transform.position.z - m_floor.transform.localScale.z) { m_neighbors.Add("East", cell); } if (cell.transform.position.x == transform.position.x - m_floor.transform.localScale.x && cell.transform.position.z == transform.position.z) { m_neighbors.Add("South", cell); } if (cell.transform.position.x == transform.position.x && cell.transform.position.z == transform.position.z + m_floor.transform.localScale.z) { m_neighbors.Add("West", cell); } } } /*Debug.Log(name + " voisins: "); * Debug.Log("---> N: " + m_neighbors["North"]); * Debug.Log("---> E: " + m_neighbors["East"]); * Debug.Log("---> S: " + m_neighbors["South"]); * Debug.Log("---> W: " + m_neighbors["West"]); * Debug.Log(this.NeighborList.Count); * Debug.Log("----------------------------------------\n");*/ }
public void PathTo(ACell _cell) { //suprimer le mur qui sépare la cell de la suivante && supprimer le mur opposé du voisin Way way = whichNeighbor(_cell); switch (way) { case Way.North: //Debug.Log("--->to the north"); Destroy(m_wallN); Destroy(_cell.m_wallS); break; case Way.East: //Debug.Log("--->to the east"); Destroy(m_wallE); Destroy(_cell.m_wallW); break; case Way.South: //Debug.Log("--->to the south"); Destroy(m_wallS); Destroy(_cell.m_wallN); break; case Way.West: //Debug.Log("--->to the west"); Destroy(m_wallW); Destroy(_cell.m_wallE); break; } //=========================================== Mode debug //Vector3 to = _cell.transform.position; //to.y += m_wallPrefab.transform.localScale.y / 2; //GameObject tmpCube = Instantiate(debugTo, to, new Quaternion()); //tmpCube.name = "cube"; }
protected Way whichNeighbor(ACell _cell) { if (_cell == NeighborNorth) { return(Way.North); } if (_cell == NeighborEast) { return(Way.East); } if (_cell == NeighborSouth) { return(Way.South); } if (_cell == NeighborWest) { return(Way.West); } return(Way.None); }
public void GetPath(Cell start, Cell end) { //Closed and open sets closedSet.Clear(); open.Clear(); //Holds result trajectory.Clear(); currentDestination = end; ACell first = new ACell(start); open.Add(first); List <Cell> result = new List <Cell>(); while (open.Count > 0) { //Get first node by sorting by smallest f cost and picking that ACell current = open[0]; for (int i = 1; i < open.Count; i++) { if (open[i].f < current.f || (open[i].f == current.f && open[i].h < current.h)) { current = open[i]; } } open.Remove(current); if (current.main == null || current == null) { continue; } closedSet.Add(current.main.worldPosition); if (current.main.worldPosition == end.worldPosition) { while (current != null) { result.Insert(0, current.main); current = current.parent; } trajectory = result; moveList = trajectory; return; } List <Cell> neighbours = grid.GetNeighbours(current.main); foreach (Cell n in neighbours) { ACell neighbour = new ACell(n); if (closedSet.Contains(n.worldPosition)) { continue; } float newDistFromStart = current.g + GetDistance(current.main, n); if (newDistFromStart < neighbour.g || !open.Contains(neighbour)) { open.Remove(neighbour); neighbour.g = newDistFromStart; neighbour.h = GetDistance(neighbour.main, end); neighbour.parent = current; //Remove if it exists so we can store the new updated value open.Add(neighbour); } } } }
public ACell(Cell a, ACell p) { main = a; parent = p; }
public ACell(Cell a) { main = a; parent = null; }