백준 7682 - 틱택토 (Java)
https://www.acmicpc.net/problem/7682
7682번: 틱택토
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 줄은 9개의 문자를 포함하며, 'X', 'O', '.' 중 하나이다. '.'은 빈칸을 의미하며, 9개의 문자는 게임판에서 제일 윗 줄 왼쪽부터의 순서이다. 입
www.acmicpc.net
문제
틱택토 게임은 두 명의 사람이 번갈아가며 말을 놓는 게임이다. 게임판은 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. X가 이긴 경우
1-1. 게임 판이 가득차고 O가 완성되지 않은 경우
1-2. O가 완성되지 않고 X가 완성 된 경우
2. O가 이긴 경우
2-1. X가 완성되지 않고 O가 완성된 경우
위와 같은 상황이 valid 상황이다. 게임이 정상적으로 끝난 상황들.
남은 상황들은 invalid 상황이다. 게임이 정상적으로 끝나지 않은 상황.
틱택토가 완성되었는지 검사는 3x3 사이즈이기 때문에
한 열씩, 한 행씩 같은 것으로 채워져 있는지 검사하고, 대각선은 좌상에서 우하로, 우상에서 좌하로 검사하면 모든 검사가 마쳐진다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class BJ_7682_틱택토 {
static char[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true)
{
String str = br.readLine();
if(str.equals("end"))
break;
map = new char[3][3];
int xCnt = 0;
int oCnt = 0;
int index = 0;
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
map[i][j] = str.charAt(index++);
if(map[i][j]=='X')
xCnt++;
else if(map[i][j] =='O')
oCnt++;
}
}
// X가 이긴 경우
if(xCnt == oCnt+1){
// 판이 가득차고 O가 완성되지 않은 경우
if(xCnt+oCnt == 9 && !bingo('O'))
System.out.println("valid");
// O가 완성 되지 않고, X가 완성 된 경우
else if(!bingo('O') && bingo('X'))
System.out.println("valid");
// 둘 다 아닌 경우는 X도 이기지 못함
else
System.out.println("invalid");
}
// O가 이긴 경우
else if(xCnt == oCnt)
{
// X가 완성되지 않고, O가 완성된 경우
if(!bingo('X') && bingo('O'))
System.out.println("valid");
// 그게 아니라면 먼저 두는 것은 X이기 때문에 이길 수 없음
else
System.out.println("invalid");
}
// 둘 다 완성되지 않은 경우
else
System.out.println("invalid");
}
}
public static boolean bingo(char c)
{
for(int i=0; i<3; i++)
{
// 가로 한줄로 성공한 경우
if(map[i][0] == c && map[i][1] == c && map[i][2] == c)
return true;
}
for(int i=0; i<3; i++)
{
// 세로 한줄로 성공한 경우
if(map[0][i] == c && map[1][i] == c && map[2][i] == c)
return true;
}
// 대각선으로 성공한 경우, 좌상에서 우하로
if(map[0][0] == c && map[1][1] == c && map[2][2] == c)
return true;
// 대각선으로 성공한 경우, 우상에서 좌하로
if(map[0][2] == c && map[1][1] == c && map[2][0] == c)
return true;
// 여기까지 return이 없을 경우 끝나지 않음
return false;
}
}