void Preparation() { //Clean Board CleanBoard(); //Get used tile type tileType = BoardManager.instance.tileType; //Set up open list openList = new List <TileScript>(); //Set origin's movement cost to 0 and add to open list origin.movementCost = 0.0f; openList.Add(origin); //Go to next stage stage = (PathfindingStage)((int)stage + 1); }
void RetracePath() { //Set up retrace list List <TileScript> retraceList = new List <TileScript>(); List <Vector3> posList = new List <Vector3>(); TileScript retraceTile = destination; while (retraceTile != null) { if (retraceTile.state != TileState.Origin && retraceTile.state != TileState.Destination) //Do not replace color for these tiles { retraceTile.state = TileState.Path; } retraceList.Add(retraceTile); posList.Add(retraceTile.transform.position); if (retraceTile == origin) { break; } retraceTile = retraceTile.parentTile; } //Draw Retrace Line if (posList.Count <= 1) //No Solution { retraceLine.gameObject.SetActive(false); } else { retraceLine.positionCount = posList.Count; retraceLine.SetPositions(posList.ToArray()); retraceLine.gameObject.SetActive(true); } //Go to next stage stage = (PathfindingStage)((int)stage + 1); }
void SearchingOpenList() { //While open list is not empty if (openList.Count > 0 && !destination.isChecked) { //Set current tile as first in the list TileScript currentTile = openList[0]; //Find tile with smallest movement cost for (int i = 1; i < openList.Count; i++) { float newHeuristic = 0.0f; float curHeuristic = 0.0f; if (algorithm == PathfindingAlgorithm.AStar) { if (tileType == TileType.Square) { Square newSqr = ((SquareScript)openList[i]).position; Square curSqr = ((SquareScript)currentTile).position; newHeuristic = newSqr.GetHeuristic(destination.x, destination.y); curHeuristic = curSqr.GetHeuristic(destination.x, destination.y); } else if (tileType == TileType.Hex) { Hex newHex = ((HexScript)openList[i]).position; Hex curHex = ((HexScript)currentTile).position; newHeuristic = newHex.GetHeuristic(destination.x, destination.y); curHeuristic = curHex.GetHeuristic(destination.x, destination.y); } newHeuristic *= weight; curHeuristic *= weight; } if (openList[i].movementCost + newHeuristic < currentTile.movementCost + curHeuristic) { currentTile = openList[i]; } } //Remove current tile from open list currentTile.isChecked = true; openList.Remove(currentTile); if (tileType == TileType.Square) { //Get neighbours of current tile Square s = ((SquareScript)currentTile).position; Square[] neighbours = s.GetNeighbours(); for (int i = 0; i < neighbours.Length; i++) { //Check if coordinate is valid if ( neighbours[i].y < 0 || neighbours[i].y >= tileBoard.GetLength(0) || neighbours[i].x < 0 || neighbours[i].x >= tileBoard.GetLength(1) ) { continue; } //Transform coordinate back to TileScript TileScript neighbour = BoardManager.instance.GetTile(neighbours[i].x, neighbours[i].y); //Skip if neighbour doesn't exist if (neighbour == null) { continue; } //Skip if neighbour is an obstacle if (neighbour.isObstacle) { continue; } //Skip if crossing diagonal gaps if (checkDiagonals && !canCrossDiagonalGaps && i % 2 != 0) { TileScript prevNeighbour = BoardManager.instance.GetTile(s.GetNeighbour(i - 1).x, s.GetNeighbour(i - 1).y); TileScript nextNeighbour = BoardManager.instance.GetTile(s.GetNeighbour(i + 1).x, s.GetNeighbour(i + 1).y); if (prevNeighbour.isObstacle && nextNeighbour.isObstacle) //Do not cross diagonal gaps { continue; } } //Skip if neighbour is checked if (neighbour.isChecked) { continue; } //New current tile's neighbour movement cost float newCost = currentTile.movementCost + s.GetCost(i); //If new cost is smaller, replace it and set parent tile if (newCost < neighbour.movementCost) { neighbour.movementCost = newCost; neighbour.parentTile = currentTile; if (!openList.Contains(neighbour)) { openList.Add(neighbour); } } } } else if (tileType == TileType.Hex) { //Get neighbours of current tile Hex h = ((HexScript)currentTile).position; Hex[] neighbours = h.GetNeighbours(); for (int i = 0; i < neighbours.Length; i++) { //Check if coordinate is valid if ( neighbours[i].ToArrayPos(BoardManager.instance.boardSize).y < 0 || neighbours[i].ToArrayPos(BoardManager.instance.boardSize).y >= tileBoard.GetLength(0) || neighbours[i].ToArrayPos(BoardManager.instance.boardSize).x < 0 || neighbours[i].ToArrayPos(BoardManager.instance.boardSize).x >= tileBoard.GetLength(1) ) { continue; } //Transform coordinate back to TileScript TileScript neighbour = BoardManager.instance.GetTile(neighbours[i].x, neighbours[i].y); //Skip if neighbour doesn't exist if (neighbour == null) { continue; } //Skip if neighbour is an obstacle if (neighbour.isObstacle) { continue; } //Skip if neighbour is checked if (neighbour.isChecked) { continue; } //New current tile's neighbour movement cost float newCost = currentTile.movementCost + h.GetCost(i); //If new cost is smaller, replace it and set parent tile if (newCost < neighbour.movementCost) { neighbour.movementCost = newCost; neighbour.parentTile = currentTile; if (!openList.Contains(neighbour)) { openList.Add(neighbour); } } } } } else { //Go to next stage stage = (PathfindingStage)((int)stage + 1); } }
public void FindPath() { stage = PathfindingStage.Preparation; isRunning = true; isPaused = false; }