Open In App

Implementation of Tic-Tac-Toe for 2 person game (User vs. User)

Improve
Improve
Like Article
Like
Save
Share
Report

For 1-Person game (User vs. CPU), please refer Implementation of Tic-Tac-Toe game 

Rules of the Game

  • The game is to be played between two people (in this program between HUMAN to HUMAN).
  • First the game will take the names of the two players as input.
  • One of the player chooses ‘O’ and the other ‘X’ to mark their respective cells.
  • There would be a game toss, which will decide which player will move first.
  • The game starts with one of the players and the game ends when one of the players has one whole row/ column/ diagonal filled with his/her respective character (‘O’ or ‘X’).
  • If the game is Tie then, A message is displayed “Game is Tie”.

Winning Strategy – An Interesting Fact
If both the players play optimally then it is destined that you will never lose (“although the match can still be drawn”). It doesn’t matter whether you play first or second. In another way – “ Two expert players will always draw ”.
Isn’t this interesting?

Below is the code for the Game: 

C++




// C++ program to play Tic-Tac-Toe
#include <bits/stdc++.h>
using namespace std;
 
// Length of the board
#define SIDE 3
 
// Name of the players
string PLAYER1, PLAYER2;
 
// Function to show the current
// board status
void showBoard(char board[][SIDE])
{
    printf("\n\n");
 
    printf("\t\t\t %c | %c | %c \n",
           board[0][0],
           board[0][1],
           board[0][2]);
 
    printf("\t\t\t------------\n");
 
    printf("\t\t\t %c | %c | %c \n",
           board[1][0],
           board[1][1],
           board[1][2]);
 
    printf("\t\t\t------------\n");
    printf("\t\t\t %c | %c | %c \n\n",
           board[2][0],
           board[2][1],
           board[2][2]);
 
    return;
}
 
// Function to show the instructions
void showInstructions()
{
    printf("\t\t\t Tic-Tac-Toe\n\n");
 
    printf("Choose a cell numbered "
           "from 1 to 9 as below"
           " and play\n\n");
 
    printf("\t\t\t 1 | 2 | 3 \n");
    printf("\t\t\t------------\n");
    printf("\t\t\t 4 | 5 | 6 \n");
    printf("\t\t\t------------\n");
    printf("\t\t\t 7 | 8 | 9 \n\n");
 
    printf("-\t-\t-\t-\t-\t"
           "-\t-\t-\t-\t-\n\n");
 
    return;
}
 
// Function to initialise the game
void initialise(char board[][SIDE],
                int moves[])
{
    // Initiate the random number
    // generator so that the same
    // configuration doesn't arises
    srand(time(NULL));
 
    // Initially the board is empty
    for (int i = 0; i < SIDE; i++) {
        for (int j = 0; j < SIDE; j++)
            board[i][j] = ' ';
    }
 
    // Fill the moves with numbers
    for (int i = 0; i < SIDE * SIDE; i++)
        moves[i] = i;
 
    // randomise the moves
    random_shuffle(moves,
                   moves + SIDE * SIDE);
 
    return;
}
 
// Function to declare winner of the game
void declareWinner(string whoseTurn)
{
    if (whoseTurn == PLAYER1)
        cout << PLAYER1 << " has won\n";
    else
        cout << PLAYER1 << " has won\n";
    return;
}
 
// Function that returns true if
// any of the row is crossed with
// the same player's move
bool rowCrossed(char board[][SIDE])
{
    for (int i = 0; i < SIDE; i++) {
        if (board[i][0] == board[i][1]
            && board[i][1] == board[i][2]
            && board[i][0] != ' ')
            return (true);
    }
    return (false);
}
 
// Function that returns true if any
// of the column is crossed with the
// same player's move
bool columnCrossed(char board[][SIDE])
{
    for (int i = 0; i < SIDE; i++) {
        if (board[0][i] == board[1][i]
            && board[1][i] == board[2][i]
            && board[0][i] != ' ')
            return (true);
    }
    return (false);
}
 
// Function that returns true if any
// of the diagonal is crossed with
// the same player's move
bool diagonalCrossed(char board[][SIDE])
{
    if (board[0][0] == board[1][1]
        && board[1][1] == board[2][2]
        && board[0][0] != ' ')
        return (true);
 
    if (board[0][2] == board[1][1]
        && board[1][1] == board[2][0]
        && board[0][2] != ' ')
        return (true);
 
    return (false);
}
 
