[Java] 백준 7682 틱택토

hyunnzl·2024년 12월 21일

백준

목록 보기
21/116
post-thumbnail

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)
아무도 승리하지 않은 경우에는 틱택토 판에 빈칸이 있어야 함

이번 문제는 예외처리를 얼마나 잘 해주느냐가 관건이었던 것 같다.


0개의 댓글