public Form1() { InitializeComponent(); this.DoubleBuffered = true; this.BackColor = Color.Black; w = (Width) / Cols; h = (Height) / Rows; this.WindowState = FormWindowState.Maximized; Spots = new Dictionary <Point, Spot>(); OpenSet = new OpenSet(Color.Green); ClosedSet = new ClosedSet(Color.Red); MainPath = new List <Spot>(); Random Ran = new Random(10000000); for (int i = 0; i < Cols; i++) { for (int j = 0; j < Rows; j++) { Spot spot = new Spot(i, j, w, h, Color.White, Ran); KeyValuePair <Point, Spot> pair = new KeyValuePair <Point, Spot>(spot.Point, spot); Spots.Add(spot.Point, spot); if (i == Cols - 1 && j == Rows - 1) { End = spot.Point; } } } //Spot s = Spots.Last().Value; foreach (KeyValuePair <Point, Spot> item in Spots) { item.Value.FindNeighbours(Spots, Cols, Rows); } Astar algorithm = new Astar(Spots, End); algorithm.InvalidateCaller += RefreshForm; ThreadPool.QueueUserWorkItem(new WaitCallback(algorithm.FindPath)); }
public Astar(Dictionary <Point, Spot> spots, Point end) { OpenSet = new OpenSet(Color.Green); ClosedSet = new ClosedSet(Color.Red); MainPath = new List <Spot>(); Spots = spots; End = end; }
////////////////////////////////////////////////////////////////////////// private void _ImplementPathfinding(int checks) { // do while has variants while (checks-- > 0) { // not found if (OpenSet.Count == 0) { Complete(FindPathResult.NotReachable); return; } // limit achieved if (ClosedSet.Count >= Options.CheckLimit) { Complete(FindPathResult.Overwhelm); return; } // get next node var currentNode = OpenSet.First(); // close current, move from open to close set OpenSet.Remove(currentNode); ClosedSet.Add(currentNode.Master); ClosedNodes.AddLast(currentNode); // goal check if (Goal.Any(n => n.Equals(currentNode.Master))) { getPath(currentNode, Path); Complete(FindPathResult.Found); return; } // proceed connections foreach (var neighborNode in Explorer.GetNeighbours(currentNode.Master)) { // skip if not passable if (neighborNode == null || Explorer.Passable(neighborNode) == false) { continue; } // IsClosed, skip if already checked if (ClosedSet.Contains(neighborNode)) { continue; } var pathCost = currentNode.PathCost + Explorer.GetPathCost(currentNode.Master, neighborNode); var openNode = OpenSet.FirstOrDefault(pathNode => pathNode.Master.Equals(neighborNode)); if (openNode != null) { // if presented and part is shorter, then reset his parent and cost if (openNode.PathCost > pathCost) { openNode.СameFrom = currentNode; openNode.PathCost = pathCost; // update priority openNode.Cost = openNode.PathCostEstimated + openNode.PathCost; OpenSet.UpdatePriority(openNode, openNode.Cost); } } else { // if not presented, add as variant var pathNode = new PathNode <T>(neighborNode); pathNode.СameFrom = currentNode; pathNode.PathCost = pathCost; if (Options.Heuristic) { pathNode.PathCostEstimated = getShortestPath(Explorer, pathNode.Master, Goal); pathNode.Cost = pathNode.PathCostEstimated + pathNode.PathCost; } else { pathNode.Cost = pathNode.PathCost; } OpenSet.Enqueue(pathNode, pathNode.Cost); } } } ///////////////////////////////////// float getShortestPath(iExplorer <T> explorer, T start, IEnumerable <T> goal) { var shortestPath = float.MaxValue; // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator foreach (var n in goal) { var currentShortestPath = explorer.GetShortestPath(start, n); if (shortestPath > currentShortestPath) { shortestPath = currentShortestPath; } } return(shortestPath); } void getPath(PathNode <T> pathNode, LinkedList <T> path) { for (var currentNode = pathNode; currentNode != null; currentNode = currentNode.СameFrom) { path.AddFirst(currentNode.Master); } } }