// Function that returns true if the
// game is over else it returns a false
bool gameOver(char board[][SIDE])
{
    return (rowCrossed(board)
            || columnCrossed(board)
            || diagonalCrossed(board));
}
 
// Function to play Tic-Tac-Toe
void playTicTacToe(string whoseTurn)
{
    // A 3*3 Tic-Tac-Toe board for playing
    char board[SIDE][SIDE];
 
    int moves[SIDE * SIDE];
 
    // Initialise the game
    initialise(board, moves);
 
    // Show instructions before playing
    showInstructions();
 
    int moveIndex = 0, x, y;
    int r, c;
 
    // Keep playing till the game is
    // over or it is a draw
    while (gameOver(board) == false
           && moveIndex != SIDE * SIDE) {
        if (whoseTurn == PLAYER1) {
 
        // Label for player1 wrong choice
        // of row and column
        player1:
 
            // Input the desired row and
            // column by player 1 to
            // insert X
            cout << PLAYER1
                 << " Enter the respective"
                 << " row and column to "
                    "insert X :\n";
            cin >> r >> c;
 
            if (r <= 3 && c <= 3) {
 
                // To check desired row and
                // column should be empty
                if (board[r - 1] == ' ')
                    board[r - 1] = 'X';
 
                // If input is on already
                // filled position
                else {
                    cout << "You cannot Overlap"
                         << " on Already "
                            "filled position:\n";
                    goto player1;
                }
            }
 
            // Input is not valid
            else {
                cout << "\nInput is not "
                     << "valid please enter "
                     << "right one\n";
 
                goto player1;
            }
 
            showBoard(board);
            moveIndex++;
            whoseTurn = PLAYER2;
        }
 
        else if (whoseTurn == PLAYER2) {
 
        // Label for player2 wrong choice
        // of row and column
        player2:
 
            // Input the desired row and
            // column by player 1 to
            // insert X
            cout << PLAYER2
                 << " Enter the respective"
                 << " row and column to "
                    "insert O :";
            cin >> r >> c;
            if (r <= 3 && c <= 3) {
 
                // Input the desired row and
                // column by player 1 to
                // insert X
                if (board[r - 1] == ' ')
                    board[r - 1] = 'O';
 
                // If input is on already
                // filled position
                else {
                    cout << "You cannot Overlap"
                         << " on Already "
                         << "filled position:\n";
                    goto player2;
                }
            }
 
            // Input is not valid
            else {
                cout << "\nInput is not "
                     << "valid please enter "
                     << "right one :\n";
                goto player2;
            }
 
            showBoard(board);
            moveIndex++;
            whoseTurn = PLAYER1;
        }
    }
 
    // If the game has drawn
    if (gameOver(board) == false
        && moveIndex == SIDE * SIDE)
        printf("It's a draw\n");
    else {
 
        // Toggling the user to declare
        // the actual winner
        if (whoseTurn == PLAYER1)
            whoseTurn = PLAYER2;
        else if (whoseTurn == PLAYER2)
            whoseTurn = PLAYER1;
 
        // Declare the winner
        declareWinner(whoseTurn);
    }
    return;
}
 
// Driver Code
int main()
{
    // Take the name of players
    cout << "Enter name of first Player: ";
    cin >> PLAYER1;
 
    cout << "Enter name of Second Player: ";
    cin >> PLAYER2;
 
    // Use current time as seed for
    // random generator
    srand(time(0));
 
    // Lets do toss
    int toss = rand() % 2;
 
    // Let us play the game
    if (toss == 1) {
        cout << "Player "
             << PLAYER1
             << " win the toss"
             << endl;
 
        playTicTacToe(PLAYER1);
    }
    else {
        cout << "Player "
             << PLAYER2
             << " win the toss"
             << endl;
        playTicTacToe(PLAYER2);
    }
 
    return (0);
}


Python3




import random
 
# Length of the board
SIDE = 3
 
