Ejemplo n.º 1
0
 public bool search()
 {
     try
     {
         long node    = ANode.GetGUID(this._startNodeX, this._startNodeY);
         long endNode = ANode.GetGUID(this._endNodeX, this._endNodeY);
         int  nodex;
         int  nodey;
         while (node != endNode)
         {
             nodex = ANode.GetGUID_X(node);
             nodey = ANode.GetGUID_Y(node);
             int startX = (0 > nodex - 1) ? 0 : (nodex - 1);
             int endX   = (this._grid.numCols - 1 < nodex + 1) ? (this._grid.numCols - 1) : (nodex + 1);
             int startY = (0 > nodey - 1) ? 0 : (nodey - 1);
             int endY   = (this._grid.numRows - 1 < nodey + 1) ? (this._grid.numRows - 1) : (nodey + 1);
             for (int i = startX; i <= endX; i++)
             {
                 for (int j = startY; j <= endY; j++)
                 {
                     if (this._open.getLength() > AStar.MaxOpenNodeCount)
                     {
                         LogManager.WriteLog(LogTypes.Warning, string.Format("AStar:search()待检测的点太多,没必要再寻路: start({0}, {1}), to({2}, {3}), MaxOpenNodeCount={4}", new object[]
                         {
                             this._startNodeX,
                             this._startNodeY,
                             this._endNodeX,
                             this._endNodeY,
                             AStar.MaxOpenNodeCount
                         }), null, true);
                         return(false);
                     }
                     long test           = ANode.GetGUID(i, j);
                     int  testx          = i;
                     int  testy          = j;
                     bool isTestWalkable = this._grid.isWalkable(testx, testy);
                     if (test != node && isTestWalkable && this._grid.isDiagonalWalkable(node, test))
                     {
                         double cost = this._straightCost;
                         if (nodex != testx && nodey != testy)
                         {
                             cost = this._diagCost;
                         }
                         double nodeg        = this._grid.Nodes[nodex, nodey].g;
                         double g            = nodeg + cost * 1.0;
                         double h            = this.diagonal(testx, testy);
                         double f            = g + h;
                         bool   isInOpen     = this._open.indexOf(test) != -1;
                         int    indexOfClose = this.IndexOfClose(test);
                         if (isInOpen || indexOfClose != -1)
                         {
                             if (this._grid.Nodes[testx, testy].f > f)
                             {
                                 this._grid.Nodes[testx, testy].f       = f;
                                 this._grid.Nodes[testx, testy].g       = g;
                                 this._grid.Nodes[testx, testy].h       = h;
                                 this._grid.Nodes[testx, testy].parentX = nodex;
                                 this._grid.Nodes[testx, testy].parentY = nodey;
                                 if (isInOpen)
                                 {
                                     this._open.updateNode(test);
                                 }
                             }
                         }
                         else
                         {
                             this._grid.Nodes[testx, testy].f       = f;
                             this._grid.Nodes[testx, testy].g       = g;
                             this._grid.Nodes[testx, testy].h       = h;
                             this._grid.Nodes[testx, testy].parentX = nodex;
                             this._grid.Nodes[testx, testy].parentY = nodey;
                             this._open.push(test);
                         }
                     }
                 }
             }
             this._closed[node] = true;
             if (this._open.getLength() == 0)
             {
                 return(false);
             }
             node = this._open.shift();
         }
         nodex          = ANode.GetGUID_X(node);
         nodey          = ANode.GetGUID_Y(node);
         this._endNodeX = nodex;
         this._endNodeY = nodey;
         this.buildPath();
     }
     catch (Exception e)
     {
         Debug.WriteLine(e.Message);
     }
     return(true);
 }
Ejemplo n.º 2
0
        public bool search()
        {
            try
            {
                //异步运算。当上一次遍历超出最大允许值后停止遍历,下一次从
                //上次暂停处开始继续遍历
                long node    = ANode.GetGUID(_startNodeX, _startNodeY);
                long endNode = ANode.GetGUID(_endNodeX, _endNodeY);

                int nodex = 0;
                int nodey = 0;

                while (node != endNode)
                {
                    nodex = ANode.GetGUID_X(node);
                    nodey = ANode.GetGUID_Y(node);

                    int startX = 0 > nodex - 1 ? 0 : nodex - 1;
                    int endX   = _grid.numCols - 1 < nodex + 1 ? _grid.numCols - 1 : nodex + 1;
                    int startY = 0 > nodey - 1 ? 0 : nodey - 1;
                    int endY   = _grid.numRows - 1 < nodey + 1 ? _grid.numRows - 1 : nodey + 1;

                    for (int i = startX; i <= endX; i++)
                    {
                        for (int j = startY; j <= endY; j++)
                        {
                            //待检测的点太多,没必要再寻路了
                            if (_open.getLength() > MaxOpenNodeCount)
                            {
                                string warning = String.Format("AStar:search()待检测的点太多,没必要再寻路: start({0}, {1}), to({2}, {3}), MaxOpenNodeCount={4}",
                                                               _startNodeX, _startNodeY, _endNodeX, _endNodeY, MaxOpenNodeCount);
                                LogManager.WriteLog(LogTypes.Warning, warning);
                                return(false);
                            }

                            long test = ANode.GetGUID(i, j);

                            int testx = i;
                            int testy = j;

                            bool isTestWalkable = _grid.isWalkable(testx, testy);
                            if (test == node || !isTestWalkable ||
                                !_grid.isDiagonalWalkable(node, test))
                            {
                                continue;
                            }

                            double cost = _straightCost;

                            if (!((nodex == testx) || (nodey == testy)))
                            {
                                cost = _diagCost;
                            }

                            double nodeg = _grid.Nodes[nodex, nodey].g;
                            double g     = nodeg + cost * costMultiplier;
                            double h     = diagonal(testx, testy);
                            double f     = g + h;

                            Boolean isInOpen     = _open.indexOf(test) != -1;
                            int     indexOfClose = IndexOfClose(test);

                            if (isInOpen || indexOfClose != -1)
                            {
                                if (_grid.Nodes[testx, testy].f > f)
                                {
                                    _grid.Nodes[testx, testy].f       = f;
                                    _grid.Nodes[testx, testy].g       = g;
                                    _grid.Nodes[testx, testy].h       = h;
                                    _grid.Nodes[testx, testy].parentX = nodex;
                                    _grid.Nodes[testx, testy].parentY = nodey;

                                    if (isInOpen)
                                    {
                                        _open.updateNode(test);
                                    }
                                }
                            }
                            else
                            {
                                _grid.Nodes[testx, testy].f       = f;
                                _grid.Nodes[testx, testy].g       = g;
                                _grid.Nodes[testx, testy].h       = h;
                                _grid.Nodes[testx, testy].parentX = nodex;
                                _grid.Nodes[testx, testy].parentY = nodey;
                                _open.push(test);
                            }
                        }
                    }

                    _closed[node] = true;
                    if (_open.getLength() == 0)
                    {
                        return(false);
                    }

                    node = _open.shift();
                }

                //所有的node,都由很多副本,所以,很多时候,必须生成确定的副本
                nodex = ANode.GetGUID_X(node);
                nodey = ANode.GetGUID_Y(node);

                _endNodeX = nodex;
                _endNodeY = nodey;

                buildPath();
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
            }

            return(true);
        }