[Python] [SWEA] 재미있는 오셀로 게임(4615)

긍정왕·2021년 6월 1일
2

Algorithm

목록 보기
12/69
post-thumbnail

💡 문제 해결

  1. 초기 돌의 위치를 셋팅
  2. 순차적인 플레이를 반복문을 통해 실행
  3. 보드 위에 돌을 두고 8방향을 탐색
  4. 탐색하는 방향에 색이 다른 돌이 존재한다면 while문을 통해 끝점을 탐색
  5. 탐색하는 도중 이동하는 좌표를 리스트에 저장
  6. 탐색 도중 판의 범위를 넘어서면 그대로 return
  7. 탐색하는 방향의 끝점이 자신과 같은 색이면 이동했던 좌표들의 돌을 자신과 같은 색의 돌로 변환
  8. 보드 위 색에 따른 돌의 개수를 출력

📌 x좌표y좌표의 위치가 다르고 idx가 0이 아닌 1부터 시작하는 것에 주의



🧾 문제 설명

오셀로라는 게임은 흑돌과 백돌을 가진 사람이 번갈아가며 보드에 돌을 놓아서 
최종적으로 보드에 자신의 돌이 많은 사람이 이기는 게임이다.
보드는 4x4, 6x6, 8x8(가로, 세로 길이) 크기를 사용한다. 6x6 보드에서 게임을 할 때, 
처음에 플레이어는 다음과 같이 돌을 놓고 시작한다(B : 흑돌, W : 백돌).
4x4, 8x8 보드에서도 동일하게 정가운데에 아래와 같이 배치하고 시작한다.

그리고 흑, 백이 번갈아가며 돌을 놓는다.
처음엔 흑부터 시작하는데 이 때 흑이 돌을 놓을 수 있는 곳은 백돌과 인접한 곳이다.
플레이어는 빈공간에 돌을 놓을 수 있다.
단, 자신이 놓을 돌과 자신의 돌 사이에 상대편의 돌이 있을 경우에만 그 곳에 돌을 놓을 수 있고, 
그 때의 상대편의 돌은 자신의 돌로 만들 수 있다.
이런 식으로 번갈아가며 흑, 백 플레이어가 돌을 놓는다.
만약 돌을 놓을 곳이 없다면 상대편 플레이어가 다시 돌을 놓는다.
보드에 빈 곳이 없거나 양 플레이어 모두 돌을 놓을 곳이 없으면 
게임이 끝나고 그 때 보드에 있는 돌의 개수가 많은 플레이어가 승리하게 된다.

문제보기



🖨 입출력



📝 풀이

dx, dy = [-1, 1, 0, 0, -1, 1, -1, 1], [0, 0, -1, 1, -1, -1, 1, 1]

def initial_set(N):
    board = [[0] * (N + 1) for _ in range(N + 1)]
    mid = N // 2
    board[mid][mid] = 2
    board[mid][mid + 1] = 1
    board[mid + 1][mid] = 1
    board[mid + 1][mid + 1] = 2
    return board


def go(board, dx, dy, nx, ny, color, N, k):
    move_points = [(nx, ny)]
    while board[nx][ny] != 0 and board[nx][ny] != color:
        nx += dx[k]
        ny += dy[k]
        move_points.append((nx, ny))
        if nx < 0 or nx > N or ny < 0 or ny > N:
            return False
    if board[nx][ny] == color:
        for i, j in move_points:
            board[i][j] = color
    return board


def check(board, N):
    answer = [0, 0]
    for i in range(N + 1):
        for j in range(N + 1):
            if board[i][j] == 1:
                answer[0] += 1
            elif board[i][j] == 2:
                answer[1] += 1
    return answer



for tc in range(1, int(input()) + 1):
    N, M = map(int, input().split())
    plays = list(list(map(int, input().split())) for _ in range(M))

    board = initial_set(N)
    for y, x, color in plays:
        board[x][y] = color
        for k in range(8):
            nx = x + dx[k]
            ny = y + dy[k]
            if 0 <= nx < N + 1 and 0 <= ny < N + 1:
                tmp = go(board, dx, dy, nx, ny, color, N, k)
                if tmp:
                    board = tmp
    
    answer = check(board, N)

    print(f'#{tc} {answer[0]} {answer[1]}')

profile
Impossible + 땀 한방울 == I'm possible

0개의 댓글