inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part2: 자료구조와 알고리즘

A* 구현 Part2

실수한 부분에서 나온 증상에 대한 이해

223

Hyobin Kim

작성한 질문수 81

0

제가 parent[nextY, nextX] =  new Pos(node.Y, node.X) 대신에 PosY, PosX를 집어 넣으니까

뭔가 맵이 폭포스마냥 계속 업데이트 되는걸로 보이던데

이게 모든 점의 부모점을 시작점으로 해버려서 진행도 못하고 그자리에서 멤돌기 때문에 생기는거죠?

 public void Astar()
        {
            // the delta values when moving towards Up, Left, Down, Right
            int[] deltaY = { -1, 0, 1, 0 };
            int[] deltaX = { 0, -1, 0, 1 };
            int[] cost = { 1, 1, 1, 1 };

            // Giving points depending on how close the player is to the destination
            // F = G + H
            // F = Final Score (the smaller, the better. Varying depending on the route)
            // G = the cost to move from the start to the destination (the smaller, the better. Varying depending on the route)
            // H = the distance from the current position and the destination, without ignoring any obstacles (the smaller, the better. Fixed)

            // the status whether a coordinate has been visited (visited = closed)
            bool[,] closed = new bool[_board.Size, _board.Size]; // ClosedList (List can be used as well)

            // the status whether a route to (y, x) has been found (Gigving score)
            // not found -> Int32.Max
            // found -> F = G + H
            int[,] open = new int[_board.Size, _board.Size]; // OpenList (which has the scores on each coordinate)
            // Initialize OpenList
            for (int y = 0; y < _board.Size; y++)
                for (int x = 0; x < _board.Size; x++)
                    open[y, x] = Int32.MaxValue;

            // an Array to track the parent nodes 
            Pos[,] parent = new Pos[_board.Size, _board.Size];

            // Use PriorityQueue, which is specialized to pick up the best case
            // a tool to pick up the best candidate from OpenList
            PriorityQueue<PQNode> pq = new PriorityQueue<PQNode>();

            // Found Start (Reservation begins) // Log and give the score to the coordinate
            open[PosY, PosX] = 0 + Math.Abs(_board.DestY - PosY) + Math.Abs(_board.DestX - PosX); // : G == 0; H = the distance from Start to Destination
            pq.Push(new PQNode() { F = Math.Abs(_board.DestY - PosY) + Math.Abs(_board.DestX - PosX), G = 0, Y = PosY, X = PosX });
            parent[PosY, PosX] = new Pos(PosY, PosX); // parent of Start is itself

            while (pq.Count > 0)
            {
                // Find out the best candidate
                PQNode node = pq.Pop();
                // Skip if a coordinate has been visited(clsoed) with a faster route, while finding out routes to the same coordinate
                if (closed[node.Y, node.X])
                    continue;

                // Visit saying this coordinate won't visited again
                closed[node.Y, node.X] = true;
                // Quit if reached the destination
                if (node.Y == _board.DestY && node.X == _board.DestX)
                    break;

                // Reserve(Open) the coordinates by verifying if they are available to move to
                for (int i = 0; i < deltaY.Length; i++)
                {
                    int nextY = node.Y + deltaY[i];
                    int nextX = node.X + deltaX[i];

                    // Skip when the coordinate is out of the boundary
                    if (nextY < 0 || nextY >= _board.Size || nextX < 0 || nextX >= _board.Size)
                        continue;
                    // Skip when the coordinate is Wall
                    if (_board.Tile[nextY, nextX] == Board.TileType.Wall)
                        continue;
                    if (closed[nextY, nextX])
                        continue

                    // Evalutate the cost
                    int g = node.G + cost[i]; // the cost to move to the next coordinate
                    int h = Math.Abs(_board.DestY - nextY) + Math.Abs(_board.DestX - nextX); // the distance from the current position to the destination
                    // Skip when a btter route is found
                    if (open[nextY, nextX] < g + h)
                        continue;

                    open[nextY, nextX] = g + h; // Put the calculated score
                    pq.Push(new PQNode() { F = g + h, G = g, Y = nextY, X = nextX }); // input the coordinate to the Priority Queue
                    parent[nextY, nextX] = new Pos(PosY, PosX); // the parent node of the next coordinate is the current node, which is the fastest one (verified by going through the filters above)
                }
            }
            // retrieve the path by follwing the parent nodes inversly
            CalculatePathFromParent(parent);
        }

C#

답변 2

0

Hyobin Kim

CalcFromParent 였군요 저는 계속 while루프 안에서만 찾으려고 했었는데......

감사합니다

0

Rookiss

parent 배열이 [내가 어디서 왔는지]를 추적하기 위해 관리하는건데,
데이터가 잘못 들어가는 바람에
시작 좌표 -> 종료 좌표로 바로 이동한 것으로 인식되어서 발생한 문제입니다.
시작/끝으로 순간이동하고 끝나니 바로 맵을 랜덤으로 바꾸기 때문에 그렇게 보이는겁니다.

이런 문제는 사실 CalcFromParent에 브레이크 포인트를 걸고 타고 들어가서
살펴보는게 가장 정확합니다.

게임개발에서 주로 어느부분에 알고리즘들이 쓰이는지 궁금합니다

0

169

2

글꼴 바꿔도 자간이 좁아 찌그러져보이시는 분들

0

86

1

NullReferenceException 예외) 같은 실수하시는분 계실까봐 남겨요

0

66

1

parent를 Pos타입으로 만든 이유

0

74

1

콘솔창에 격자가 안나옴 미로 생성 X

0

133

1

격자 생성 안됨 무한루프

0

113

1

BFS 질문

0

143

2

격자 무한 출력

0

166

2

A* 의 PriorityQueue 관련 질문입니다

0

154

2

vscode에서 원그리기

0

179

1

환결설정 강의 원 그리기

0

122

1

15-17분

0

85

1

3:16초에 근데 이렇게 해가지고 부분에 "{}"를 만들어서 자식 node들을 생성하던데 왜 중괄호로 감싸게 만드는 건가요?

0

140

2

동적 배열 관련 질문입니다!

0

209

1

Big-o 표기법에서 시간 복잡도

0

167

1

7:40에서 언급하신 색상이 날아가는 문제 이해를 못하겠습니다

0

150

1

트리구현연습 강의 질문있어요

0

142

1

창은 뜨는데 맵이 나타나지 않아요.

0

174

1

Ctrl F5 하면 나오는 창은 어디서 설정할까요??

0

271

1

void CalcPathFromParent(Pos[,] parent)에 대해서

0

201

2

NullReferenceException예외가 발생했을때 어떻게 해야하나요?

0

227

1

[해결] 환경설정 강의에서 원이 이상하게 그려지는 문제

3

306

2

오른손 법칙에서 플레이어 점이 안 움직입니다

0

243

2

맵 만들기 오류

0

177

1