https://www.acmicpc.net/problem/7682
골드5
틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 3×3 격자판이며, 처음에는 비어 있다. 두 사람은 각각 X 또는 O 말을 번갈아가며 놓는데, 반드시 첫 번째 사람이 X를 놓고 두 번째 사람이 O를 놓는다. 어느 때든지 한 사람의 말이 가로, 세로, 대각선 방향으로 3칸을 잇는 데 성공하면 게임은 즉시 끝난다. 게임판이 가득 차도 게임은 끝난다.
게임판의 상태가 주어지면, 그 상태가 틱택토 게임에서 발생할 수 있는 최종 상태인지를 판별하시오.
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, 'X', 'O', '.' 중 하나이다. '.'은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입력의 마지막에는 문자열 "end"가 주어진다.
각 테스트 케이스마다 한 줄에 정답을 출력한다. 가능할 경우 "valid", 불가능할 경우 "invalid"를 출력한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
StringBuilder sb = new StringBuilder();
while (!(line = br.readLine()).equals("end")) {
if (isValid(line)) {
sb.append("valid").append("\n");
} else {
sb.append("invalid").append("\n");
}
}
System.out.println(sb);
}
private static boolean isValid(String board) {
int xCount = 0, oCount = 0;
for (char c : board.toCharArray()) {
if (c == 'X')
xCount++;
else if (c == 'O')
oCount++;
}
if (xCount < oCount || xCount > oCount + 1)
return false;
boolean xWin = checkWin(board, 'X');
boolean oWin = checkWin(board, 'O');
if (xWin && oWin)
return false;
if (xWin && xCount != oCount + 1)
return false;
if (oWin && xCount != oCount)
return false;
if (!xWin && !oWin && xCount + oCount != 9)
return false;
return true;
}
private static boolean checkWin(String board, char player) {
int[][] winConditions = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 },
{ 0, 4, 8 }, { 2, 4, 6 } };
for (int[] condition : winConditions) {
if (board.charAt(condition[0]) == player && board.charAt(condition[1]) == player
&& board.charAt(condition[2]) == player) {
return true;
}
}
return false;
}
}
문제에서 주어진 판이 성립할 수 있는지 없는지 판별하는 문제였다.
성립할 수 없다면 바로 빠져나와서 invalid를, 모든 조건이 성립하면 valid를 추가했다.
if (xCount < oCount || xCount > oCount + 1)
X가 O보다 먼저 말을 놓기 때문에 O의 수가 더 많거나
둘이 올린 말의 수가 1보다 크다면 성립이 되지 않는다.
그리고 각각 가로, 세로, 대각선을 성공한 적이 있는지 확인을 하는데,
if (xWin && oWin)
둘 중에 한 명이라도 성공을 하면 바로 게임이 즉시 종료되기 때문에 둘 다 성공 할 수 없음
if (xWin && xCount != oCount + 1)
X가 이긴 경우, X의 개수는 O보다 1 더 많아야 함
if (oWin && xCount != oCount)
O가 이긴 경우, X와 O의 개수가 같아야 함
if (!xWin && !oWin && xCount + oCount != 9)
아무도 승리하지 않은 경우에는 틱택토 판에 빈칸이 있어야 함
이번 문제는 예외처리를 얼마나 잘 해주느냐가 관건이었던 것 같다.
