Tic Tac Toe In C++ - C++ Programming Tutorial
C++ Course / Miscellaneous / Tic Tac Toe In C++

Tic Tac Toe In C++

BLUF: Mastering Tic Tac Toe In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Tic Tac Toe In C++

C++ is renowned for its efficiency. Learn how Tic Tac Toe In C++ enables low-level control and high-performance computing in the tutorial below.

Tic-tac-toe is a simple game for two players that typically results in a draw if both players make optimal moves. This game is alternatively called Xs and Os or noughts and crosses.

A computer or another electronic device can be employed to engage in a game of tic-tac-toe, a classic pastime often played using pen and paper. This enduring game serves as the basis for various others, such as Connect 4.

History of Tic-Tac-Toe

During the time around the initial century B.C., an early form of the game was enjoyed within the Roman Empire. The term "terni lapilli" signifies the use of three pebbles simultaneously. Archaeological findings in the Roman Empire reveal remnants adorned with grid markings made from chalk used in the game. Similarly, ancient Egyptian archaeological sites have also provided proof of the game being played in that era.

The initial written record of the British term for the game, "noughts and crosses," dates back to 1864. The term "tick-tack-toe" made its literary debut in 1884, initially describing a children's game played on a slate.

Rules of the Game

  • The game must be played by two players (in this program between HUMAN and COMPUTER).
  • Both players mark their cells with the letters "O" and "X".
  • The game ends when one of the players fills an entire row, column or diagonal with either the character ('O' or 'X') of that player.
  • If no one wins, the match is considered a draw.
  • Program Break Down

Example

# define COMPUTER 1
# define HUMAN 2
# define SIDE 3 
# define COMPUTERMOVE 'O'
# define HUMANMOVE 'X'

Here, we have predetermined a selection of moves that will be executed during the game. The board size has been set to 3, with the computer's moves represented by 'O' and the human or user's moves represented by 'X'.

Example

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 ;
}

The function named void showBoard will display the current state of our 3X3 board, which has been set with numbers 1 to 9 for representation.

Example

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 ;
}

The mentioned function, specifically void showInstruction, will display guidelines such as selecting a cell numbered from 1 to 9 as indicated below, and then proceed with the game.

Example

void initialize ( 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 ;
}

The function mentioned above, named void initialize, is responsible for setting up random numbers to avoid the repetition of the same configuration. At the beginning, the game board is completely empty.

Example

void declareWinner ( int whoseTurn )
{
	if ( whoseTurn == COMPUTER )
		printf ( " COMPUTER has won \ n " ) ;
	else
		printf ( " HUMAN has won \ n " ) ;
	return ;
}

The function named declareWinner, which has a return type of void, is responsible for determining the game's victor, whether it be the computer or the human player.

Example

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 ) ;
}

The function named bool rowCrossed will determine whether a row has been completed by the player's move, returning either true or false based on this condition.

Example

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 ) ;
}

The function above, specifically the bool columnCrossed function, will indicate whether a player's move crosses any columns by returning either true or false.

Example

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);
}

The function named bool diagonalCrossed will output either true or false based on whether the player's move crosses any of the diagonals.

Example

bool gameOver ( char board [ ] [ SIDE ] )
{
	return ( rowCrossed ( board ) || columnCrossed ( board ) || diagonalCrossed ( board ) ) ;
}

The function named gameOver will return a boolean value of true or false to indicate whether the game has ended.

Example

void playTicTacToe ( int 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 the instructions before playing
	showInstructions ( ) ;
	int moveIndex = 0 , x , y ;
	// Keep playing till the game is over or it is a draw
	while ( gameOver ( board ) == false &&
			moveIndex != SIDE * SIDE )
	{
		if ( whoseTurn == COMPUTER )
		{
			x = moves [ moveIndex ] / SIDE ;
			y = moves [ moveIndex ] % SIDE ;
			board [ x ] [ y ] = COMPUTERMOVE ;
			printf ( " COMPUTER has put a % c in cell % d \ n " , COMPUTERMOVE , moves [ moveIndex ] + 1 ) ;
			showBoard ( board ) ;
			moveIndex + + ;
			whoseTurn = HUMAN ;
		}
		else if ( whoseTurn == HUMAN )
		{
			x = moves [ moveIndex ] / SIDE ;
			y = moves [ moveIndex ] % SIDE ;
			board [ x ] [ y ] = HUMANMOVE ;
			printf ( " HUMAN has put a % c in cell % d \ n " , HUMANMOVE , moves [ moveIndex] + 1 ) ;
			showBoard ( board ) ;
			moveIndex + + ;
			whoseTurn = COMPUTER ;
		}
	}
	// 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 == COMPUTER )
			whoseTurn = HUMAN ;
		else if ( whoseTurn == HUMAN )
			whoseTurn = COMPUTER ; 
		// Declare the winner
		declareWinner ( whoseTurn ) ;
	}

