public static IEnumerable <HexCoords> AStar(this MapUnit unit, HexCoords dst) { Dictionary <HexCoords, PathNode> result = new Dictionary <HexCoords, PathNode>(); PriorityQueue <PathNode> frontier = new PriorityQueue <PathNode>(); frontier.Enqueue(new PathNode( 0, unit.Heuristic(unit.loc, dst), null, unit.loc)); while (frontier.Count > 0) { PathNode current = frontier.Dequeue(); // If we've arrived if (current.loc == dst) { return(current.pathTo); } // If we already have a path to this location that's at least this cheap, // don't repeat it if (!result.IsRedundant(current)) { // If we can stay in the current location, mark it down as a destination if (unit.CanStay(current.loc)) { result[current.loc] = current; } // If we can leave the current location, try entering neighboring locations int movesRemaining = (int)unit.moveRange - current.costToNode; if ((movesRemaining > 0) && unit.CanLeave(current.loc)) { // If we can enter any neighboring locations, try to do so later. IEnumerable <MapCell> neighborCells = current.loc.neighbors .Where(map.InBounds) .Select(map.CellAt) .Where(unit.CanEnter); foreach (MapCell neighbor in neighborCells) { frontier.Enqueue(new PathNode( current.costToNode + 1, current, neighbor.loc)); } } } } return(null); }
public static bool CanLeave( this MapUnit unit, HexCoords loc) { if (!map.InBounds(loc)) { return(false); } else { return(unit.CanLeave(map[loc])); } }
public static IDictionary <HexCoords, PathNode> Dijkstra(this MapUnit unit, int maxCost = int.MaxValue) { Dictionary <HexCoords, PathNode> result = new Dictionary <HexCoords, PathNode>(); Queue <PathNode> frontier = new Queue <PathNode>(); frontier.Enqueue(new PathNode( 0, null, unit.loc)); while (frontier.Count > 0) { PathNode current = frontier.Dequeue(); // If we already have a path to this location that's at least this cheap, // don't repeat it if (!result.IsRedundant(current)) { // If we can stay in the current location, mark it down as a destination result[current.loc] = current; // If we can leave the current location, try entering neighboring locations int movesRemaining = maxCost - current.costToNode; if ((movesRemaining > 0) && unit.CanLeave(current.loc)) { // If we can enter any neighboring locations, try to do so later. IEnumerable <MapCell> neighborCells = current.loc.neighbors .Where(map.InBounds) .Select(map.CellAt) .Where(unit.CanEnter); var q = neighborCells.ToList(); foreach (MapCell neighbor in neighborCells) { frontier.Enqueue(new PathNode( current.costToNode + 1, current, neighbor.loc)); } } } } return(result); }