private void ReconstructPath(ExploerNode endNode) { ExploerNode currentNode = endNode; while (!currentNode.position.Equals(position)) { currentMovePath.Push(currentNode.cameFrom.position); currentNode = currentNode.cameFrom; } }
public Explorer(DungeonMaster master, int size) { this.dungeonMaster = master; map = new ExploerNode[size, size]; mapSize = size; for (int i = 0; i < size; ++i) { for (int j = 0; j < size; ++j) { map[i, j] = new ExploerNode(dungeonMaster.IsTile(j, i), j, i); } } }
private void MakePath(Int2D destination) { // Debug.WriteLine( "start to make the path" ); // Debug.WriteLine( "start : " + position.x + " / " + position.y ); // Debug.WriteLine( "dest : " + destination.x + " / " + destination.y ); // 조심해!!! // priority_queue가 없어서 일단 list로 구현 // List<ExploerNode> openSet = new List<ExploerNode>(); MinHeap <ExploerNode> openSet = new MinHeap <ExploerNode>(); for (int i = 0; i < mapSize; ++i) { for (int j = 0; j < mapSize; ++j) { map[i, j].Reset(); } } map[position.y, position.x].gScore = 0; map[position.y, position.x].fScore = map[position.y, position.x].gScore + GetHeuristicScore(position, destination); map[position.y, position.x].isOpened = true; // openSet.Add( map[position.y, position.x] ); openSet.Push(map[position.y, position.x]); while (openSet.Count > 0) { // ExploerNode current = openSet.Min(); ExploerNode current = openSet.Peek(); // Debug.WriteLine( "current : " + current.position.x + " / " + current.position.y ); if (current.position.Equals(destination)) { currentMovePath.Push(currentDestination); // 최종 목적지를 일단 넣고 그 사이를 채움 ReconstructPath(current); currentMovePath.Pop(); // 현재 위치는 빼자 break; } // openSet.Remove( openSet.Min() ); openSet.Pop(); current.isClosed = true; // 조심해! // 배열을 하나 새로 만드는 것이 어색하다 // 맨 끝 지점들에는 안 가니까 예외 처리는 생략 List <ExploerNode> neigborNodes = new List <ExploerNode> { map[current.position.y - 1, current.position.x], map[current.position.y + 1, current.position.x], map[current.position.y, current.position.x - 1], map[current.position.y, current.position.x + 1] }; for (int i = 0; i < neigborNodes.Count; ++i) { ExploerNode neighbor = neigborNodes[i]; if (neighbor.isClosed) { continue; } float gScoreTentative = current.gScore + Math.Abs(destination.x - current.position.x) + Math.Abs(destination.y - current.position.y); if (!neighbor.isOpened || gScoreTentative < neighbor.gScore) { neighbor.cameFrom = current; neighbor.gScore = gScoreTentative; neighbor.fScore = neighbor.gScore + GetHeuristicScore(neighbor.position, destination); if (!neighbor.isOpened) { neighbor.isOpened = true; // openSet.Add( neighbor ); openSet.Push(neighbor); } else { openSet.DecreaseKeyValue(neighbor); } // openSet.Sort( new NodeComp() ); } } } // Debug.WriteLine( "end!!!!" ); }