Coders Packet

Tic-Tac-Toe Game using C++

By Sanskriti Saraswat

I have made this well known game called Tic-Tac-Toe using simple C++ programming language. This is a fun game easy to make by the beginners.

Tic-Tac-Toe is a fun game where two people can play at a time. Each player has his/her symbol, i.e. either an 'X' or 'O'. Each player has to make a field of his/her symbol either row-wise, column-wise or diagonally to win the game. Also called "Cross and zero" as the game is played.

Here I have made this game in simple C++ PROGRAMMING LANGUAGE (executing successfully) for beginners to learn and try different techniques to make it better. 

In this code , all the moves are made internally without taking any inputs from the users. Even when it is saying human and computer, all the chances are made by computer internally. This can be taken as a way to learn the game.

#include<bits/stdc++.h> 
using namespace std; 
  
#define computer 1 
#define human 2 
  
#define side 3 // Length of the tic-tac-toe board 
  
// Computer will move with 'O' 
#define computerchance 'O' 
#define humanchance 'X'  // and human with 'X'
  
// A function for displaying current board 
void Board(char board[][side]) 
{ 
    cout<<"\n\n"; 
      
    cout<<"\t\t\t"<<" "<<board[0][0]<<" "<<"|"<<" "<<board[0][1]<<" "<<"|"<<" "<< board[0][2]<<"\n"; 
    cout<<"\t\t\t-----------\n"; 
    cout<<"\t\t\t"<<" "<<board[1][0]<<" "<<"|"<<" "<< board[1][1]<<" "<<"|"<<" "<< board[1][2]<<"\n"; 
    cout<<"\t\t\t-----------\n"; 
    cout<<"\t\t\t"<<" "<<board[2][0]<<" "<<"|"<<" "<<board[2][1]<<" "<<"|"<<" "<<board[2][2]<<"\n"; 
   
    return; 
} 
  
// A function to display the instructions 
void printInstructions() 
{ 
    cout<<"\t\t\t  Tic-Tac-Toe\n\n"; 
    cout<<"Choose a cell numbered from 1 to 9 as below and play\n\n"; 
      
    cout<<"\t\t\t  1 | 2  | 3  \n"; 
    cout<<"\t\t\t--------------\n"; 
    cout<<"\t\t\t  4 | 5  | 6  \n"; 
    cout<<"\t\t\t--------------\n"; 
    cout<<"\t\t\t  7 | 8  | 9  \n\n"; 
      
    cout<<"-\t-\t-\t-\t-\t-\t-\t-\t-\t-"<<endl<<endl; 
  
    return; 
} 
  
  
// A function to initialise the game  
void initialising(char board[][side], int moves[]) 
{ 
    // Initiate the random number generator so that  
    // no same configuration, no repetitions
    srand(time(NULL));  
    for (int i=0; i<side; i++) 
    { 
        for (int j=0; j<side; j++) 
            board[i][j] = ' '; 
    } 
      
    // Filling the moves 
    for (int i=0; i<side*side; i++) 
        moves[i] = i; 
  
    // randomising the moves 
    random_shuffle(moves, moves + side*side); 
      
    return; 
} 
  
// A function to declare the winner of the game 
void Winner(int Turn) 
{ 
    if (Turn == computer) 
        cout<<"COMPUTER has won the game"<<endl; 
    else
        cout<<"HUMAN has won the game"<<endl;
    return; 
} 
  
//to check if row is crossed
bool row_wise(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); 
} 
  
//to check if column is crossed 
bool column_wise(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); 
} 
  
