public Fringe(HeuristicFunc heuristic) { Heuristic = heuristic; }
private Node GetNode(Tile t, Node parent, IDictionary <Tile, Node> nodes, CostFunc getCost, HeuristicFunc getH) { Node newNode = new Node(parent, t, getCost(t, parent?.Value), getH(t)); Node existingNode; if (nodes.TryGetValue(t, out existingNode) && existingNode.F <= newNode.F) { return(existingNode); } nodes[t] = newNode; return(newNode); }
/// <summary>Dijkstra pathfinder with heuristic</summary> /// <param name="start">Starting tile</param> /// <param name="getCost">Cost function for the tile, also tells pathfinder when to stop and where walls are</param> /// <param name="getH">Heuristic function for the tile</param> /// <returns>The path, or <seealso cref="Enumerable.Empty{Tile}"/> if no path found</returns> private IEnumerable <Tile> FindPathCustom(Tile start, CostFunc getCost, HeuristicFunc getH) { Dictionary <Tile, Node> nodes = new Dictionary <Tile, Node>(); List <Node> openList = new List <Node> { this.GetNode(start, null, nodes, getCost, getH) }; HashSet <string> closedList = new HashSet <string>(); while (openList.Any()) { // Get current tile and close it Node curNode = openList.First(); Tile curTile = curNode.Value; openList.Remove(curNode); closedList.Add(curTile.Id); // Skip it if it's a wall and not the first tile if (curNode.Cost < 0 && curTile != start) { continue; } // Check if done // ReSharper disable once CompareOfFloatsByEqualityOperator if (curNode.Cost == 0) { Stack <Tile> path = new Stack <Tile>(); while (curNode != null) { path.Push(curNode.Value); curNode = curNode.Parent; } return(path); } // Add neighbors Tile neighbor = curTile.TileNorth; if (neighbor != null && !closedList.Contains(neighbor.Id)) { openList.RemoveAll(n => n.Value.Id == neighbor.Id); openList.Add(this.GetNode(neighbor, curNode, nodes, getCost, getH)); } neighbor = curTile.TileEast; if (neighbor != null && !closedList.Contains(neighbor.Id)) { openList.RemoveAll(n => n.Value.Id == neighbor.Id); openList.Add(this.GetNode(neighbor, curNode, nodes, getCost, getH)); } neighbor = curTile.TileSouth; if (neighbor != null && !closedList.Contains(neighbor.Id)) { openList.RemoveAll(n => n.Value.Id == neighbor.Id); openList.Add(this.GetNode(neighbor, curNode, nodes, getCost, getH)); } neighbor = curTile.TileWest; if (neighbor != null && !closedList.Contains(neighbor.Id)) { openList.RemoveAll(n => n.Value.Id == neighbor.Id); openList.Add(this.GetNode(neighbor, curNode, nodes, getCost, getH)); } // Sort openList openList.Sort((a, b) => (int)(a.F - b.F)); } return(Enumerable.Empty <Tile>()); }
public AStar(HeuristicFunc heuristic) { Heuristic = heuristic; }