A Tic-Tac-Toe board of size 3X3 is given after all the moves are played, i.e., all nine spots are filled. Find out if the given board is valid, i.e., is it possible to reach this board position after a set of moves or not.
Note that every arbitrarily filled grid of 9 spaces isn’t valid, e.g., a grid filled with 3 X and 6 O isn’t a valid situation because each player needs to take alternate turns.
Note: Â The game starts with X.

Input:
board[] = {'X', 'X', 'O',
'O', 'O', 'X',
'X', 'O', 'X'};
Output: Valid
Explanation: This is a valid board.Input:
board[] = {'O', 'X', 'X',
'O', 'X', 'X',
'O', 'O', 'X'};
Output: Invalid
Explanation: Both X and O cannot win.
Count Moves and Check Winning Configurations - O(1) Time and O(1) Space
The idea is to first count the number of X and O moves to ensure the move sequence is valid. Then, check all eight possible winning lines for both players. Since the board is completely filled and X always starts, the board is valid only if:
- X = O + 1
- Both players do not win simultaneously.
- If O wins, it must be the only winner.
- If X wins, it must also be the only winner.
- If no one wins, the board is also valid.
Working of Approach:
- Count the number of 'X' and 'O' on the board and ensure that X has exactly one more move than O, since the board is completely filled and X always starts.
- Check all 8 possible winning combinations and count how many winning lines are formed by X and O.
- If only X has one winning line, or only O has one winning line, the board is valid according to the move count.
- If neither player has a winning line, the board is also valid.
- Otherwise (both players win or any invalid configuration), return false.
Let us understand with an example:
Input: board[] = {'X', 'X', 'O', 'O', 'O', 'X', 'X', 'O', 'X'};
- Count the symbols on the board: xCount = 5 and oCount = 4. Since xCount = oCount + 1, the move count is valid.
- Check all 8 possible winning combinations for X. No winning line is found, so cx = 0.
- Check all 8 possible winning combinations for O. No winning line is found, so co = 0.
- Since neither player has a winning line (cx = 0 and co = 0), the condition !co && !cx becomes true.
- Therefore, the function returns true, and the output is "Valid".
#include <iostream>
using namespace std;
// This matrix stores all possible winning
// combinations in Tic-Tac-Toe.
int win[8][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {0, 3, 6}, {1, 4, 7}, {2, 5, 8}, {0, 4, 8}, {2, 4, 6}};
// Returns the number of winning combinations
// formed by the given player.
int isCWin(char *board, char c)
{
int cnt = 0;
// 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)
cnt++;
}
return cnt;
}
bool isValid(char board[9])
{
int xCount = 0, oCount = 0;
// Count the number of X's and O's
for (int i = 0; i < 9; i++)
{
if (board[i] == 'X')
xCount++;
else if (board[i] == 'O')
oCount++;
}
int cx = isCWin(board, 'X');
int co = isCWin(board, 'O');
// X always plays first, so X must have
// exactly one more move than O.
if (xCount != oCount + 1)
return false;
// Only O wins
if (cx == 0 && co == 1)
return true;
// Only X wins
if (co == 0 && cx == 1)
return true;
// No player wins
if (cx == 0 && co == 0)
return true;
return false;
}
int main()
{
char board[9] = {'X', 'X', 'O', 'O', 'O', 'X', 'X', 'O', 'X'};
if (isValid(board))
cout << "Valid";
else
cout << "Invalid";
return 0;
}
public class GFG {
// This matrix stores all possible winning
// combinations in Tic-Tac-Toe.
static int[][] win
= { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 },
{ 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 },
{ 0, 4, 8 }, { 2, 4, 6 } };
// Returns the number of winning combinations
// formed by the given player.
static int isCWin(char[] board, char c)
{
int cnt = 0;
// 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)
cnt++;
}
return cnt;
}
static boolean isValid(char[] board)
{
int xCount = 0, oCount = 0;
// Count the number of X's and O's
for (int i = 0; i < 9; i++) {
if (board[i] == 'X')
xCount++;
else if (board[i] == 'O')
oCount++;
}
int cx = isCWin(board, 'X');
int co = isCWin(board, 'O');
// X always plays first, so X must have
// exactly one more move than O.
if (xCount != oCount + 1)
return false;
// Only O wins
if (cx == 0 && co == 1)
return true;
// Only X wins
if (co == 0 && cx == 1)
return true;
// No player wins
if (cx == 0 && co == 0)
return true;
return false;
}
public static void main(String[] args)
{
char[] board = { 'X', 'X', 'O', 'O', 'O',
'X', 'X', 'O', 'X' };
if (isValid(board))
System.out.println("Valid");
else
System.out.println("Invalid");
}
}
# Returns the number of winning combinations
# formed by the given player.
def isCWin(board, c):
win = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
cnt = 0
# Check all possible winning combinations
for i in range(8):
if board[win[i][0]] == c and board[win[i][1]] == c and board[win[i][2]] == c:
cnt += 1
return cnt
def isValid(board):
xCount = 0
oCount = 0
# Count the number of X's and O's
for i in range(9):
if board[i] == 'X':
xCount += 1
elif board[i] == 'O':
oCount += 1
cx = isCWin(board, 'X')
co = isCWin(board, 'O')
# X always plays first, so X must have
# exactly one more move than O.
if xCount!= oCount + 1:
return False
# Only O wins
if cx == 0 and co == 1:
return True
# Only X wins
if co == 0 and cx == 1:
return True
# No player wins
if cx == 0 and co == 0:
return True
return False
if __name__ == '__main__':
board = ['X', 'X', 'O', 'O', 'O', 'X', 'X', 'O', 'X']
if isValid(board):
print('Valid')
else:
print('Invalid')
using System;
class GFG {
// This matrix stores all possible winning
// combinations in Tic-Tac-Toe.
static int[, ] win
= { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 },
{ 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 },
{ 0, 4, 8 }, { 2, 4, 6 } };
// Returns the number of winning combinations
// formed by the given player.
static int isCWin(char[] board, char c)
{
int cnt = 0;
// 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)
cnt++;
}
return cnt;
}
static bool isValid(char[] board)
{
int xCount = 0, oCount = 0;
// Count the number of X's and O's
for (int i = 0; i < 9; i++) {
if (board[i] == 'X')
xCount++;
else if (board[i] == 'O')
oCount++;
}
int cx = isCWin(board, 'X');
int co = isCWin(board, 'O');
// X always plays first, so X must have
// exactly one more move than O.
if (xCount != oCount + 1)
return false;
// Only O wins
if (cx == 0 && co == 1)
return true;
// Only X wins
if (co == 0 && cx == 1)
return true;
// No player wins
if (cx == 0 && co == 0)
return true;
return false;
}
static void Main(string[] args)
{
char[] board = { 'X', 'X', 'O', 'O', 'O',
'X', 'X', 'O', 'X' };
if (isValid(board))
Console.WriteLine("Valid");
else
Console.WriteLine("Invalid");
}
}
// Returns the number of winning combinations
// formed by the given player.
function isCWin(board, c)
{
const win = [
[ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ], [ 0, 3, 6 ],
[ 1, 4, 7 ], [ 2, 5, 8 ], [ 0, 4, 8 ], [ 2, 4, 6 ]
];
let cnt = 0;
// Check all possible winning combinations
for (let i = 0; i < 8; i++) {
if (board[win[i][0]] === c && board[win[i][1]] === c
&& board[win[i][2]] === c)
cnt++;
}
return cnt;
}
function isValid(board)
{
let xCount = 0, oCount = 0;
// Count the number of X's and O's
for (let i = 0; i < 9; i++) {
if (board[i] === "X")
xCount++;
else if (board[i] === "O")
oCount++;
}
const cx = isCWin(board, "X");
const co = isCWin(board, "O");
// X always plays first, so X must have
// exactly one more move than O.
if (xCount !== oCount + 1)
return false;
// Only O wins
if (cx === 0 && co === 1)
return true;
// Only X wins
if (co === 0 && cx === 1)
return true;
// No player wins
if (cx === 0 && co === 0)
return true;
return false;
}
// Driver Code
const board =
[ "X", "X", "O", "O", "O", "X", "X", "O", "X" ];
if (isValid(board))
console.log("Valid");
else
console.log("Invalid");
Output
Valid