// to check if diagonally crossed
bool diagonally(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 go to false
bool GameOver(char board[][side]) 
{ 
    return(row_wise(board) || column_wise(board) || diagonally(board) ); 
} 
  
// A function to play the game
void play(int Turn) 
{ 
    // A 3*3 board for playing  
    char board[side][side]; 
      
    int moves[side*side]; 
      
    // Initialise the game 
    initialising(board, moves); 
      
    // Show the instructions before playing 
    printInstructions(); 
      
    int pos = 0, i, j; 
      
    // Keep playing till the game is over or it is a draw 
    while (GameOver(board) == false &&  pos != side*side) 
    { 
        if (Turn == computer) 
        { 
            i = moves[pos] / side; 
            j = moves[pos] % side; 
            board[i][j] = computerchance; 
            cout<<"COMPUTER has put a X in cell "<< moves[pos]+1; 
            Board(board); 
            pos++; 
            Turn = human; 
        } 
          
        else if (Turn == human) 
        { 
            i = moves[pos] / side; 
            j = moves[pos] % side; 
            board[i][j] = humanchance; 
            cout<<"HUMAN has put a O in cell "<<moves[pos]+1; 
            Board(board); 
            pos++; 
            Turn = computer; 
        } 
    } 
  
    // If the game has drawn 
    if (GameOver(board) == false && pos == side * side) 
        cout<<"It's a draw"<<endl; 
    else
    { 
        // Toggling the user to declare the actual 
        // winner 
        if (Turn == computer) 
            Turn = human; 
        else if (Turn == human) 
            Turn = computer; 
          
        // Declare the winner 
        Winner(Turn); 
    } 
    return; 
} 
  
// Driver program 
int main() 
{ 
    // Let us play the game with HUMAN starting first 
    play(human); 
      
    return (0); 
} 

Explanation of the code:

The program always starts from the main() function. Here the compiler encounters the play() function with the parameter of "human", which means it is the turn of human (remember chance will be made by the computer). Now the program jumps to play function. Here, I made the board array and moves array and called the initializing() function in which the board and moves are initialized. After initializing, instructions are displayed using the printInstructions() function. Further, the loop continues until the game is over or drawn. This is checked by the GameOver() function, where the fields are checked to be crossed row-wise, column-wise or diagonally using the row_wise() , column_wise() and diagonally() functions respectively.

If the game is not over, then the turn is checked for the computer and human. Accordingly, the moves are made to insert their respective symbols in the empty random spaces of the board. Once the game is over, the players are toggled to get the actual winner, and finally, the winner is displayed using the Winner() function.

This was the code where no user is involved himself/herself. The moves are made internally using the equations and calculations. Well, this might seem boring to many because you can't play yourself. So below is a code for users to play themselves and win.

#include 
using namespace std;
int main()
{
  char board[10] = {'o','1','2','3','4','5','6','7','8','9'}; //such that board starts with number 1
  int player = 1;
  int option;
  int count = 0;
  cout<<"\tTic Toc Toe Game"<<endl<<endl;
  //Enter once atleast 
  do
  {
  cout<<"Player 1: (X)  OR  Player 2 :(0)"<<endl;
  
    cout << endl;
  cout<<"\t\t\t "<<board[1]<<" "<<"|"<<" "<< board[2]<<" "<<"|"<<" "<< board[3]<<endl; 
   cout<<"\t\t\t-----------\n"; 
    cout<<"\t\t\t "<<board[4]<<" "<<"|"<<" "<<board[5]<<" "<<"|"<<" "<< board[6]<<endl; 
    cout<<"\t\t\t-----------\n"; 
    cout<<"\t\t\t "<< board[7]<<" "<<"|"<<" "<<board[8]<<" "<<"|"<<" "<< board[9]<<endl; 
  
  cout<<"(Player "<<player<<") Enter a number: ";
  cin>>option;
  
  if(player == 1)
  {
    switch(option) //switch case to choose and check for space and insert symbol X 
                   //get next move to player 2
    {
      case 1: 
      if(board[1]=='X'|| board[1]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[1] = 'X';
        player = 2; //next move to player 2	
      }
      break;
      
      case 2: 
      if(board[2]=='X'|| board[2]=='O')
      {
        cout<<"Wrong Move"<<endl;
        
      }
      else
      {
        board[2] = 'X';
        player = 2;	
      }
      break;
      
      case 3: 
      if(board[3]=='X'|| board[3]=='O')
      {
        cout<<"Wrong Move"<<endl;
      
      }
      else
      {
        board[3] = 'X';
        player = 2;	
      }
      break;
      case 4: 
      if(board[4]=='X'|| board[4]=='O')
      {
        cout<<"Wrong Move"<<endl;
        
      }
      else
      {
        board[4] = 'X';
        player = 2;	
      }
      break;
      case 5: 
      if(board[5]=='X'|| board[5]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[5] = 'X';	
        player = 2;
      }
      break;
      case 6: 
      if(board[6]=='X'|| board[6]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[6] = 'X';
        player = 2;	
      }
      break;
      case 7: 
      if(board[7]=='X'|| board[7]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[7] = 'X';
        player = 2;	
      }
      break;
      case 8: 
      if(board[8]=='X'|| board[8]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[8] = 'X';	
        player = 2;
      }
      break;
      case 9: 
      if(board[9]=='X'|| board[9]=='O')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[9] = 'X';
        player = 2;	
      }
      break;
      //default case
      default:cout<<"Wrong Move"<<endl;
      break;
    }
  }
  //switch case for inserting 'O'
  else
  {
    switch(option)
    {
      case 1: 
      if(board[1]=='O'|| board[1]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[1] = 'O';
        player = 1; //next move to player 1	
      }
      break;
      
      case 2: 
      if(board[2]=='O'|| board[2]=='X')
      {
        cout<<"Wrong Move"<<endl;

      }
      else
      {
        board[2] = 'O';	
        player = 1;	
      }
      break;
      
      case 3: 
      if(board[3]=='O'||board[3]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[3] = 'O';	
        player = 1;	
      }
      break;
      case 4: 
      if(board[4]=='O'||board[4]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[4] = 'O';	
        player = 1;	
      }
      break;
      case 5: 
      if(board[5]=='O'||board[5]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[5] = 'O';
        player = 1;		
      }
      break;
      case 6: 
      if(board[6]=='O'||board[6]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[6] = 'O';
        player = 1;		
      }
      break;
      case 7: 
      if(board[7]=='O'||board[7]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[7] = 'O';	
        player = 1;	
      }
      break;
      case 8: 
      if(board[8]=='O'||board[8]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[8] = 'O';	
        player = 1;	
      }
      break;
      case 9: 
      if(board[9]=='O'||board[9]=='X')
      {
        cout<<"Wrong Move"<<endl;
      }
      else
      {
        board[9] = 'O';	
        player = 1;	
      }
      break;
      
      default:cout<<"Wrong Move"<<endl;
      break;
    }
  }
  //check for same row or same column or diagonally same
  if (board[1] == board[2] && board[2] == board[3])
    count = 1;
  else if (board[4] == board[5] && board[5] == board[6])
    count = 1;
  else if (board[7] == board[8] && board[8] == board[9])
    count = 1;
  else if (board[1] == board[4] && board[4] == board[7])
    count = 1;
  else if (board[2] == board[5] && board[5] == board[8])
    count = 1;
  else if (board[3] == board[6] && board[6] == board[9])
    count = 1;
  else if (board[1] == board[5] && board[5] == board[9])
    count = 1;
  else if (board[3] == board[5] && board[5] == board[7])
    count = 1;
  else
    count = 0;
  }
  while(count == 0);
  
    cout<<"\tTic Toc Toe Game"<<endl<<endl;
  cout<<"Player 1 (X)  OR  Player 2 (0)"<<endl;
  
      cout << endl;
      cout<<"\t\t\t "<<board[1]<<" "<<"|"<<" "<< board[2]<<" "<<"|"<<" "<< board[3]<<endl; 
   cout<<"\t\t\t-----------"<<endl; 
    cout<<"\t\t\t "<<board[4]<<" "<<"|"<<" "<<board[5]<<" "<<"|"<<" "<< board[6]<<endl; 
    cout<<"\t\t\t-----------"<<endl; 
    cout<<"\t\t\t "<< board[7]<<" "<<"|"<<" "<<board[8]<<" "<<"|"<<" "<< board[9]<<endl; 
  
  //Final winner display
  if(count==1)
  {
    if(player == 1)
    {
      player = 2;
    }
    else if(player == 2)
    {
      player = 1;
    }
    cout<<"Player "<<player<<" win "<<endl;	
  }
  else
    cout<<"Game is a draw"<<endl;
  
  return 0;
}

Explanation of the code:

This code uses a simple technique of switch case. Instead of a 2-D array(as it may be complex for some) a single normal array is used for the tic-tac-toe board which starts with number 1 and ends on number 9. I have used the do-while loop because there is no harm in entering the game at least once.

Empty/original game board is displayed at the starting. Now the main work starts here. I used the variable option to switch it for 'X' (option 1 to insert at position 1 and so on). Here I have checked the condition, if the position is available and correct to insert the symbol then put your symbol and the next move goes to player 2, if not then a statement of the wrong move is displayed. Similarly, we will do the same for the symbol 'O'.

After the switch case, I have checked for any crossed field (row, column, or diagonal). If the value of my variable count has been incremented from 0(declared at starting) then it's a win for one of the players else if the count is equal to 0, it means no player has won.

After toggling the players, the actual winner is displayed (since after making the winning move, the chance is jumped to the next player but the winner is the previous player hence the deciding winner part). 

This is more interesting as two players are involved independently and the program is an easy way for beginners to learn and get motivated.

Download project

Reviews Report

Submitted by Sanskriti Saraswat (sanskriti24)

Download packets of source code on Coders Packet