Algorithm for Determining Tic Tac Toe Game Over

2019-01-01 05:00发布

I've written a game of tic-tac-toe in Java, and my current method of determining the end of the game accounts for the following possible scenarios for the game being over:

  1. The board is full, and no winner has yet been declared: Game is a draw.
  2. Cross has won.
  3. Circle has won.

Unfortunately, to do so, it reads through a predefined set of these scenarios from a table. This isn't necessarily bad considering that there are only 9 spaces on a board, and thus the table is somewhat small, but is there a better algorithmic way of determining if the game is over? The determination of whether someone has won or not is the meat of the problem, since checking if 9 spaces are full is trivial.

The table method might be the solution, but if not, what is? Also, what if the board were not size n=9? What if it were a much larger board, say n=16, n=25, and so on, causing the number of consecutively placed items to win to be x=4, x=5, etc? A general algorithm to use for all n = { 9, 16, 25, 36 ... }?

21条回答
爱死公子算了
2楼-- · 2019-01-01 05:36

This is a really simple way to check.

    public class Game() { 

    Game player1 = new Game('x');
    Game player2 = new Game('o');

    char piece;

    Game(char piece) {
       this.piece = piece;
    }

public void checkWin(Game player) {

    // check horizontal win
    for (int i = 0; i <= 6; i += 3) {

        if (board[i] == player.piece &&
                board[i + 1] == player.piece &&
                board[i + 2] == player.piece)
            endGame(player);
    }

    // check vertical win
    for (int i = 0; i <= 2; i++) {

        if (board[i] == player.piece &&
                board[i + 3] == player.piece &&
                board[i + 6] == player.piece)
            endGame(player);
    }

    // check diagonal win
    if ((board[0] == player.piece &&
            board[4] == player.piece &&
            board[8] == player.piece) ||
            board[2] == player.piece &&
            board[4] == player.piece &&
            board[6] == player.piece)
        endGame(player);
    }

}

查看更多
美炸的是我
3楼-- · 2019-01-01 05:38

you can use a magic square http://mathworld.wolfram.com/MagicSquare.html if any row, column, or diag adds up to 15 then a player has won.

查看更多
素衣白纱
4楼-- · 2019-01-01 05:39

Constant time O(8), on average 4 short AND's. Player = short number. Needs additional checks for making sure move is valid.

// O(8)
boolean isWinner(short X) {
    for (int i = 0; i < 8; i++)
        if ((X & winCombinations[i]) == winCombinations[i])
            return true;
    return false;
}

short[] winCombinations = new short[]{
  7, 7 << 3, 7 << 6, // horizontal
  73, 73 << 1, 73 << 2, // vertical
  273, // diagonal
  84   // anti-diagonal
};

for (short X = 0; X < 511; X++)
   System.out.println(isWinner(X));
查看更多
登录 后发表回答