SWEA/D3

[SWEA] - 4615. 재미있는 오셀로 게임 (D3)

0으하하0 2022. 5. 11. 22:34

[문제]

오셀로라는 게임은 흑돌과 백돌을 가진 사람이 번갈아가며 보드에 돌을 놓아서 최종적으로 보드에 자신의 돌이 많은 사람이 이기는 게임이다.
보드는 4x4, 6x6, 8x8(가로, 세로 길이) 크기를 사용한다. 6x6 보드에서 게임을 할 때, 처음에 플레이어는 다음과 같이 돌을 놓고 시작한다(B : 흑돌, W : 백돌).
4x4, 8x8 보드에서도 동일하게 정가운데에 아래와 같이 배치하고 시작한다.

그리고 흑, 백이 번갈아가며 돌을 놓는다.
처음엔 흑부터 시작하는데 이 때 흑이 돌을 놓을 수 있는 곳은 다음과 같이 4군데이다.

플레이어는 빈공간에 돌을 놓을 수 있다.
단, 자신이 놓을 돌과 자신의 돌 사이에 상대편의 돌이 있을 경우에만 그 곳에 돌을 놓을 수 있고, 그 때의 상대편의 돌은 자신의 돌로 만들 수 있다.
(여기에서 "사이"란 가로/세로/대각선을 의미한다.)
(2, 3) 위치에 흑돌을 놓은 후의 보드는 다음과 같다.

이런 식으로 번갈아가며 흑, 백 플레이어가 돌을 놓는다.
만약 돌을 놓을 곳이 없다면 상대편 플레이어가 다시 돌을 놓는다.
보드에 빈 곳이 없거나 양 플레이어 모두 돌을 놓을 곳이 없으면 게임이 끝나고 그 때 보드에 있는 돌의 개수가 많은 플레이어가 승리하게 된다.

[입력]
첫 번째 줄에 테스트 케이스의 수 T가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 보드의 한 변의 길이 N과 플레이어가 돌을 놓는 횟수 M이 주어진다. N은 4, 6, 8 중 하나이다.
그 다음 M줄에는 돌을 놓을 위치와 돌의 색이 주어진다.
돌의 색이 1이면 흑돌, 2이면 백돌이다.
만약 3 2 1이 입력된다면 (3, 2) 위치에 흑돌을 놓는 것을 의미한다.
돌을 놓을 수 없는 곳은 입력으로 주어지지 않는다.

[출력]
각 테스트 케이스마다 게임이 끝난 후 보드 위의 흑돌, 백돌의 개수를 출력한다.
흑돌이 30개, 백돌이 34인 경우 30 34를 출력한다.

문제 풀기

4615. 재미있는 오셀로 게임

 


[풀이]

  • 초기에 흑돌과 백돌을 세팅하고, (x, y) 좌표와 색을 입력받아서 돌을 둔다.
  • 돌 주변을 탐색하여 자신의 돌을 찾는다. (만약 같은 색의 돌을 찾으면 check = true)
  • 상대의 돌을 자신의 돌로 바꾼다.
import java.util.Scanner;

class Solution {	
	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		
		int t = sc.nextInt();
		
		for(int tc=1; tc<=t; tc++) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			
			int black = 0;
			int white = 0;
			
			int board[][] = new int[n][n];
			
			// 처음 배치 상태
			board[(n/2)-1][n/2] = 1;
			board[n/2][(n/2)-1] = 1;
			board[n/2][n/2] = 2;
			board[(n/2)-1][(n/2)-1] = 2;
			
			for(int i=0; i<m; i++) {
				int x = sc.nextInt()-1;
				int y = sc.nextInt()-1;
				int color = sc.nextInt();
				
				board[x][y] = color;
				
				// 입력받은 (x, y) 좌표의 주변 돌 탐색
				for(int j=-1; j<=1; j++) {
					for(int k=-1; k<=1; k++) {
						if(j==0 && k==0) continue;
						
						// 주변 돌의 좌표를 (xx, yy)로 저장
						int xx = x + j;
						int yy = y + k;
						
						// (xx, yy) 돌이 자신의 돌인지 확인하기 위한 변수
						boolean check = false;
						while(xx >= 0 && xx < n && yy >=0 && yy < n
										&& board[xx][yy] != 0) {
							// 자신의 돌이라면 체크변수에 true값을 저장하고 멈춤
							if(board[xx][yy] == color) {
								check = true;
								break;
							}
							
							// 상대의 돌이라면 다음 좌표 탐색
							xx += j;
							yy += k;
						}
						
						// 상대의 돌을 자신의 돌로 교체
						while(check) {
							if(xx == x && yy == y) break;
							board[xx][yy] = color;
							xx -= j;
							yy -= k;
						}
					}
				}
			}
			
			for(int i=0; i<n; i++) {
				for(int j=0; j<n; j++) {
					if(board[i][j] == 1) black++;
					else if(board[i][j] == 2) white++;
				}
			}
			
			System.out.format("#%d %d %d\n", tc, black, white);
		}
	}
}