Implementation of Tic-Tac-Toe game - GeeksforGeeks

08 Feb, 2018
Rules of the Game
The game is to be played between two people (in this program between HUMAN and COMPUTER).
One of the player chooses ‘O’ and the other ‘X’ to mark their respective cells.
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 no one wins, then the game is said to be draw.ImplementationIn our program the moves taken by the computer and the human are chosen randomly. We use rand() function for this.What more can be done in the program?The program is in not played optimally by both sides because the moves are chosen randomly. The program can be easily modified so that both players play optimally (which will fall under the category of Artificial Intelligence). Also the program can be modified such that the user himself gives the input (using scanf() or cin).The above changes are left as an exercise to the readers.Winning Strategy – An Interesting FactIf 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 ways – “ Two expert players will always draw ”.Isn’t this interesting ?Recommended: Please try your approach on {IDE} first, before moving on to the solution.// 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 statusvoid 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 instructionsvoid 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 gamevoid 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 movebool 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 movebool 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 movebool 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 falsebool gameOver(char board[][SIDE]){    return(rowCrossed(board) || columnCrossed(board)            || diagonalCrossed(board) );}  // A function to play Tic-Tac-Toevoid 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 programint main(){    // Let us play the game with COMPUTER starting first    playTicTacToe(COMPUTER);          return (0);}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
An Interesting Variant of this gameAs said above, if two experienced players are playing the Tic-Tac-Toe, then the game will always draw.There is another viral variant of this game- Ultimate Tic-Tac-Toe, which aims to make the normal Tic-Tac-Toe more interesting and less predictable.Have a look at the game here- Link1 Link2The above article implements simple Tic-Tac-Toe where moves are randomly made. Please refer below article to see how optimal moves are made.Minimax Algorithm in Game Theory | Set 3 (Tic-Tac-Toe AI – Finding optimal move)Great discussions on the “winning/never losing” strategyQuoraWikihowThis article is contributed by Rachit Belwariar .If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.My Personal Notes
arrow_drop_upSave
What more can be done in the program?The program is in not played optimally by both sides because the moves are chosen randomly. The program can be easily modified so that both players play optimally (which will fall under the category of Artificial Intelligence). Also the program can be modified such that the user himself gives the input (using scanf() or cin).The above changes are left as an exercise to the readers.
Winning Strategy – An Interesting FactIf 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 ways – “ Two expert players will always draw ”.Isn’t this interesting ?
// 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 statusvoid 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 instructionsvoid 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 gamevoid 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 movebool 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 movebool 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 movebool 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 falsebool gameOver(char board[][SIDE]){    return(rowCrossed(board) || columnCrossed(board)            || diagonalCrossed(board) );}  // A function to play Tic-Tac-Toevoid 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 programint main(){    // Let us play the game with COMPUTER starting first    playTicTacToe(COMPUTER);          return (0);}
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

An Interesting Variant of this gameAs said above, if two experienced players are playing the Tic-Tac-Toe, then the game will always draw.There is another viral variant of this game- Ultimate Tic-Tac-Toe, which aims to make the normal Tic-Tac-Toe more interesting and less predictable.Have a look at the game here- Link1 Link2
The above article implements simple Tic-Tac-Toe where moves are randomly made. Please refer below article to see how optimal moves are made.Minimax Algorithm in Game Theory | Set 3 (Tic-Tac-Toe AI – Finding optimal move)
Great discussions on the “winning/never losing” strategyQuoraWikihow
This article is contributed by Rachit Belwariar .If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Game Theory
Game Theory
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Classification of Algorithms with Examples
A Binary String Game
Random Number Memory Game in C
Find the player who will win by choosing a number in range [1, K] with sum total N
Game Theory (Normal-form Game) | Set 7 (Graphical Method [M X 2] Game)
Two player game in which a player can remove all occurrences of a number
Find the winner of the Game to Win by erasing any two consecutive similar alphabets
Find the player who will win the Coin game
Maximum and minimum isolated vertices in a graph
Make a palindromic string from given string