📜  给定井字游戏板配置的有效性

📅  最后修改于: 2022-05-13 01:57:22.962000             🧑  作者: Mango

给定井字游戏板配置的有效性

玩了一些动作后会给出一个井字棋盘。找出给定的棋盘是否有效,即是否有可能在一些动作之后到达该棋盘位置。
请注意,每个由 9 个空格组成的任意填充网格都是无效的,例如,填充有 3 个 X 和 6 个 O 的网格不是有效的情况,因为每个玩家都需要交替轮流。

井字形

输入以大小为 9 的一维数组的形式给出。
例子:

Input: board[] =  {'X', 'X', 'O', 
                   'O', 'O', 'X',
                   'X', 'O', 'X'};
Output: Valid

Input: board[] =  {'O', 'X', 'X', 
                   'O', 'X', 'X',
                   'O', 'O', 'X'};
Output: Invalid
(Both X and O cannot win)

Input: board[] =  {'O', 'X', ' ', 
                   ' ', ' ', ' ',
                   ' ', ' ', ' '};
Output: Valid
(Valid board with only two moves played)

基本上,要找到输入网格的有效性,我们可以考虑输入网格无效时的条件。让不。 “X”的数量是 countX 和 no。的“O”是countO。由于我们知道游戏从 X 开始,如果满足以下两个条件,则给定的井字游戏网格肯定是无效的
a) countX != countO 和
b) countX != countO + 1
由于“X”始终是第一步,因此还需要第二个条件。
现在这是否意味着所有剩余的董事会职位都是有效的?答案是不。想想输入网格是这样的情况,即 X 和 O 都是直线。这也是无效的位置,因为当一名玩家获胜时游戏结束。所以我们还需要检查以下条件
c) 如果输入格显示双方都处于获胜状态,则为无效位置。
d) 如果输入网格显示 O 的玩家已经放了一条直线(即处于获胜状态)并且 countX != countO,这是一个无效的位置。原因是 O 只在 X 下手之后才下手。由于 X 已经开始比赛,当 X 和 O 打出相同的号码时,O 将获胜。的动作。
e) 如果输入网格显示 X 处于获胜状态,则 xCount 必须比 oCount 大一。
有了上述条件,即 a)、b)、c) 和 d),我们现在可以轻松地制定算法/程序来检查给定井字棋棋盘位置的有效性。

1)  countX == countO or countX == countO + 1
2)  If O is in win condition then check 
     a)     If X also wins, not valid
     b)     If xbox != obox , not valid
3)  If X is in win condition then check if xCount is
     one more than oCount or not  

另一种查找给定棋盘有效性的方法是使用“逆向法”,即排除给定棋盘无效时的所有可能性。

C++
// C++ program to check whether a given tic tac toe
// board is valid or not
#include 
using namespace std;
 
// This matrix is used to find indexes to check all
// possible winning triplets in board[0..8]
int win[8][3] = {{0, 1, 2}, // Check first row.
                {3, 4, 5}, // Check second Row
                {6, 7, 8}, // Check third Row
                {0, 3, 6}, // Check first column
                {1, 4, 7}, // Check second Column
                {2, 5, 8}, // Check third Column
                {0, 4, 8}, // Check first Diagonal
                {2, 4, 6}}; // Check second Diagonal
 
// Returns true if character 'c' wins. c can be either
// 'X' or 'O'
bool isCWin(char *board, char c)
{
    // Check all possible winning combinations
    for (int i=0; i<8; i++)
        if (board[win[i][0]] == c &&
            board[win[i][1]] == c &&
            board[win[i][2]] == c )
            return true;
    return false;
}
 
// Returns true if given board is valid, else returns false
bool isValid(char board[9])
{
    // Count number of 'X' and 'O' in the given board
    int xCount=0, oCount=0;
    for (int i=0; i<9; i++)
    {
    if (board[i]=='X') xCount++;
    if (board[i]=='O') oCount++;
    }
 
    // Board can be valid only if either xCount and oCount
    // is same or count is one more than oCount
    if (xCount==oCount || xCount==oCount+1)
    {
        // Check if 'O' is winner
        if (isCWin(board, 'O'))
        {
            // Check if 'X' is also winner, then
            // return false
            if (isCWin(board, 'X'))
                return false;
 
            // Else return true xCount and yCount are same
            return (xCount == oCount);
        }
 
        // If 'X' wins, then count of X must be greater
        if (isCWin(board, 'X') && xCount != oCount + 1)
        return false;
 
        // If 'O' is not winner, then return true
        return true;
    }
    return false;
}
 
// Driver program
int main()
{
char board[] = {'X', 'X', 'O',
                'O', 'O', 'X',
                'X', 'O', 'X'};
(isValid(board))? cout << "Given board is valid":
                    cout << "Given board is not valid";
return 0;
}


