Tutorial: Tic Tac Toe

    Wow!, my very own first tutorial. *the author pats self on the back...erm maybe I should just skip the compliments and head straight to business...afterall, you did come here to learn about programming, right? Hmm...something in your reply doesn't sound quite too convincing. Well to put your mind at ease, I would like to say that I'm a total NEWBIE! Darn, I think I just lost half my audience by stating that...Oh well at least you stayed ^_^, thx mate.

    Well, since this is going to be perhaps your very first game, I would like to start off with the basics. Oh wait! I just remember how lazy a person I am, so I think I'll skip the introductions. Best of luck, mate! Just joking, but if you do find it hard to follow in my tutorials, I suggest you visit http://www.gametutorials.com and brush up on your basics. I'm going to assume that you at least know some basics like cin/cout and arrays, so without further ado's let's begin.

    In this game, I'm going to use 3 header files which are <iostream.h>, <stdlib.h>, and <windows.h>: stdlib.h is for the random function and windows.h is for time (or you can use time.h for time).

    Next, I want to display the tic tac toe board:

1

2

3

4

5

6

7

8

9

 

char board_info[9] = {'1','2','3',
                              '4','5','6',
                              '7','8','9'};

void draw_board()
{
     cout << endl;

     for (int i = 0; i < 9; i++)
     {
         cout << " | " << board_info[i];
         if ((i+1) % 3 == 0) cout << endl << " -------------" << endl; 
     }
}

   You can draw every single line manually if you wanted to, but I prefer the above method more.

void draw_board()
{
     cout << "-------------" << endl;
     cout <<"|" << board_info[0] << "|" << board_info[1] << "|" << board_info[2] << Endl;
     cout << "-------------" << endl;
     etc,etc...

}

    Now that Step 1 is finished, let's test to see if you're on the right track.

Here are the source codes:

Version 1

Version 2

    Now that we got our board, the next step it to re-initialize the board so that the numbers don't show up.

for (int i = 0; i < 9 ; i++)
{
    board_info[i] = ' ';
}
  • Set all the variables to ' BLANK '

    Now is the time to add some user controls. We will be using 'cin' for getting inputs from the player.

void player_movement()
{
    int choice;
    cout << "\nPlease select a number from 1 - 9: ";
    cin >> choice;

    //Error Checking

    if (cin.fail())
    {
        cout << "Error!";
        exit(1);
    }

    while (choice >= 10 || choice <=0)
    {
        cout << "\nPlease select again: ";
        cin >> choice;
    }

    while (board_info[(choice-1)] != ' ')
    {
        cout << "\nPlease select again: ";
        cin >> choice;
    };

    board_info[choice-1] = 'X';
}

 

 
  • Tell the user to select a number between 1 to 9

 

  • If the input was not a valid number, exit program

 

  • Testing the boundary for acceptable numbers
  •  If the number falls out of range, prompt for another number.

     

  • Test to see if the selection is not already occupied.

 

  • IF successful, update the array[] with 'X'

Please Note: an array always starts at index[0] NOT index[1] so we have to minus 1 from it since our input is 1-9 (not 0-8)

    BTW, you don't need all those error checks, but as a precaution I would recommend you use it.

Here is what you should have so far:

Source Code

    Next step is to add a computer player for an opponent. This might be the most challenging part of this whole game, but don't worry, I'm not here to fancy you with smart AI or anything. Instead, I will teach you a cheap method to simulate AI. I will just program every possible combinations there are and simpler have the computer counter the move with a predefined set of actions.

For example: if the 1st is 'X' and second is 'X' and the third must be 'Blank' so put the 'O' where there's a blank to block.

void computer_movement()
{
    if ((int(board_info[0]) + int(board_info[1]) + int(board_info[2])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[0] == ' ') board_info[0] = 'O';
        else if (board_info[1] == ' ') board_info[1] = 'O';
        else if (board_info[2] == ' ') board_info[2] = 'O'; 
    }

    else if ((int(board_info[3]) + int(board_info[4]) + int(board_info[5])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[3] == ' ') board_info[3] = 'O';
        else if (board_info[4] == ' ') board_info[4] = 'O';
        else if (board_info[5] == ' ') board_info[5] = 'O'; 
    }

    else if ((int(board_info[6]) + int(board_info[7]) + int(board_info[8])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[6] == ' ') board_info[6] = 'O';
        else if (board_info[7] == ' ') board_info[7] = 'O';
        else if (board_info[8] == ' ') board_info[8] = 'O'; 
    }

    else if ((int(board_info[0]) + int(board_info[3]) + int(board_info[6])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[0] == ' ') board_info[0] = 'O';
        else if (board_info[3] == ' ') board_info[3] = 'O';
        else if (board_info[6] == ' ') board_info[6] = 'O'; 
    }

    else if ((int(board_info[1]) + int(board_info[4]) + int(board_info[7])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[1] == ' ') board_info[1] = 'O';
        else if (board_info[4] == ' ') board_info[4] = 'O';
        else if (board_info[7] == ' ') board_info[7] = 'O'; 
    }

    else if ((int(board_info[2]) + int(board_info[5]) + int(board_info[8])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[2] == ' ') board_info[2] = 'O';
        else if (board_info[5] == ' ') board_info[5] = 'O';
        else if (board_info[8] == ' ') board_info[8] = 'O'; 
    } 

    else if ((int(board_info[0]) + int(board_info[4]) + int(board_info[8])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[0] == ' ') board_info[0] = 'O';
        else if (board_info[4] == ' ') board_info[4] = 'O';
        else if (board_info[8] == ' ') board_info[8] = 'O';
    }

    else if ((int(board_info[2]) + int(board_info[4]) + int(board_info[6])) == (2*int(char('X')))+int(char(' ')))
    {
        if (board_info[2] == ' ') board_info[2] = 'O';
        else if (board_info[4] == ' ') board_info[4] = 'O';
        else if (board_info[6] == ' ') board_info[6] = 'O'; 
    }
    else

    {
        int number = rand()%9; 
        while (board_info[number] != ' ') number = rand()%9;
        board_info[number] = 'O';
    }
}
  • If  (X+X+'BLANK') exist
  • we convert the above to integers so that it's easier to see if the first row has any of the following combinations.
  • If any of the combinations exist, then check which array has the blank and replace it with 'O'
  • If none of them exists, simpler randomize a location and put an 'O'

Have a look at this:

Source Code

    Checking for a winner. There are only 8 possible combinations for victory. 3 rows across, 3 columns down, or 2 diagonals. So testing for a winner is pretty simple enough, just run a scan for any of these combinations after a player has made its move and if a winner combo has been detected, it would return true.

bool check_for_winner(char player)
{
    if ((board_info[0] == player && board_info[1] == player) && (board_info[2] == player))
    return true;

    if ((board_info[3] == player && board_info[4] == player) && (board_info[5] == player))
    return true;

    if ((board_info[6] == player && board_info[7] == player) && (board_info[8] == player))
    return true;

    if ((board_info[0] == player && board_info[3] == player) && (board_info[6] == player)) 
    return true;

    if ((board_info[1] == player && board_info[4] == player) && (board_info[7] == player))
    return true;

    if ((board_info[2] == player && board_info[5] == player) && (board_info[8] == player))
    return true;

    if ((board_info[0] == player && board_info[4] == player) && (board_info[8] == player))
    return true;

    if ((board_info[2] == player && board_info[4] == player) && (board_info[6] == player))
    return true; 
    else return false;
}

    Next make a counter to test if the game has reached 9 moves, in which case you must declare a draw otherwise the game will halt. Well that just pretty much covers this lesson. Please download the finished version.