示例#1
0
        //---------------------------------------------------------------------------------------------

        public void RemoveDiagonalCorners(PathNode parent, PathBuilder builder)
        {
            int count = this.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                PathNode current = this[i];
                if (current.DiagonalToParent)
                {
                    PathNodeList currentAdje = builder.FindAdjacentNodes(current);
                    currentAdje.MergePossible(this);
                    if (currentAdje.Count == 1 || currentAdje.Count == 0)
                    {
                        this.RemoveAt(i);
                    }
                }
            }
        }
示例#2
0
        public bool ComputePath(PathNode start, PathNode end, int fromDistance)
        {
            OpenNodes  = new PathNodeList();
            CloseNodes = new PathNodeList();
            PathNode current = start;

            start.G = 0;
            start.H = ComputeH(start, end);

            if (!OpenNodes.ContainsNode(start))
            {
                OpenNodes.Add(start);
            }

            bool finish = false;
            bool result = false;

            if (!this.PossibleNodes.ContainsNode(start))
            {
                this.PossibleNodes.Add(start);
            }

            if (!this.PossibleNodes.ContainsNode(end))
            {
                this.PossibleNodes.Add(end);
            }

            while (!finish && Searchs < 10000)
            {
                Searchs++;
                OpenNodes.Remove(current);
                if (!CloseNodes.ContainsNode(current))
                {
                    CloseNodes.Add(current);
                }

                PathNodeList searchNodes = FindAdjacentNodes(current);

                foreach (PathNode node in searchNodes)
                {
                    if (!this.PossibleNodes.ContainsNode(node))
                    {
                        this.PossibleNodes.Add(node);
                    }
                }

                searchNodes.MergePossible(this.PossibleNodes);
                searchNodes.RemoveDiagonalCorners(current, this);

                if (searchNodes.Count > 0)
                {
                    searchNodes.MergeIdent(CloseNodes);
                }
                else
                {
                    PathNodeList adjNodes = FindAdjacentNodes(current);
                    foreach (PathNode adj in adjNodes)
                    {
                        PathNode sNode = this.PossibleNodes.FindNode(adj.X, adj.Y);
                        if (sNode == null)
                        {
                            sNode = adj;
                            this.PossibleNodes.Add(sNode);
                        }
                        sNode.Walkable = null;

                        searchNodes.Add(sNode);
                    }
                    searchNodes.RemoveDiagonalCorners(current, this);
                }

                searchNodes.NormalizeReferences(OpenNodes);

                PathNode bestNode = null;
                foreach (PathNode searchNode in searchNodes)
                {
                    if (!OpenNodes.ContainsNode(searchNode))
                    {
                        searchNode.Parent = current;
                        searchNode.H      = ComputeH(searchNode, end);
                        searchNode.G      = ComputeG(searchNode.Parent, searchNode);
                        OpenNodes.Add(searchNode);
                    }
                    else if (searchNode.G > (current.G + (searchNode.DiagonalToParent ? 14 : 10)))
                    {
                        searchNode.Parent = current;
                        searchNode.H      = ComputeH(searchNode, end);
                        searchNode.G      = ComputeG(searchNode.Parent, searchNode);
                    }
                }

                foreach (PathNode openNode in OpenNodes)
                {
                    if (bestNode == null || (openNode.F < bestNode.F))
                    {
                        bestNode = openNode;
                    }
                }

                if (bestNode == null)
                {
                    finish = true;
                }
                else if (bestNode.H == (fromDistance * 10))
                {
                    OpenNodes.Remove(bestNode);
                    if (!CloseNodes.ContainsNode(bestNode))
                    {
                        CloseNodes.Add(bestNode);
                    }

                    bestNode.Finish = true;
                    result          = true;
                    finish          = true;
                }

                current = bestNode;
            }
            return(result);
        }