코딩테스트

[Hackerrank] The Bomberman Game

essay0263 2025. 1. 15. 02:29

문제 설명

Bomberman은 직사각형 격자(grid)에서 폭탄을 설치하고 터뜨리는 게임입니다. 각 칸은 폭탄(O)이 있거나 비어있음(.)을 나타냅니다.

게임은 다음 규칙에 따라 진행됩니다:

  1. 1초: Bomberman은 아무 행동도 하지 않습니다.
  2. 짝수 초(2, 4, 6, ...): 비어있는 모든 칸에 폭탄을 설치합니다.
  3. 폭탄은 설치 후 정확히 3초 후에 폭발하며, 폭발 시 상하좌우 인접한 칸도 함께 비워집니다.
  4. 동시에 설치된 폭탄은 동시에 폭발합니다.
  5. 폭발로 인해 비워진 칸에는 즉시 폭탄이 설치되지 않습니다.

목표

  • **초기 격자 상태(grid)**와 시간 n이 주어질 때, n초 후의 격자 상태를 출력하시오.

입력 형식

  1. 첫 번째 줄: 세 개의 정수 r(행의 수), c(열의 수), n(시뮬레이션 시간).
  2. 다음 r줄: 초기 격자 상태.
    • .: 빈 칸
    • O: 폭탄이 설치된 칸

출력 형식

  • n초 후의 격자 상태를 출력합니다.

문제 예시

입력:

 
6 7 3
.......
...O...
....O..
.......
OO.....
OO.....

출력:

OOO.OOO
OO...OO
OOO...O
..OO.OO
...OOOO
...OOOO

사실 이 문제는 문제를 이해하는 시간이 훨씬 오래 걸렸다. 아무리 봐도 문제를 이해를 못 하다가 구글링을 통해서 블로그 글을 보고 알게 되었다.

출처: https://zoosso.tistory.com/108

그래서 결국 문제를 생각해 보면 2초, 4초, 6초... 에는 필드가 전부 폭탄으로 채워져 있고, 1초, 5초, 9초마다 동일한 필드가 반복되고 3초, 7초, 11초... 마다 동일한 필드가 반복되는 것을 확인할 수 있다. 

그리고 dx = [0, 1, 0, -1], dy = [1, 0, -1, 0]으로 두어서 dx[i], dy[i]로 해서 각 열마다 상하좌우를 확인해서 범위 안이고, 폭탄이면 그 주변을 터트리는 방식을 이용했다.

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def bomberMan(n, grid):
    # Write your code here
    x = len(grid)
    y = 0
    for i in grid[0]:
        if i == "O" or i == ".":
            y += 1 
    if n % 2 == 0:
        visited = [["O" for _ in range(y)] for _ in range(x)]
    elif n % 4 == 3:
        visited = [["O" for _ in range(y)] for _ in range(x)]
        for j in range(y):
            for i in range(x):
                if grid[i][j] == "O":
                    visited[i][j] = "."
                    for num in range(4):
                        if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
                            visited[i + dx[num]][j + dy[num]] = "."
    elif n == 1:
        return grid
    elif n % 4 == 1:
        visited = [["O" for _ in range(y)] for _ in range(x)]
        for j in range(y):
            for i in range(x):
                if grid[i][j] == "O":
                    visited[i][j] = "."
                    for num in range(4):
                        if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
                            visited[i + dx[num]][j + dy[num]] = "."
        grid = visited
        visited = [["O" for _ in range(y)] for _ in range(x)]
        for j in range(y):
            for i in range(x):
                if grid[i][j] == "O":
                    visited[i][j] = "."
                    for num in range(4):
                        if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
                            visited[i + dx[num]][j + dy[num]] = "."
    visited = ["".join(x) for x in visited]
    return visited

이렇게 보니까 정답이 나왔다. 그런데 코드가 너무 지저분해서 수정을 해주었다.

def bomberMan(n, grid):
    rows, cols = len(grid), len(grid[0].replace(" ", ""))

    if n == 1:
        return grid
    
    elif n % 2 == 0:
        return ['O' * cols for _ in range(rows)]

    def explode(grid):
        exploded = [['O'] * cols for _ in range(rows)]
        directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

        for i in range(rows):
            for j in range(cols):
                if grid[i][j] == 'O':
                    exploded[i][j] = '.'
                    for dx, dy in directions:
                        ni, nj = i + dx, j + dy
                        if 0 <= ni < rows and 0 <= nj < cols:
                            exploded[ni][nj] = '.'
        return [''.join(row) for row in exploded]

    first_explosion = explode(grid)
    second_explosion = explode(first_explosion)

    return first_explosion if n % 4 == 3 else second_explosion

정답처리되었다.