<Medium> Minesweeper (LeetCode : C#)

이도희·2023년 5월 15일
0

알고리즘 문제 풀이

목록 보기
80/185

https://leetcode.com/problems/minesweeper/

📕 문제 설명

지뢰 찾기 중 다음으로 클릭할 정보가 주어진다. 해당 클릭 정보를 누른 후 보드 상태 반환하기

보드 정보
M : 아직 누르지 않은 지뢰 있는 칸
E : 아직 누르지 않은 빈 칸
B : 누른 상태에서 빈 칸
digit : 누른 상태에서 숫자 칸 (숫자는 상하좌우 및 대각선 주변의 지뢰 개수)
X : 누른 상태에서 지뢰

Rule
1) M을 누르면 X로 변경한 후 게임 종료
2) E를 눌렀을 때 만약 주변에 인접한 지뢰가 없으면 B로 변경 후 주변의 (상하좌우 및 대각선) 모든 빈 칸 열기
3) E를 눌렀을 때 주변에 인접한 지뢰가 있으면 해당되는 숫자로 변경

  • Input
    게임 보드 정보 (char[][]), 클릭한 정보 (int[])
  • Output
    클릭 정보 반영 후 보드 상태

예제

풀이

public class Solution {
    public char[][] UpdateBoard(char[][] board, int[] click) {
        // bfs direction (상하좌우대각선)
        int[] dirX = new int[8] {1, -1, 0, 0, 1, 1, -1, -1};
        int[] dirY = new int[8] {0, 0, 1, -1, 1, -1, 1, -1};
        bool[,] visited = new bool[board.Length,board[0].Length];

        Queue<int[]> queue = new Queue<int[]>();
        queue.Enqueue(click);

        while (queue.Count >= 1)
        {
            int[] currentPos = queue.Dequeue();
            if (visited[currentPos[0], currentPos[1]]) continue; // 방문했으면 넘기기
            visited[currentPos[0], currentPos[1]] = true;

            switch (board[currentPos[0]][currentPos[1]])
            {
                case 'M': // 현재 누른게 지뢰면 x로 바꾸고 바로 종료
                    board[currentPos[0]][currentPos[1]] = 'X';
                    return board;
                case 'E': // 빈 칸이면 B되야하는지 Digit 되야하는지 체크
                    UpdateSquare(currentPos);
                    break;
            }
        }

        return board;

        void UpdateSquare(int[] currPos)
        {
            int adjacentMineCnt = 0;
            List<int[]> adjacentEList = new List<int[]>();
            for (int i = 0; i < 8; i++)
            {
                int x = currPos[0] + dirX[i];
                int y = currPos[1] + dirY[i];

                if (x >= board.Length || x < 0 || y >= board[0].Length || y < 0) continue; // board 범위 밖

                switch (board[x][y])
                {
                    case 'M': // 주변 지뢰면 지뢰 개수 업데이트
                        adjacentMineCnt += 1;
                        break;
                    case 'E': // 주변 빈 칸이면 지뢰 개수 0일 때 방문해야 하므로 저장
                        adjacentEList.Add(new int[2] {x, y});
                        break;
                }
            }

            if (adjacentMineCnt >= 1) // digit 되는 케이스 -> 그냥 digit으로 변경
            {
                board[currPos[0]][currPos[1]] = (char) (adjacentMineCnt + '0');
            }
            else // 주변 0이라 B되는 케이스 -> 주변 E들 큐에 넣고 B로 변경
            {
                foreach (int[] pos in adjacentEList)
                {
                    queue.Enqueue(pos);
                }
                board[currPos[0]][currPos[1]] = 'B';
            }
        }
    }
}

결과

profile
하나씩 심어 나가는 개발 농장🥕 (블로그 이전중)

0개의 댓글