Exemple #1
0
 public PathFinderManager(BitTable terr)
 {
     terrain = terr;
     units = new AStarNode[DW][];
     for (int i = 0; i < DW; i++)
     {
         units[i] = new AStarNode[DH];
         for (int j = 0; j < DH; j++)
         {
             units[i][j] = new AStarNode(i, j);
         }
     }
 }
Exemple #2
0
        public PathFinderResult FindPath(int sx, int sy, int tx, int ty)
        {
            if (sx == tx && sy == ty)
            {
                return(new PathFinderResult(new FastList <Point>(), false));
            }

            int ofsX = Math.Min(sx, tx);
            int ofsY = Math.Min(sy, ty);

            FastList <AStarNode> enQueueBuffer = new FastList <AStarNode>(10);

            AStarNode startNode = units[sx][sy];

            startNode.parent = null;
            startNode.h      = 0;
            startNode.g      = 0;
            startNode.f      = 0;
            startNode.depth  = 0;

            queue.Enqueue(startNode);
            inQueueTable.Add(startNode.GetHashCode(), startNode);

            bool found = false;
            bool rcpf  = false;

            AStarNode finalNode = null;

            while (queue.Count > 0 && !(found || rcpf))
            {
                AStarNode curPos  = queue.Dequeue(); //将open列表中最前面的元素设为当前格
                int       curHash = curPos.GetHashCode();

                if (curPos.depth > MaxStep)
                {
                    rcpf      = true;
                    finalNode = curPos;
                    break;
                }


                inQueueTable.Remove(curHash);
                passedTable.Add(curHash, curPos);

                int cx = curPos.X;
                int cy = curPos.Y;

                // BFS展开新节点
                for (int i = 0; i < 8; i++)
                {
                    int nx = cx + stateEnum[i][0];
                    int ny = cy + stateEnum[i][1];

                    // 检查范围
                    if (nx >= 0 && nx < width && ny >= 0 && ny < height)
                    {
                        AStarNode np     = units[nx][ny];
                        int       npHash = np.GetHashCode();


                        if (nx == tx && ny == ty) //如此方格为终点
                        {
                            found     = true;     //找到路径了
                            finalNode = np;

                            np.depth  = curPos.depth + 1;
                            np.parent = curPos;  //当前格坐标为终点的父方格坐标
                            break;
                        }
                        else
                        {
                            if (!terrain.GetBit(ny * width + nx))  //地块能通过
                            {
                                bool      isNPInQueue = false;
                                AStarNode temp;
                                if (inQueueTable.TryGetValue(npHash, out temp) && temp == np)
                                {
                                    if (np.g > curPos.g + stateEnumCost[i])
                                    {
                                        np.g = curPos.g + stateEnumCost[i];
                                        np.f = np.g + np.h;
                                    }
                                    isNPInQueue = true;
                                }

                                if (!isNPInQueue &&
                                    (!passedTable.TryGetValue(npHash, out temp) && temp != np))
                                //如果此方格不在即将展开的节点表 和 已遍历过的节点表
                                {
                                    np.parent = curPos; //当前格为此格的父方格

                                    np.g     = curPos.g + stateEnumCost[i];
                                    np.h     = Math.Abs(tx - nx) + Math.Abs(ty - ny);
                                    np.f     = np.g + np.h;
                                    np.depth = curPos.depth + 1;

                                    enQueueBuffer.Add(np);
                                    inQueueTable.Add(npHash, np);
                                }
                            }
                        }
                    }
                }

                // A*
                //enQueueBuffer.Sort(Comparision);
                if (enQueueBuffer.Count > 0)
                {
                    QuickSort(enQueueBuffer, 0, enQueueBuffer.Count - 1);
                    for (int i = 0; i < enQueueBuffer.Count; i++)
                    {
                        queue.Enqueue(enQueueBuffer[i]);
                    }
                    enQueueBuffer.Clear();
                }
            }

            if (rcpf)
            {
                AStarNode curNode    = finalNode;
                int       baseOffset = result.Count;
                for (int i = 0; i < curNode.depth; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[baseOffset + curNode.depth - 1] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }while (curNode.parent != null);

                return(new PathFinderResult(result, true));
            }
            if (found)
            {
                AStarNode curNode = finalNode;
                for (int i = 0; i < curNode.depth + 1; i++)
                {
                    result.Add(Point.Zero);
                }
                do
                {
                    //result.Add(curNode);
                    result[curNode.depth] = new Point(curNode.X, curNode.Y);
                    curNode = curNode.parent;
                }while (curNode.parent != null);

                result[0] = new Point(sx, sy);
                return(new PathFinderResult(result, false));
            }
            return(null);
        }
Exemple #3
0
        public PathFinder(BitTable terr, AStarNode[][] units)
        {
            this.terrain = terr;
            this.units = units;

            this.width = PathFinderManager.DW;
            this.height = PathFinderManager.DH;
        }