public static List <Tile> FindPath_GreedyBestFirstSearch(TileGrid grid, Tile start, Tile end, List <IVisualStep> outSteps) { // Visual stuff outSteps.Add(new MarkStartTileStep(start)); outSteps.Add(new MarkEndTileStep(end)); // ~Visual stuff Comparison <Tile> heuristicComparison = (lhs, rhs) => { float lhsCost = GetEuclideanHeuristicCost(lhs, end); float rhsCost = GetEuclideanHeuristicCost(rhs, end); return(lhsCost.CompareTo(rhsCost)); }; MinHeap <Tile> frontier = new MinHeap <Tile>(heuristicComparison); frontier.Add(start); HashSet <Tile> visited = new HashSet <Tile>(); visited.Add(start); start.PrevTile = null; while (frontier.Count > 0) { Tile current = frontier.Remove(); // Visual stuff if (current != start && current != end) { outSteps.Add(new VisitTileStep(current)); } // ~Visual stuff if (current == end) { break; } foreach (var neighbor in grid.GetNeighbors(current)) { if (!visited.Contains(neighbor)) { frontier.Add(neighbor); visited.Add(neighbor); neighbor.PrevTile = current; // Visual stuff if (neighbor != end) { outSteps.Add(new PushTileInFrontierStep(neighbor, 0)); } // ~Visual stuff } } } List <Tile> path = BacktrackToPath(end); // Visual stuff foreach (var tile in path) { if (tile == start || tile == end) { continue; } outSteps.Add(new MarkPathTileStep(tile)); } // ~Visual stuff return(path); }
public static List <Tile> FindPath_Dijkstra(TileGrid grid, Tile start, Tile end, List <IVisualStep> outSteps) { // Visual stuff outSteps.Add(new MarkStartTileStep(start)); outSteps.Add(new MarkEndTileStep(end)); // ~Visual stuff foreach (var tile in grid.Tiles) { tile.Cost = int.MaxValue; } start.Cost = 0; HashSet <Tile> visited = new HashSet <Tile>(); visited.Add(start); MinHeap <Tile> frontier = new MinHeap <Tile>((lhs, rhs) => lhs.Cost.CompareTo(rhs.Cost)); frontier.Add(start); start.PrevTile = null; while (frontier.Count > 0) { Tile current = frontier.Remove(); // Visual stuff if (current != start && current != end) { outSteps.Add(new VisitTileStep(current)); } // ~Visual stuff if (current == end) { break; } foreach (var neighbor in grid.GetNeighbors(current)) { int newNeighborCost = current.Cost + neighbor.Weight; if (newNeighborCost < neighbor.Cost) { neighbor.Cost = newNeighborCost; neighbor.PrevTile = current; } if (!visited.Contains(neighbor)) { visited.Add(neighbor); frontier.Add(neighbor); // Visual stuff if (neighbor != end) { outSteps.Add(new PushTileInFrontierStep(neighbor, neighbor.Cost)); } // ~Visual stuff } } } List <Tile> path = BacktrackToPath(end); // Visual stuff foreach (var tile in path) { if (tile == start || tile == end) { continue; } outSteps.Add(new MarkPathTileStep(tile)); } // ~Visual stuff return(path); }
private static BreadCrumb FindPathReversed(Grid world, Point start, Point end) { var openList = new MinHeap <BreadCrumb>(256); var brWorld = new BreadCrumb[world.Right, world.Top]; var current = new BreadCrumb(start) { Cost = 0 }; var finish = new BreadCrumb(end); brWorld[current.Position.X, current.Position.Y] = current; openList.Add(current); while (openList.Count > 0) { //Find best item and switch it to the 'closedList' current = openList.ExtractFirst(); current.OnClosedList = true; //Find neighbours for (var i = 0; i < Surrounding.Length; i++) { var tmp = new Point(current.Position.X + Surrounding[i].X, current.Position.Y + Surrounding[i].Y); if (!world.ConnectionIsValid(current.Position, tmp)) { continue; } try { //Check if we've already examined a neighbour, if not create a new node for it. BreadCrumb node; if (brWorld[tmp.X, tmp.Y] == null) { node = new BreadCrumb(tmp); brWorld[tmp.X, tmp.Y] = node; } else { node = brWorld[tmp.X, tmp.Y]; } //If the node is not on the 'closedList' check it's new score, keep the best if (!node.OnClosedList) { var diff = 0; if (current.Position.X != node.Position.X) { diff += 1; } if (current.Position.Y != node.Position.Y) { diff += 1; } var distance = (int)Mathf.Pow( Mathf.Max(Mathf.Abs(end.X - node.Position.X), Mathf.Abs(end.Y - node.Position.Y)), 2); var cost = current.Cost + diff + distance; if (cost < node.Cost) { node.Cost = cost; node.Next = current; } //If the node wasn't on the openList yet, add it if (!node.OnOpenList) { //Check to see if we're done if (node.Equals(finish)) { node.Next = current; return(node); } node.OnOpenList = true; openList.Add(node); } } } catch (Exception e) { Debug.LogWarning(tmp); } } } return(null); //no path found }