코딩테스트/SWExpertAcademy

재미있는 오셀로 게임 Python(SW Expert Academy)

멍토 2020. 3. 26.

난이도 : D3

문제번호 : 4615

※ 저의 풀이가 무조건적인 정답은 아닙니다.

다른 코드가 좀더 효율적이고 좋을 수 있습니다.

다른사람들의 풀이는 언제나 참고만 하시기 바랍니다.

문제 주소 및 출처입니다.

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWQmA4uK8ygDFAXj&categoryId=AWQmA4uK8ygDFAXj&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


목차

1. 문제 설명

2. 문제 해석

3. 소스 코드


1. 문제 설명

오셀로라는 게임은 흑돌과 백돌을 가진 사람이 번갈아가며 보드에 돌을 놓아서 최종적으로 보드에 자신의 돌이 많은 사람이 이기는 게임이다.

보드는 4x4, 6x6, 8x8(가로, 세로 길이) 크기를 사용한다. 6x6 보드에서 게임을 할 때, 처음에 플레이어는 다음과 같이 돌을 놓고 시작한다(B : 흑돌, W : 백돌).

4x4, 8x8 보드에서도 동일하게 정가운데에 아래와 같이 배치하고 시작한다.



그리고 흑, 백이 번갈아가며 돌을 놓는다.

처음엔 흑부터 시작하는데 이 때 흑이 돌을 놓을 수 있는 곳은 다음과 같이 4군데이다.



플레이어는 빈공간에 돌을 놓을 수 있다.

단, 자신이 놓을 돌과 자신의 돌 사이에 상대편의 돌이 있을 경우에만 그 곳에 돌을 놓을 수 있고, 그 때의 상대편의 돌은 자신의 돌로 만들 수 있다.

(여기에서 "사이"란 가로/세로/대각선을 의미한다.)

(2, 3) 위치에 흑돌을 놓은 후의 보드는 다음과 같다.



이런 식으로 번갈아가며 흑, 백 플레이어가 돌을 놓는다.

만약 돌을 놓을 곳이 없다면 상대편 플레이어가 다시 돌을 놓는다.

보드에 빈 곳이 없거나 양 플레이어 모두 돌을 놓을 곳이 없으면 게임이 끝나고 그 때 보드에 있는 돌의 개수가 많은 플레이어가 승리하게 된다.

 

입력

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 보드의 한 변의 길이 N과 플레이어가 돌을 놓는 횟수 M이 주어진다. N은 4, 6, 8 중 하나이다.

그 다음 M줄에는 돌을 놓을 위치와 돌의 색이 주어진다.

돌의 색이 1이면 흑돌, 2이면 백돌이다.

만약 3 2 1이 입력된다면 (3, 2) 위치에 흑돌을 놓는 것을 의미한다.

돌을 놓을 수 없는 곳은 입력으로 주어지지 않는다.

출력

첫 번째 줄에 테스트 케이스의 수 T가 주어진다.

각 테스트 케이스의 첫 번째 줄에는 보드의 한 변의 길이 N과 플레이어가 돌을 놓는 횟수 M이 주어진다. N은 4, 6, 8 중 하나이다.

그 다음 M줄에는 돌을 놓을 위치와 돌의 색이 주어진다.

돌의 색이 1이면 흑돌, 2이면 백돌이다.

만약 3 2 1이 입력된다면 (3, 2) 위치에 흑돌을 놓는 것을 의미한다.

돌을 놓을 수 없는 곳은 입력으로 주어지지 않는다.

예시

입력 출력

1
4 12
1 2 1
1 1 2
4 3 1
4 4 2
2 1 1
4 2 2
3 4 1
1 3 2
2 4 1
1 4 2
4 1 2
3 1 2

#1 0 16

2. 문제풀이

어렵지는 않았지만 구현할게 많았던 문제였다.

기능이 많은경우 각 기능별로 쪼개어 구현하는 편이 편하다.

따라서 여러개의 함수를 만들었는데

처음 돌을 초기화 하는함수

위치가 이동이 가능한지 판단하고 가능하다면 흰돌인지 검은돌인지 판단하는 함수

돌을 놓으면 데이터를 처리하는 함수

마지막으로 돌의 개수를 세주는 함수를 만들어 구현하였다.

 

돌을 놓았을때 팔방을 검사해야 하며 상대방 돌인경우 좌표를 기억하고있다가

내돌을 만나는 경우 상대방 돌을 전부 자기 돌로 바꿔주는 작업이 가장 중요하다.

 

이동중에 벽을만나거나 비어있다면 돌은 바꿀수가 없다.

 


3. 소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#D3 4615 재미있는 오셀로 게임
#상 하 좌 우 왼위, 오위, 왼아, 오아
dx = [-1100-1-111]
dy = [00-11-11-11]
 
#보드판을 초기화 한다.
#처음에 검은돌과 흰돌을 2개씩 놓는다.
def init(N):
    global board
    t_pos = N//2
    board[t_pos-1][t_pos-1= 2
    board[t_pos][t_pos] = 2
    board[t_pos][t_pos-1= 1
    board[t_pos-1][t_pos] = 1
 
#위치를 체크한다.
def isWall(x, y, color):
    global N, board 
    #이동이 벽을넘어가면
    if x < 0 or x >= N or y < 0 or y >= N:
        return 0 
    #돌이없으면
    if not board[x][y]:
        return 0
    #자기돌이라면
    if board[x][y] == color:
        return 2
    #상대돌이라면
    return 1
 
#돌을 놓으면 데이터를 처리한다.
def boardCheck(x, y, color):
    global board, dx, dy
    for i in range(8):
        #어디방향으로 이동할지 설정한다.
        d_x = dx[i]
        d_y = dy[i]
        #상대방 돌을 내돌로 바꾸는 리스트 생성
        change_list = []
        #반복문을 통해 체크한다.
        while True:
            #이동할 경로를 체크한다.
            a = isWall(x + d_x, y + d_y, color)
            #리턴이 0일때이며, 돌이없거나 벽이동을 못할때이다.
            #반복문을 종료한다.
            if not a: break
            #나와 같은색상의 돌을 만났을때이다.
            if a == 2:
                #지금까지 저장했던 상대방돌을을 내돌로 바꾼다.
                #반복문을 중지한다.
                for c_x, c_y in change_list:
                    board[c_x][c_y] = color
                break
            #상대방의 돌을 만났을때이다.
            #리스트에 상대방 돌정보를 저장한다.
            if a == 1:
                change_list.append([x + d_x, y + d_y])
            #반복이 진행될때마다 한칸씩 진행한다.
            d_x += dx[i]
            d_y += dy[i]
    #놓은 돌을 처리한다.
    board[x][y] = color
 
#돌개수를 검사하는 함수
def w_b_count(N):
    global board, w_count, b_count
    #2차원리스트를 돌면서 숫자를 체크한다.
    for i in board:
        b_count += i.count(1)
        w_count += i.count(2)
 
= int(input())
for t in range(1, T+1):
    N, M = map(int, input().split())
    #보드판을 N X N만큼 0으로 초기화한다.
    board = [[0 for _ in range(N)] for _ in range(N)]
    #초기화 함수를 불러 셋팅한다.
    init(N)
    #M번만큼 반복하여 입력받는다.
    for _ in range(M):
        x, y, color = map(int, input().split())
        #돌을 받을때마다 데이터를 처리한다.
        boardCheck(x-1, y-1, color)
    #돌의 객수를 체크한다.
    w_count = 0
    b_count = 0
    w_b_count(N)
    #결과를 출력한다.
    print('#{} {} {}'.format(t, b_count, w_count))

댓글

💲 광고입니다.