문제
https://www.acmicpc.net/problem/7682
문제 개요
틱택토는 두 명이 번갈아 가며 말을 놓는 게임으로, 3×3 격자판에서 X와 O를 배치하여 가로, 세로, 또는 대각선 방향으로 연속된 3칸을 채우면 승리하는 게임입니다. 이 문제에서는 특정 틱택토 게임판 상태가 게임의 규칙을 준수하는 유효한 최종 상태인지 판별해야 합니다.
접근 방법
- 게임판 상태 입력 및 변환:
- 입력을 받아 3x3 형태의 게임판으로 변환합니다.
- 입력의 각 문자(X, O, .)는 게임판의 상태를 나타냅니다.
- 유효성 검사:
- X와 O의 개수 조건: X의 개수는 항상 O보다 크거나 같고, 최대 1개 더 많아야 합니다.
- 승리 조건 검사: X 또는 O가 승리 조건을 만족했는지 확인합니다.
- 여러 승리 조건 확인:
- 만약 X와 O가 동시에 승리하는 경우는 불가능하므로 유효하지 않습니다.
- X가 승리했을 경우 X의 개수는 O보다 정확히 하나 많아야 합니다.
- O가 승리했을 경우 X와 O의 개수가 같아야 합니다.
- 빈 칸 검사:
- 승리자가 없는 경우, 게임판에 빈칸이 남아있다면 게임이 끝나지 않은 상태이므로 유효하지 않습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
while (!s.equals("end")) {
String[][] board = new String[3][3];
int idx = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
board[i][j] = String.valueOf(s.charAt(idx++));
}
}
System.out.println(isValid(board) ? "valid" : "invalid");
s = br.readLine();
}
}
public static boolean isValid(String[][] board) {
int[] arr = cntNum(board);
int x_cnt = arr[0];
int o_cnt = arr[1];
boolean x_correct = checkWin(board, "X");
boolean o_correct = checkWin(board, "O");
if (x_cnt < o_cnt) return false; // O가 더 많을 수 없음
if (x_cnt - o_cnt >= 2) return false; // X와 O의 차이는 최대 1
if (x_correct && o_correct) return false; // 두 플레이어가 동시에 승리 불가
if (x_correct && x_cnt - o_cnt != 1) return false; // X가 승리하면 X가 O보다 하나 더 많아야 함
if (!x_correct && o_correct && (x_cnt > o_cnt)) return false; // O가 승리하면 X와 O의 개수는 같아야 함
if (!x_correct && !o_correct && checkEmpty(board)) return false; // 승리자 없고 빈칸이 남아 있으면 불가
return true;
}
public static boolean checkEmpty(String[][] board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j].equals(".")) return true;
}
}
return false;
}
public static int[] cntNum(String[][] board) {
int x = 0;
int o = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j].equals("X")) {
x++;
} else if (board[i][j].equals("O")) {
o++;
}
}
}
return new int[]{x, o};
}
public static boolean checkWin(String[][] board, String player) {
for (int i = 0; i < 3; i++) {
if (board[i][0].equals(player) && board[i][1].equals(player) && board[i][2].equals(player))
return true;
}
for (int i = 0; i < 3; i++) {
if (board[0][i].equals(player) && board[1][i].equals(player) && board[2][i].equals(player))
return true;
}
if (board[0][0].equals(player) && board[1][1].equals(player) && board[2][2].equals(player))
return true;
if (board[0][2].equals(player) && board[1][1].equals(player) && board[2][0].equals(player))
return true;
return false;
}
}
'문제 > 백준' 카테고리의 다른 글
[백준] 4920 테트리스 게임 - Java (0) | 2024.10.30 |
---|---|
[백준] 1654 랜선 자르기 - Java (2) | 2024.10.25 |
[백준] 3190 뱀 - Java (1) | 2024.10.24 |
[백준] 1094 막대기 - Java (0) | 2024.10.23 |
[백준] 1018 체스판 다시 칠하기 - Java (0) | 2024.10.23 |