The main function responsible for playing tic-tac-toe is the void playTictacToe function.

Program for Tic-Tac-Toe in C++

Example

// A C++ Program to play tic-tac-toe
#include <bits/stdc++.h>
using namespace std;
#define COMPUTER 1
#define HUMAN 2
#define SIDE 3 // Length of the board
// Computer will move with 'O'
// and human with 'X'
#define COMPUTERMOVE 'O'
#define HUMANMOVE 'X'
// A 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;
}

// A 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;
}

// A 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;
}

// A function to declare the winner of the game
void declareWinner(int whoseTurn)
{
    if (whoseTurn == COMPUTER)
        printf("COMPUTER has won\n");
    else
        printf("HUMAN has won\n");
    return;
}

// A 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);
}

// A 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);
}

// A 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);
}

// A 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));
}

// A function to play Tic-Tac-Toe
void playTicTacToe(int 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 the instructions before playing
    showInstructions();

    int moveIndex = 0, x, y;

    // Keep playing till the game is over or it is a draw
    while (gameOver(board) == false &&
           moveIndex != SIDE * SIDE)
    {
        if (whoseTurn == COMPUTER)
        {
            x = moves[moveIndex] / SIDE;
            y = moves[moveIndex] % SIDE;
            board[x][y] = COMPUTERMOVE;
            printf("COMPUTER has put a %c in cell %d\n",
                   COMPUTERMOVE, moves[moveIndex] + 1);
            showBoard(board);
            moveIndex++;
            whoseTurn = HUMAN;
        }

        else if (whoseTurn == HUMAN)
        {
            x = moves[moveIndex] / SIDE;
            y = moves[moveIndex] % SIDE;
            board[x][y] = HUMANMOVE;
            printf("HUMAN has put a %c in cell %d\n",
                   HUMANMOVE, moves[moveIndex] + 1);
            showBoard(board);
            moveIndex++;
            whoseTurn = COMPUTER;
        }
    }

    // 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 == COMPUTER)
            whoseTurn = HUMAN;
        else if (whoseTurn == HUMAN)
            whoseTurn = COMPUTER;

        // Declare the winner
        declareWinner(whoseTurn);
    }
    return;
}

// Driver program
int main()
{
    // Let us play the game with COMPUTER starting first
    playTicTacToe(COMPUTER);

    return (0);
}

Output:

Output

Tic-Tac-Toe

Choose a cell numbered from 1 to 9 as below and play
              1 | 2  | 3  
            - - - - - - - -
              4 | 5  | 6  
            - - - - - - - - 
              7 | 8  | 9  
-    -    -    -    -    -    -    -    -    -
COMPUTER has put a O in cell 6
                |    |    
            - - - - - - - -
                |    | O  
            - - - - - - - -
                |    |    
HUMAN has put a X in cell 7
                |    |    
            - - - - - - - -
                |    | O  
            - - - - - - - -
              X |    |    

COMPUTER has put a O in cell 5
                |    |    
            - - - - - - - -
                | O  | O  
            - - - - - - - -
              X |    |    
HUMAN has put a X in cell 1
              X |    |    
            - - - - - - - -
                | O  | O  
            - - - - - - - -
              X |    |    
COMPUTER has put a O in cell 9
              X |    |    
            - - - - - - - -
                | O  | O  
            - - - - - - - -
              X |    | O  
HUMAN has put a X in cell 8
              X |    |    
            - - - - - - - -
                | O  | O  
            - - - - - - - -
              X | X  | O  

COMPUTER has put a O in cell 4
              X |    |    
            - - - - - - - -
              O | O  | O  
            - - - - - - - -
              X | X  | O  
COMPUTER has won

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience