Beispiel #1
0
        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));
        }
Beispiel #2
0
        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;
        }
Beispiel #3
0
        //////////////////////////////////////////////////////////////////////////
        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);
                }
            }
        }