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); } } }
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); }
public PathFinder(BitTable terr, AStarNode[][] units) { this.terrain = terr; this.units = units; this.width = PathFinderManager.DW; this.height = PathFinderManager.DH; }