Tic-Tac-Toe 만들기

저는 지금 간단한 Tic-Tac-Toe 만들기 예제를 하고 있는 중입니다.
우승 조건은 적어도 하나라도 가로 세로 대각선 빙고가 나오면 된다는 건데
우승했는지 판단하는 부분을 잘 못 짜겠습니다.

제가 생각한 무식한(?) 방법은 가로, 세로, 그리고 대각선 방향으로 for loop 를 돌려서 빙고를 확인 하는 것인데 그런 경우 loop 갯수가 너무 많아지는 건 아닌가 걱정이 되어서 질문을 드립니다.

제가 하면 player 1에 대해서 가로에 대해서 루프, 세로에 대해서 루프, 대각선에 대해서 루프
그리고 같은 작업을 player 2에 대해서 하게 되기 때문에 여러 개의 루프가 발생할 것 같습니다.

혹시 이것을 단순하게 하는 방법이 있을까요?

class TicTacToe {
    char[][] board;

    /** Initialize your data structure here. */
    public TicTacToe(int n) {
        board = new char[n][n];
    }
    
    /** Player {player} makes a move at ({row}, {col}).
        @param row The row of the board.
        @param col The column of the board.
        @param player The player, can be either 1 or 2.
        @return The current winning condition, can be either:
                0: No one wins.
                1: Player 1 wins.
                2: Player 2 wins. */
    public int move(int row, int col, int player) {
        char temp = '';
        if (player == 1) {
            temp = 'X';
        } else {
            temp = 'O';
        }
        
        if (board[row][col] != 'X' || board[row][col] != 'O') {
            board[row][col] = temp;
        }
        
        
       // for (int i = 0; i < row; i++) {
        /// 어떻게 해야 되나...    
       /// 가로, 세로, 그리고 대각선을 각각 X 와 O 에 대해서 확인해야 될 것 같은데....
       // }
    }
}

/**
 * Your TicTacToe object will be instantiated and called as such:
 * TicTacToe obj = new TicTacToe(n);
 * int param_1 = obj.move(row,col,player);
 */

PS. 혹시 너무 설명이 없어서 이해를 못 하신 경우, 답변을 달아주시면 감사하겠습니다. 그것에 맞춰서 내용을 더 추가하겠습니다.

안녕하세요 ㅎㅎㅎ

플레이어가 선택을 할때만 승리인지 아닌지 판단하면 되므로.
플레이어가 선택한 딱 그부분의 가로세로 대각선을 판단하면 댑니다. 그럼 맵을 전부 탐색할 필요가 없죠

답변 감사합니다.
생각해보니 그 부분만 확인하면 되네요.
그럼 그것과 별개로 Array에서 한 줄의 값을 모두 확인하는 함수가 자바에 있나요?
(죄송합니다. 주력 언어의 상태가…)
혹시 자바에 없다면 다른 언어에 이런 기능이 있나요?

그런 고오급 기능이 있다면 저도 알려주세요 ㅎㅎㅎ

아마 iteration을 해야할겁니다.

어레이가 아니라 비트 플래그를 이용하면 될 수도 있겠네요.

32비트 기준 32개의 비트가 한 줄의 상태가 되는거죠.

1은 내가 표시한 곳, 0은 내가 표시하지 않은곳.

어레이를 대체할 순 없고 보조수단으로 써야할듯

주륵…
그저 눈물만 나옵니다…

class TicTacToe {
public:
    enum class Player{ A, B };
    enum class Result{ NONE, WIN, INVALID };

private:
    int ttt = 0;

    static auto mask(int row, int col, Player player = Player::A) {
        return 1 << (row * 8 + col * 2 + (int)player);
    }

    auto is_on(int row, int col, Player player)  {
        return (ttt & mask(row, col, player)) == mask(row, col, player);
    }

    auto end_check()  {
        static int arr[] = {
            mask(0, 0) | mask(0, 1) | mask(0, 2),
            mask(1, 0) | mask(1, 1) | mask(1, 2),
            mask(2, 0) | mask(2, 1) | mask(2, 2),
            mask(0, 0) | mask(1, 0) | mask(2, 0),
            mask(0, 1) | mask(1, 1) | mask(2, 1),
            mask(0, 2) | mask(1, 2) | mask(2, 2),
            mask(0, 0) | mask(1, 1) | mask(2, 2),
            mask(0, 2) | mask(1, 1) | mask(2, 0),
        };

        for(auto i: arr)
            if((ttt & i) == i || (ttt & i << 1) == i << 1)
                return true;

        return false;
    }

public:
    auto move(int row, int col, Player player) {
        if(is_on(row, col, Player::A) || is_on(row, col, Player::B))
            return Result::INVALID;

        if(ttt |= mask(row, col, player); end_check())
            return Result::WIN;

        return Result::NONE;
    }

    friend auto operator!(Player player) {
        return (Player)!(int)player;
    }

    friend auto& operator<<(std::ostream& lhs, TicTacToe& rhs) {
        for(int i = 0; i < 3; ++i) {
            lhs << '|';

            for(int j = 0; j < 3; ++j)
                lhs << (rhs.is_on(i, j, Player::A) ? "O|":
                        rhs.is_on(i, j, Player::B) ? "X|":
                                                     " |");

            lhs << '\n';
        }

        return lhs;
    }
};

비트로 비빈다면 이런 구현이 가능하겠읍니다…

1 Like

으잉