# Function to show the current board status
def showBoard(board):
    print("\n\n")
    for i in range(SIDE):
        print(f"\t\t\t {board[i][0]} | {board[i][1]} | {board[i][2]}")
        if i != SIDE - 1:
            print("\t\t\t------------")
    print("\n")
    return
 
# Function to show the instructions
def showInstructions():
    print("\t\t\t Tic-Tac-Toe\n\n")
    print("Choose a cell numbered from 1 to 9 as below and play\n\n")
    print("\t\t\t 1 | 2 | 3 ")
    print("\t\t\t------------")
    print("\t\t\t 4 | 5 | 6 ")
    print("\t\t\t------------")
    print("\t\t\t 7 | 8 | 9 \n\n")
    print("-\t-\t-\t-\t-\t-\t-\t-\t-\t-\n\n")
    return
 
# Function to initialize the game
def initialise(board, moves):
    random.seed()
    for i in range(SIDE):
        for j in range(SIDE):
            board[i][j] = ' '
    for i in range(SIDE * SIDE):
        moves[i] = i
    random.shuffle(moves)
    return
 
# Function to declare the winner of the game
def declareWinner(whoseTurn):
    print(f"{PLAYER1 if whoseTurn == PLAYER1 else PLAYER2} has won")
    return
 
# Function that returns true if any row is crossed with the same player's move
def rowCrossed(board):
    for i in range(SIDE):
        if board[i][0] == board[i][1] == board[i][2] != ' ':
            return True
    return False
 
# Function that returns true if any column is crossed with the same player's move
def columnCrossed(board):
    for i in range(SIDE):
        if board[0][i] == board[1][i] == board[2][i] != ' ':
            return True
    return False
 
# Function that returns true if any diagonal is crossed with the same player's move
def diagonalCrossed(board):
    if board[0][0] == board[1][1] == board[2][2] != ' ':
        return True
    if board[0][2] == board[1][1] == board[2][0] != ' ':
        return True
    return False
 
# Function that returns true if the game is over else it returns False
def gameOver(board):
    return rowCrossed(board) or columnCrossed(board) or diagonalCrossed(board)
 
# Function to play Tic-Tac-Toe
def playTicTacToe(whoseTurn):
    board = [[' ' for _ in range(SIDE)] for _ in range(SIDE)]
    moves = [i for i in range(SIDE * SIDE)]
 
    # Initialize the game
    initialise(board, moves)
 
    # Show instructions before playing
    showInstructions()
 
    moveIndex = 0
    while not gameOver(board) and moveIndex != SIDE * SIDE:
        if whoseTurn == PLAYER1:
            # Input the desired row and column by player 1 to insert X
            print(f"{PLAYER1} Enter the respective row and column to insert X :")
            r, c = map(int, input().split())
            if 1 <= r <= 3 and 1 <= c <= 3 and board[r - 1] == ' ':
                board[r - 1] = 'X'
            else:
                print("Invalid input. Try again.")
                continue
        else:
            # Input the desired row and column by player 2 to insert O
            print(f"{PLAYER2} Enter the respective row and column to insert O :")
            r, c = map(int, input().split())
            if 1 <= r <= 3 and 1 <= c <= 3 and board[r - 1] == ' ':
                board[r - 1] = 'O'
            else:
                print("Invalid input. Try again.")
                continue
 
        showBoard(board)
        moveIndex += 1
        whoseTurn = PLAYER2 if whoseTurn == PLAYER1 else PLAYER1
 
    # If the game has drawn
    if not gameOver(board) and moveIndex == SIDE * SIDE:
        print("It's a draw")
    else:
        # Toggling the user to declare the actual winner
        whoseTurn = PLAYER2 if whoseTurn == PLAYER1 else PLAYER1
        declareWinner(whoseTurn)
    return
 
# Driver code
PLAYER1 = input("Enter name of first Player: ")
PLAYER2 = input("Enter name of Second Player: ")
 
# Use current time as seed for random generator
random.seed()
 
# Let's do a toss
toss = random.randint(0, 1)
 
# Let us play the game
if toss == 1:
    print(f"Player {PLAYER1} won the toss")
    playTicTacToe(PLAYER1)
else:
    print(f"Player {PLAYER2} won the toss")
    playTicTacToe(PLAYER2)


Output: 
Below is the output of the above code: 

 



Last Updated : 11 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads