给你一个字符串数组 board 表示井字游戏的棋盘。当且仅当在井字游戏过程中,棋盘有可能达到 board 所显示的状态时,才返回 true 。

井字游戏的棋盘是一个 3 x 3 数组,由字符 ' ','X' 和 'O' 组成。字符 ' ' 代表一个空位。

以下是井字游戏的规则:

玩家轮流将字符放入空位(' ')中。 玩家 1 总是放字符 'X' ,而玩家 2 总是放字符 'O' 。 'X' 和 'O' 只允许放置在空位中,不允许对已放有字符的位置进行填充。 当有 3 个相同(且非空)的字符填充任何行、列或对角线时,游戏结束。 当所有位置非空时,也算为游戏结束。 如果游戏结束,玩家不允许再放置字符。  

示例 1: alt

输入:board = ["O "," "," "] 输出:false 解释:玩家 1 总是放字符 "X" 。

示例 2: alt

输入:board = ["XOX"," X "," "] 输出:false 解释:玩家应该轮流放字符。

示例 3: alt

输入:board = ["XXX"," ","OOO"] 输出:false

示例 4: alt

输入:board = ["XOX","O O","XOX"] 输出:true  

提示:

board.length == 3 board[i].length == 3 board[i][j] 为 'X'、'O' 或 ' '

题解: 井字棋应该算是比较经典的一类游戏了吧,X先走的话,如果X赢,那么X的个数比O多1,如果O赢,那么X的个数和O的个数相等。

//写的好丑,不忍直视
class Solution {
public:
    int Xheng1, Xheng2, Xheng3, Xshu1, Xshu2, Xshu3, Xzuoxie, Xyouxie, cntX;
    int Oheng1, Oheng2, Oheng3, Oshu1, Oshu2, Oshu3, Ozuoxie, Oyouxie, cntO;
    bool Xwin, Owin;
    bool validTicTacToe(vector<string>& board) {
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < 3; j++){
                int ch = board[i][j];
                if(ch == 'X'){
                    cntX++;
                    if(i == 0) Xheng1++;
                    if(i == 1) Xheng2++;
                    if(i == 2) Xheng3++;
                    if(j == 0) Xshu1++;
                    if(j == 1) Xshu2++;
                    if(j == 2) Xshu3++;
                    if(i == j) Xzuoxie++;
                    if(i + j == 2) Xyouxie++;
                    if(Xheng1 == 3 || Xheng2 == 3 || Xheng3 == 3 || Xshu1 == 3 || Xshu2 == 3 || Xshu3 == 3 || Xzuoxie == 3 || Xyouxie == 3) Xwin = true;
                }
                if(ch == 'O'){
                    cntO++;
                    if(i == 0) Oheng1++;
                    if(i == 1) Oheng2++;
                    if(i == 2) Oheng3++;
                    if(j == 0) Oshu1++;
                    if(j == 1) Oshu2++;
                    if(j == 2) Oshu3++;
                    if(i == j) Ozuoxie++;
                    if(i + j == 2) Oyouxie++;
                    if(Oheng1 == 3 || Oheng2 == 3 || Oheng3 == 3 || Oshu1 == 3 || Oshu2 == 3 || Oshu3 == 3 || Ozuoxie == 3 || Oyouxie == 3) Owin = true;
                }
            }
        }
        if(cntX - cntO > 1 || cntX < cntO) return false;
        //if(cntX > 4) return false;
        if(Xwin && Owin) return false;
        if(Xwin && cntX - cntO != 1) return false;
        if(Owin && cntX != cntO) return false;
        return true;
    }
};
//题解的写法真是赏心悦目。。。
class Solution {
public:
    bool validTicTacToe(vector<string>& board) {
        int xCount = 0, oCount = 0;
        for (string & row : board) {
            for (char c : row) {
                xCount = (c == 'X') ? (xCount + 1) : xCount;
                oCount = (c == 'O') ? (oCount + 1) : oCount;
            }
        }
        if (oCount != xCount && oCount != xCount - 1) {
            return false;
        }
        if (win(board, 'X') && oCount != xCount - 1) {
            return false;
        }
        if (win(board, 'O') && oCount != xCount) {
            return false;
        }
        return true;
    }

    bool win(vector<string>& board, char p) {
        for (int i = 0; i < 3; ++i) {
            if (p == board[i][0] && p == board[i][1] && p == board[i][2]) {
                return true;
            }
            if (p == board[0][i] && p == board[1][i] && p == board[2][i]) {
                return true;
            }
        }
        if (p == board[0][0] && p == board[1][1] && p == board[2][2]) {
            return true;
        }
        if (p == board[0][2] && p == board[1][1] && p == board[2][0]) {
            return true;
        }
        return false;
    }
};