コード例 #1
0
        private void StoreNeighborNodes(PathNode inAround, PathNode[] inNeighbors, NeighbourClassification neighbourClassification)
        {
            int x = inAround.X;
            int y = inAround.Y;

            if ((x > 0) && (y > 0) && neighbourClassification == NeighbourClassification.ByWallAndCorner)
            {
                inNeighbors[0] = m_SearchSpace[x - 1, y - 1];
            }
            else
            {
                inNeighbors[0] = null;
            }

            if (y > 0)
            {
                inNeighbors[1] = m_SearchSpace[x, y - 1];
            }
            else
            {
                inNeighbors[1] = null;
            }

            if ((x < Width - 1) && (y > 0) && neighbourClassification == NeighbourClassification.ByWallAndCorner)
            {
                inNeighbors[2] = m_SearchSpace[x + 1, y - 1];
            }
            else
            {
                inNeighbors[2] = null;
            }

            if (x > 0)
            {
                inNeighbors[3] = m_SearchSpace[x - 1, y];
            }
            else
            {
                inNeighbors[3] = null;
            }

            if (x < Width - 1)
            {
                inNeighbors[4] = m_SearchSpace[x + 1, y];
            }
            else
            {
                inNeighbors[4] = null;
            }

            if ((x > 0) && (y < Height - 1) && neighbourClassification == NeighbourClassification.ByWallAndCorner)
            {
                inNeighbors[5] = m_SearchSpace[x - 1, y + 1];
            }
            else
            {
                inNeighbors[5] = null;
            }

            if (y < Height - 1)
            {
                inNeighbors[6] = m_SearchSpace[x, y + 1];
            }
            else
            {
                inNeighbors[6] = null;
            }

            if ((x < Width - 1) && (y < Height - 1) && neighbourClassification == NeighbourClassification.ByWallAndCorner)
            {
                inNeighbors[7] = m_SearchSpace[x + 1, y + 1];
            }
            else
            {
                inNeighbors[7] = null;
            }
        }
コード例 #2
0
        //private List<Int64> elapsed = new List<long>();

        /// <summary>
        /// Returns null, if no path is found. Start- and End-Node are included in returned path. The user context
        /// is passed to IsWalkable().
        /// </summary>
        ///
        ///
        public LinkedList <TPathNode> Search(IPoint inStartNode, IPoint inEndNode, NeighbourClassification neighbourClassification)
        {
            PathNode startNode = m_SearchSpace[inStartNode.X, inStartNode.Y];
            PathNode endNode   = m_SearchSpace[inEndNode.X, inEndNode.Y];

            //System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            //watch.Start();

            if (startNode == endNode)
            {
                return(new LinkedList <TPathNode>(new TPathNode[] { startNode.UserContext }));
            }

            PathNode[] neighborNodes = new PathNode[8];

            m_ClosedSet.Clear();
            m_OpenSet.Clear();
            m_RuntimeGrid.Clear();
            m_OrderedOpenSet.Clear();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    m_CameFrom[x, y] = null;
                }
            }

            startNode.G = 0;
            startNode.H = Heuristic(startNode, endNode);
            startNode.F = startNode.H;

            m_OpenSet.Add(startNode);
            m_OrderedOpenSet.Push(startNode);

            m_RuntimeGrid.Add(startNode);

            int nodes = 0;


            while (!m_OpenSet.IsEmpty)
            {
                PathNode x = m_OrderedOpenSet.Pop();

                if (x == endNode)
                {
                    // watch.Stop();

                    //elapsed.Add(watch.ElapsedMilliseconds);

                    LinkedList <TPathNode> result = ReconstructPath(m_CameFrom, m_CameFrom[endNode.X, endNode.Y]);

                    result.AddLast(endNode.UserContext);

                    return(result);
                }

                m_OpenSet.Remove(x);
                m_ClosedSet.Add(x);

                StoreNeighborNodes(x, neighborNodes, neighbourClassification);

                for (int i = 0; i < neighborNodes.Length; i++)
                {
                    PathNode y = neighborNodes[i];
                    Boolean  tentative_is_better;

                    if (y == null)
                    {
                        continue;
                    }

                    if (!y.UserContext.IsWalkable())
                    {
                        continue;
                    }

                    if (m_ClosedSet.Contains(y))
                    {
                        continue;
                    }

                    nodes++;

                    Double  tentative_g_score = m_RuntimeGrid[x].G + NeighborDistance(x, y);
                    Boolean wasAdded          = false;

                    if (!m_OpenSet.Contains(y))
                    {
                        m_OpenSet.Add(y);
                        tentative_is_better = true;
                        wasAdded            = true;
                    }
                    else if (tentative_g_score < m_RuntimeGrid[y].G)
                    {
                        tentative_is_better = true;
                    }
                    else
                    {
                        tentative_is_better = false;
                    }

                    if (tentative_is_better)
                    {
                        m_CameFrom[y.X, y.Y] = x;

                        if (!m_RuntimeGrid.Contains(y))
                        {
                            m_RuntimeGrid.Add(y);
                        }

                        m_RuntimeGrid[y].G = tentative_g_score;
                        m_RuntimeGrid[y].H = Heuristic(y, endNode);
                        m_RuntimeGrid[y].F = m_RuntimeGrid[y].G + m_RuntimeGrid[y].H;

                        if (wasAdded)
                        {
                            m_OrderedOpenSet.Push(y);
                        }
                        else
                        {
                            m_OrderedOpenSet.Update(y);
                        }
                    }
                }
            }

            return(null);
        }