Post

BOJ 7682 틱택토

BOJ 7682 틱택토

https://www.acmicpc.net/problem/7682

문제

틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 3×3 격자판이며, 처음에는 비어 있다. 두 사람은 각각 X 또는 O 말을 번갈아가며 놓는데, 반드시 첫 번째 사람이 X를 놓고 두 번째 사람이 O를 놓는다. 어느 때든지 한 사람의 말이 가로, 세로, 대각선 방향으로 3칸을 잇는 데 성공하면 게임은 즉시 끝난다. 게임판이 가득 차도 게임은 끝난다.

게임판의 상태가 주어지면, 그 상태가 틱택토 게임에서 발생할 수 있는 최종 상태인지를 판별하시오.


입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, ‘X’, ‘O’, ‘.’ 중 하나이다. ‘.’은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입력의 마지막에는 문자열 “end”가 주어진다.


출력

각 테스트 케이스마다 한 줄에 정답을 출력한다. 가능할 경우 “valid”, 불가능할 경우 “invalid”를 출력한다.


예제 입력 1

XXXOO.XXX
XOXOXOXOX
OXOXOXOXO
XXOOOXXOX
XO.OX...X
.XXX.XOOO
X.OO..X..
OOXXXOOXO
end

예제 출력 1

invalid
valid
invalid
valid
valid
invalid
invalid
invalid

코드

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    static char[][] board;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder answer = new StringBuilder();
        String testCase = br.readLine();

        while (!testCase.equals("end")) {
            board = new char[3][3];
            int xCount = 0;
            int oCount = 0;
            int index = 0;

            // 3x3 격자판에 각 위치에 놓여있는 문자를 입력받으며, X와 O의 개수를 체크
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    board[i][j] = testCase.charAt(index);
                    index++;

                    if(board[i][j] == 'X') {
                        xCount++;
                    } else if(board[i][j] == 'O') {
                        oCount++;
                    }
                }
            }

            /**
             * 1. X와 O의 개수가 같으면 O가 이긴 경우 밖에 없음
             * 2. X가 O보다 1개 더 많은 경우는 X가 이기거나 판이 가득 차서 비긴 경우 밖에 없음
             * 3. 나머지는 불가능한 경우
             */
            if(xCount == oCount) {
                // X가 이기지 않고, O가 이긴 경우
                if(isWon('O') && !isWon('X')) {
                    answer.append("valid\n");
                } else {
                    answer.append("invalid\n");
                }
            } else if(xCount == oCount + 1) {
                // O가 이기지 않고, X가 이긴 경우나 판이 가득 차 비긴 경우
                if(!isWon('O') && (isWon('X') || xCount + oCount == 9)) {
                    answer.append("valid\n");
                } else {
                    answer.append("invalid\n");
                }
            } else {
                answer.append("invalid\n");
            }

            testCase = br.readLine();
        }

        System.out.println(answer);
    }

    // 입력받은 문자가 가로, 세로, 대각선 중 어느 한 방향이라도 3칸 모두 차 있어 이겼는지 확인하는 메소드
    static boolean isWon(char playing) {
        // 체크할 문자가 가로, 세로 방향으로 3칸 모두 차 있는 경우, 이긴 것
        for (int i = 0; i < 3; i++) {
            if(board[i][0] == playing && board[i][1] == playing && board[i][2] == playing) {
                return true;
            }

            if(board[0][i] == playing && board[1][i] == playing && board[2][i] == playing) {
                return true;
            }
        }

        // 체크할 문자가 대각선 방향으로 3칸 모두 차 있는 경우, 이긴 것
        if(board[0][0] == playing && board[1][1] == playing && board[2][2] == playing) {
            return true;
        }

        if(board[0][2] == playing && board[1][1] == playing && board[2][0] == playing) {
            return true;
        }

        // 나머지는 진 것
        return false;
    }
}
This post is licensed under CC BY 4.0 by the author.