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);
            }
        }
Beispiel #2
0
        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);
        }