static void Main(string[] args) { // 자본주의 큐, 비싼 차들이 먼저 나오게 된다. PrioityQueue <Knight> q = new PrioityQueue <Knight>(); q.Push(new Knight() { Id = 20 }); q.Push(new Knight() { Id = 30 }); q.Push(new Knight() { Id = 40 }); q.Push(new Knight() { Id = 10 }); q.Push(new Knight() { Id = 05 }); while (q.Count() > 0) { Console.WriteLine(q.Pop().Id); } }
void Astar() { // U L D R UL DL DR UR int[] deltaY = new int[] { -1, 0, 1, 0 }; int[] deltaX = new int[] { 0, -1, 0, 1 }; int[] cost = new int[] { 10, 10, 10, 10 }; // 점수 매기기 // F = G + H // F = 최종 점수 (작을 수록 좋음, 경로에 따라 달라짐) // G = 시작점에서 해당 좌표까지 이동하는데 드는 비용 (작을 수록 좋음, 경로에 따라 달라짐) // H = 목적지에서 얼마나 가까운지 (작을 수록 좋음, 고정) // (y,x) 이미 방문했는지 여부 (방문 = closed 상태) bool[,] closed = new bool[_board.Size, _board.Size]; // CloseList // (y,x) 가는 길을 한번이라도 발견했는지 // 발견 X => MaxValue // 발견 O => F = G + H int[,] open = new int[_board.Size, _board.Size]; // OpenList for (int y = 0; y < _board.Size; y++) { for (int x = 0; x < _board.Size; x++) { open[y, x] = Int32.MaxValue; } } Pos[,] parent = new Pos[_board.Size, _board.Size]; // 오픈리스트에 있는 정보들 중에서, 가장 좋은 후보를 빠르게 뽑아오기 위한 도구. PrioityQueue <PQNode> pq = new PrioityQueue <PQNode>(); // 시작점 발견 (예약을 진행해야 한다) open[PosY, PosX] = 10 * (Math.Abs(_board.DestY - PosY) + Math.Abs(_board.DestX - PosX)); // Abs는 절대값을 의미한다. pq.Push(new PQNode() { F = 10 * (Math.Abs(_board.DestY - PosY) + Math.Abs(_board.DestX - PosX)), G = 0, Y = PosY, X = PosX }); parent[PosY, PosX] = new Pos(PosY, PosX); while (pq.Count > 0) { // 제일 좋은 후보를 찾는다. PQNode node = pq.Pop(); // 동일한 좌표를 여러 경로로 찾아서, 더 빠른 경로로 인해서 이미 방문(closed)된 경우 스킵 if (closed[node.Y, node.X]) { continue; } // 방문한다 closed[node.Y, node.X] = true; // 목적지에 도착햇으면 바로 종료 if (node.Y == _board.DestY && node.X == _board.DestX) { break; } // 상하좌우 등 이동할 수 있는 좌표인지 확인해서 예약(open)한다 for (int i = 0; i < deltaY.Length; i++) { int nextY = node.Y + deltaY[i]; int nextX = node.X + deltaX[i]; // 유효 범위를 벗어났을 경우 스킵한다. if (nextX < 0 || nextX >= _board.Size || nextY < 0 || nextY >= _board.Size) { continue; } // 벽으로 막혀서 갈 수 없으면 스킵한다. if (_board.Tile[nextY, nextX] == Part2_Section2MakeMap.TileType.Wall) { continue; } // 이미 방문한 곳이면 스킵한다. if (closed[nextY, nextX]) { continue; } // 비용 계산을 시작한다 // G = 시작하면서 이동하면서 필요한 비용 int g = node.G + cost[i]; // H = 목적지에서 시작점에서 가까운 정도를 나타내는 것 int h = 10 * (Math.Abs(_board.DestY - nextY) + Math.Abs(_board.DestX - nextX)); // 다른 경로에서 더 빠른 길을 이미 찾았으면 스킵을 해야한다 if (open[nextY, nextX] < g + h) { continue; } // 예약을 진행한다 open[nextY, nextX] = g + h; pq.Push(new PQNode() { F = g + h, G = g, Y = nextY, X = nextX }); parent[PosY, PosX] = new Pos(node.Y, node.X); } } CalcPathFromParent(parent); }