Java
// Java program to check whether a given tic tac toe
// board is valid or not 
class GFG {
 
// This matrix is used to find indexes to check all
// possible winning triplets in board[0..8]
    static int win[][] = {{0, 1, 2}, // Check first row.
    {3, 4, 5}, // Check second Row
    {6, 7, 8}, // Check third Row
    {0, 3, 6}, // Check first column
    {1, 4, 7}, // Check second Column
    {2, 5, 8}, // Check third Column
    {0, 4, 8}, // Check first Diagonal
    {2, 4, 6}}; // Check second Diagonal
 
// Returns true if character 'c' wins. c can be either
// 'X' or 'O'
    static boolean isCWin(char[] board, char c) {
        // Check all possible winning combinations
        for (int i = 0; i < 8; i++) {
            if (board[win[i][0]] == c
                    && board[win[i][1]] == c
                    && board[win[i][2]] == c) {
                return true;
            }
        }
        return false;
    }
 
// Returns true if given board is valid, else returns false
    static boolean isValid(char board[]) {
        // Count number of 'X' and 'O' in the given board
        int xCount = 0, oCount = 0;
        for (int i = 0; i < 9; i++) {
            if (board[i] == 'X') {
                xCount++;
            }
            if (board[i] == 'O') {
                oCount++;
            }
        }
 
        // Board can be valid only if either xCount and oCount
        // is same or count is one more than oCount
        if (xCount == oCount || xCount == oCount + 1) {
            // Check if 'O' is winner
            if (isCWin(board, 'O')) {
                // Check if 'X' is also winner, then
                // return false
                if (isCWin(board, 'X')) {
                    return false;
                }
 
                // Else return true xCount and yCount are same
                return (xCount == oCount);
            }
 
            // If 'X' wins, then count of X must be greater
            if (isCWin(board, 'X') && xCount != oCount + 1) {
                return false;
            }
 
            // If 'O' is not winner, then return true
            return true;
        }
        return false;
    }
 
// Driver program
    public static void main(String[] args) {
        char board[] = {'X', 'X', 'O', 'O', 'O', 'X', 'X', 'O', 'X'};
 
        if ((isValid(board))) {
            System.out.println("Given board is valid");
        } else {
            System.out.println("Given board is not valid");
        }
    }
}
//this code contributed by PrinciRaj1992


Python3
# Python3 program to check whether a given tic tac toe
# board is valid or not
 
# Returns true if char wins. Char can be either
# 'X' or 'O'
def win_check(arr, char):
    # Check all possible winning combinations
    matches = [[0, 1, 2], [3, 4, 5],
               [6, 7, 8], [0, 3, 6],
               [1, 4, 7], [2, 5, 8],
               [0, 4, 8], [2, 4, 6]]
 
    for i in range(8):
        if(arr[matches[i][0]] == char and
            arr[matches[i][1]] == char and
            arr[matches[i][2]] == char):
            return True
    return False
 
def is_valid(arr):
    # Count number of 'X' and 'O' in the given board
    xcount = arr.count('X')
    ocount = arr.count('O')
     
    # Board can be valid only if either xcount and ocount
    # is same or count is one more than oCount
    if(xcount == ocount+1 or xcount == ocount):
        # Check if O wins
        if win_check(arr, 'O'):
            # Check if X wins, At a given point only one can win,
            # if X also wins then return Invalid
            if win_check(arr, 'X'):
                return "Invalid"
 
            # O can only win if xcount == ocount in case where whole
            # board has values in each position.
            if xcount == ocount:
                return "Valid"
 
        # If X wins then it should be xc == oc + 1,
        # If not return Invalid    
        if win_check(arr, 'X') and xcount != ocount+1:
            return "Invalid"
         
        # if O is not the winner return Valid
        if not win_check(arr, 'O'):
            return "Valid"
         
    # If nothing above matches return invalid
    return "Invalid"
 
 
# Driver Code
arr = ['X', 'X', 'O',
       'O', 'O', 'X',
       'X', 'O', 'X']
print("Given board is " + is_valid(arr))


C#
// C# program to check whether a given
// tic tac toe board is valid or not
using System;
 
class GFG
{
 
// This matrix is used to find indexes
// to check all possible winning triplets
// in board[0..8]
public static int[][] win = new int[][]
{
    new int[] {0, 1, 2},
    new int[] {3, 4, 5},
    new int[] {6, 7, 8},
    new int[] {0, 3, 6},
    new int[] {1, 4, 7},
    new int[] {2, 5, 8},
    new int[] {0, 4, 8},
    new int[] {2, 4, 6}
};
 
// Returns true if character 'c'
// wins. c can be either 'X' or 'O'
public static bool isCWin(char[] board,
                          char c)
{
    // Check all possible winning
    // combinations
    for (int i = 0; i < 8; i++)
    {
        if (board[win[i][0]] == c &&
            board[win[i][1]] == c &&
            board[win[i][2]] == c)
        {
            return true;
        }
    }
    return false;
}
 
// Returns true if given board
// is valid, else returns false
public static bool isValid(char[] board)
{
    // Count number of 'X' and
    // 'O' in the given board
    int xCount = 0, oCount = 0;
    for (int i = 0; i < 9; i++)
    {
        if (board[i] == 'X')
        {
            xCount++;
        }
        if (board[i] == 'O')
        {
            oCount++;
        }
    }
 
    // Board can be valid only if either
    // xCount and oCount is same or count
    // is one more than oCount
    if (xCount == oCount ||
        xCount == oCount + 1)
    {
        // Check if 'O' is winner
        if (isCWin(board, 'O'))
        {
            // Check if 'X' is also winner,
            // then return false
            if (isCWin(board, 'X'))
            {
                return false;
            }
 
            // Else return true xCount
            // and yCount are same
            return (xCount == oCount);
        }
 
        // If 'X' wins, then count of
        // X must be greater
        if (isCWin(board, 'X') &&
            xCount != oCount + 1)
        {
            return false;
        }
 
        // If 'O' is not winner,
        // then return true
        return true;
    }
    return false;
}
 
// Driver Code
public static void Main(string[] args)
{
    char[] board = new char[] {'X', 'X', 'O', 'O', 'O',
                                    'X', 'X', 'O', 'X'};
 
    if ((isValid(board)))
    {
        Console.WriteLine("Given board is valid");
    }
    else
    {
        Console.WriteLine("Given board is not valid");
    }
}
}
 
// This code is contributed by Shrikant13


PHP


Javascript


输出:

Given board is valid

感谢 Utkarsh 提出这个解决方案。