오목

2025. 2. 3. 13:29알고리즘/코드트리(완전탐색)

 

문제 설명

문제는 굉장히 이해하기 쉽다. 기존의 오목과 유사한 문제이다. 하지만 코드로 작성하는 과정에서는 굉장히 까다로울 수 있다 위치 한 곳을 바탕으로 가로, 오른쪽 대각선, 세로, 왼쪽 대각선을 비교하면서 흰색이나 검은색의 승리라고 판단되면 오목 가운데 위치와 흰색, 검은색 누가 이겼는지 출력해주면 된다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int[][] okmok;
    static int cnt;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        okmok = new int[19][19];

        // 오목 판 입력 받기
        for (int i = 0; i < 19; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < 19; j++) {
                okmok[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 오목 검사
        for (int i = 0; i < 19; i++) {
            for (int j = 0; j < 19; j++) {
                if (okmok[i][j] == 1 || okmok[i][j] == 2) {
                    if (valid(i, j)) {
                        printResult(okmok[i][j], i, j+2);
                        return;
                    }
                    if (valid2(i, j)) {
                        printResult(okmok[i][j], i+2, j);
                        return;
                    }
                    if (valid3(i, j)) {
                        printResult(okmok[i][j], i+2, j+2);
                        return;
                    }
                    if (valid4(i, j)) {
                        printResult(okmok[i][j], i+2, j-2);
                        return;
                    }
                }
            }
        }

        // 승부가 결정되지 않은 경우
        System.out.println(0);
    }

    private static void printResult(int winner, int i, int j) {
        System.out.println(winner);
        System.out.println((i + 1) + " " + (j + 1)); // 가장 왼쪽/위쪽 돌의 위치 출력
    }

    // 가로 (→) 검사
    private static boolean valid(int i, int j) {
        if (j + 4 >= 19) return false;
        int num = okmok[i][j];

        for (int idx = 0; idx < 5; idx++) {
            if (okmok[i][j + idx] != num) return false;
        }
        return true;
    }

    // 세로 (↓) 검사
    private static boolean valid2(int i, int j) {
        if (i + 4 >= 19) return false;
        int num = okmok[i][j];

        for (int idx = 0; idx < 5; idx++) {
            if (okmok[i + idx][j] != num) return false;
        }
        return true;
    }

    // 대각선 ↘ (오른쪽 아래) 검사
    private static boolean valid3(int i, int j) {
        if (i + 4 >= 19 || j + 4 >= 19) return false;
        int num = okmok[i][j];

        for (int idx = 0; idx < 5; idx++) {
            if (okmok[i + idx][j + idx] != num) return false;
        }
        return true;
    }

    // 대각선 ↙ (왼쪽 아래) 검사
    private static boolean valid4(int i, int j) {
        if (i + 4 >= 19 || j - 4 < 0) return false;
        int num = okmok[i][j];

        for (int idx = 0; idx < 5; idx++) {
            if (okmok[i + idx][j - idx] != num) return false;
        }
        return true;
    }
}

기존의 19 * 19 배열이 최대이기 때문에 19 크기의 이상이 판단되면 오목이 될 수 없다고 판단했다. 또한, 오목이 된다면 어떤 형식으로 나열된 오목인지에 따라 위치를 설정해주었고 오목이 없다면 0을 출력해주면서 코드를 작성했다.