I am in a beginners programming course, and we have been doing C programs up until now, and the first C++ program we have confused me a bit. We have to make a simple tic tac toe program that plays against you [it doesn't have to be great at playing, it just has to work]. Since I have only done much simpler C++ programs before [simple math and printing to the screen is all I am familiar with] I have no idea how I would make it accept input properly form the user, nor keep up with what boxes of the play field are occupied with an X or an O. Below I've posted my teacher's example, and the only part I fully understand is the loop that sets the board to blank to start the game, and where the playing board is printed to the screen with the variables ready to be manipulated for game play. Any insight anyone could give on this would be very much appreciated! Here is the code.

#include <cstdlib>
#include <stdio.h>

class TicTac {
   char board[9];      //Tic Tac Toe board

   public:
   TicTac();            //Constructor
   void draw_board();   //draw the current board on the screen
};

//Constructor
TicTac::TicTac(){
  for(int i=0; i<9; i++) //initialize board to blank
    board[i]=' ';
}

void TicTac::draw_board(){
     
   system("cls");
   printf("_____________\n");
   printf("| %c | %c | %c |\n", board[6], board[7], board[8]);
   printf("_____________\n");
   printf("| %c | %c | %c |\n", board[3], board[4], board[5]);
   printf("_____________\n");
   printf("| %c | %c | %c |\n", board[0], board[1], board[2]);
   printf("_____________\n");
}

main(){
             
       TicTac my_game;       
       my_game.draw_board();
       system("pause");      
    
}
VernonDozier commented: Code tags on first post! :) +12

Recommended Answers

All 10 Replies

Lots of good Tic Tac Toe threads on Daniweb. There are a variety of ways to approach it. Break it up into smaller, more manageable tasks. For instance, I would start with a function that accepts input from the human player. You should probably make it a member function of the TicTac class.

void TicTac::GetHumanMove ()
// assume human is player x
{
    int row, col;
    std::cout << "Enter row : ";
    std::cin  >> row;
    std::cout << "Enter column : ";
    std::cin >> col;

    // change board[] array based on row and col
}

In main, to call it and test it, you could add these lines:

int main(){
             
       TicTac my_game;       
       my_game.draw_board();
       cin.get (); // instead of system ("PAUSE")
       my_game.GetHumanMove ();
       my_game.draw_board();
       cin.get (); // instead of system ("PAUSE")
       cin.get (); // instead of system ("PAUSE")

       return 0; 
}

Check out this thread for why to avoid system ("PAUSE"). http://www.gidnetwork.com/b-61.html

You'll need to #include <iostream> for cin and cout .

Hope this gives you a start.

commented: Nice link on why to avoid system("pause"); +1
commented: Good solid approach +29

Below I've posted my teacher's example,

There's a lot of C code in that example, including the headers.
If you're doing a C++ course then you'll need to use C++ syntax, mixing C and C++ is a no-no and something to be avoided.

This will show you how to do some basic interaction with the user ...
And this information about C++ classes might also be helpful ...

Hope this helps !

Thanks for the help so far! I was able to get much further with that. But now I have run into another problem. Now I can't exactly figure out how to loop my program and make it not forget the things that are already on the playing board. I'm also not certain I am making it check for blank spaces correctly in my attempted while loop. In Dev C++, I get the compile errors:"'char TicTac::board[9]' is private" and "invalid use of non static data member 'TicTac::board'. Im not really sure where to go from this point. Again, any help will be very much appreciated!

#include<iostream>
using std::cout;
using std::cin;

 char player[1];
 char i[1];

class TicTac {
   char board[9]; 

   public:
   TicTac();            //Constructor
   void draw_board();
   void getmove();
};

//Constructor
TicTac::TicTac(){
  for(int i=0; i<9; i++) //initialize board to blank
    board[i]=' ';
}

void TicTac::getmove ()
// assume human is player x
{
    int row, col;
    std::cout << "Enter row : ";
    std::cin  >> row;
    std::cout << "Enter column : ";
    std::cin >> col;

    //here is a list of if statements for all the 
    //possible squares of the playing field a player may choose.
    
    if (row==1 && col ==1){ 
    board[0]= *player;}
    
    if (row==1 && col ==2){
    board[1]= *player;}
    
    if (row==1 && col ==3){
    board[2]= *player;}
    
    if (row==2 && col ==1){
    board[3]= *player;}
    
    if (row==2 && col ==2){
    board[4]= *player;}
    
    if (row==2 && col ==3){
    board[5]= *player;}
    
    if (row==3 && col ==1){
    board[6]= *player;}
    
    if (row==3 && col ==2){
    board[7]= *player;}
    
    if (row==3 && col ==3){
    board[8]= *player;}
}

void TicTac::draw_board()
{
     
   system("cls");
   cout << ("_____________\n");
   cout << "| %c | %c | %c |\n", board[0], board[1], board[2];
   cout << "_____________\n";
   cout << "| %c | %c | %c |\n", board[3], board[4], board[5];
   cout << "_____________\n";
   cout << "| %c | %c | %c |\n", board[6], board[7], board[8];
   cout << "_____________\n";
}

main()
{          
       cout << "\nWelcome to Tic Tac Toe.\n";
       cout << "\nThe computer player will be represented by a C.\n";
       cout << "\nWhat character would you like to represent you? (Enter any letter.) ";
       cin >> player;
       
       while(TicTac::board[i] == ' ')
       {
       TicTac my_game;       
       my_game.draw_board();
       system("pause");
       my_game.getmove ();
       my_game.draw_board();
       system ("PAUSE");
       }
       return 0;    
}

I changed the code slightly.

This won't work from main:

TicTac::board[i]

Note the other call from main:

my_game.draw_board();

This is correct. You type the name of the object (my_game), then a dot, then the function or data member (if it is public. You can't do it from main if it's private).

The slightly revised code is below:

#include<iostream>
using std::cout;
using std::cin;

 char player[1];
 char i[1];

class TicTac {
   private:
   char board[9]; 
   
   public:         
   TicTac();            //Constructor
   void draw_board();
   void getmove();
   bool GameOver ();
};

//Constructor
TicTac::TicTac(){
  for(int i=0; i<9; i++) //initialize board to blank
    board[i]=' ';
}

void TicTac::getmove ()
// assume human is player x
{
    int row, col;
    std::cout << "Enter row : ";
    std::cin  >> row;
    std::cout << "Enter column : ";
    std::cin >> col;

    //here is a list of if statements for all the 
    //possible squares of the playing field a player may choose.
    
    if (row==1 && col ==1){ 
    board[0]= *player;}
    
    if (row==1 && col ==2){
    board[1]= *player;}
    
    if (row==1 && col ==3){
    board[2]= *player;}
    
    if (row==2 && col ==1){
    board[3]= *player;}
    
    if (row==2 && col ==2){
    board[4]= *player;}
    
    if (row==2 && col ==3){
    board[5]= *player;}
    
    if (row==3 && col ==1){
    board[6]= *player;}
    
    if (row==3 && col ==2){
    board[7]= *player;}
    
    if (row==3 && col ==3){
    board[8]= *player;}
}

void TicTac::draw_board()
{
     
//   system("cls");
/*   cout << ("_____________\n");
   cout << "| %c | %c | %c |\n", board[0], board[1], board[2];
   cout << "_____________\n";
   cout << "| %c | %c | %c |\n", board[3], board[4], board[5];
   cout << "_____________\n";
   cout << "| %c | %c | %c |\n", board[6], board[7], board[8];
   cout << "_____________\n";*/
   
   cout << "|" << board[0] << "|" << board[1] << "|" << board[2] << "|\n";
}

bool TicTac::GameOver ()
{
    // returns false for now, but add code to check whether game is over.
    return false;
}



int main()
{          
       cout << "\nWelcome to Tic Tac Toe.\n";
       cout << "\nThe computer player will be represented by a C.\n";
       cout << "\nWhat character would you like to represent you? (Enter any letter.) ";
       cin >> player;


       TicTac my_game;
       
       while(!my_game.GameOver ())
       {
           my_game.draw_board();
           system("pause");
           my_game.getmove ();
           my_game.draw_board();
           system ("PAUSE");
       }
       return 0;    
}

Lines 5 and 6 - What are you declaring one element arrays instead of simple char variables?

Line 9 - made board private since you said you wanted it private. Private is default, but it never hurts to type in private explicitly.

Line 68 - I commented this line out. You can put it back in later, but for debugging purposes, it's useful to see exactly what is happening. Clearing the screen can make you miss things. Comment it out when debugging. Put it back in when it's working.

Lines 69 - 75 - it looks like you are trying to use cout the way you use printf. You can use either, but don't try to mix them.

Line 77 - One way you can use cout. Only prints the top line. Add two more lines of code to print the rest.

Line 96 - made object declaration BEFORE the loop.
Line 98 - Took out the TicTac::board line and replaced it with a new function. Right now the function is trivial. You'll need to add to it.

Actually you can replace lines 37 - 63 with: board[((row-1)*3)+(col-1)] = *player; ...
Or with board[((row-1)*3)+(col-1)] = player; if you're using a simple char-variable ...

Thanks a lot for that suggestion there, it condensed the code and made it much more manageable! All though if I could trouble you to explain exactly how that works and is able to be the equivalent of several if statements, I would be very appreciative and probably a much better programmer. :)

Thanks a lot for that suggestion there, it condensed the code and made it much more manageable! All though if I could trouble you to explain exactly how that works and is able to be the equivalent of several if statements, I would be very appreciative and probably a much better programmer. :)

It's just a formula I found by making a graphical presentation of the array which represents the board, and after searching a little time I came up with this ...

You can try it out and you'll see it actually works ! :)

Thanks a lot for that suggestion there, it condensed the code and made it much more manageable! All though if I could trouble you to explain exactly how that works and is able to be the equivalent of several if statements, I would be very appreciative and probably a much better programmer. :)

OK, I'm trying to explain this to you:

We start looking at the graphical representation of the instruction 'char board[9];'

 0  1  2     3  4  5     6  7  8
[ ][ ][ ] | [ ][ ][ ] | [ ][ ][ ]

(in total we've 9 elements in the array (element 0-8))

 0           3           6
[ ][ ][ ] | [ ][ ][ ] | [ ][ ][ ]

 |           |           |
row 1       row 2       row 3
starts      starts      starts
here        here        here


If we know the row where we want to write in, we first have to calculate the actual place
of the row in the array before we start writing ...

So, after a bit trying you can find the place where the row starts (in the array)
by using the following formula:

row_place_in_array = (row-1)*3 ;
                             |
                  in each row there are
                     three columns

Now we only need to find a formula which is indicating the place in the array if we know
the row and the column ...

We already know the formula to find the row in the array, so if we start from here and
if we adjust it a little bit, we can transform this in the final formula:

place_in_array = ((row-1)*3)+(col-1) ;

If you use the graphical representation you can quickly understand the formula ...

Still I want to explain where the '(col-1)'-part came from:

-> If we use the formula to find the place where each row starts in the array,
   we automatically know the place of the first column, that's the explanation for where
   the '-1' in '(col-1)' came from ...

I hope I explained everything in a way you can understand it ...

P.S: Sorry if my English is bad, my native language is Dutch ...

Thank you for the explanation! I do understand how that works now, and I appreciate your help very much! Now, just one more thing and this thread shall be solved. I'm not sure how to make my program recognize a tie. Everything else works so far. Anyone that has any suggestions for this would be very helpful, and very appreciated!

#include<iostream>

using std::cout;
using std::cin;

 char player;
 char i[1];
 char computer;
 int tie;

class TicTac {
   private:
   char board[9]; 
   
   public:         
   TicTac();            //Constructor
   void draw_board();
   void getmove();
   bool GameOver();
   void computermove();
   void emptyspace();
};

//Constructor
TicTac::TicTac(){
              
  for(int i=0; i<9; i++) //initialize board to blank
    board[i]=' ';
    
}

void TicTac::getmove ()
{
    userin:
           
    int row, col;
    std::cout << "Enter row : ";
    std::cin  >> row;
    std::cout << "Enter column : ";
    std::cin >> col;

    //here is a list of if statements for all the 
    //possible squares of the playing field a player may choose.
    if(board[((row-1)*3)+(col-1)]==' ')
    {
    board[((row-1)*3)+(col-1)] = player;
    }
    else
    {
        cout << "Invalid move. Please try again.\n\n";
        goto userin;
        }
}

void TicTac::computermove()
{
     srand((unsigned)time(0)); 
     
     comp:
     
     int row = (rand()%3) +1; 
     int col = (rand()%3) +1;
     
     if(board[((row-1)*3)+(col-1)] == ' ') 
     {
     board[((row-1)*3)+(col-1)] = computer;
     }
     else
     {
         goto comp;
     }
}

void TicTac::draw_board()
{
   system("cls");
   cout << "\n      -=Tic Tac Toe=-\n\n";
   
   cout << "         Columns:\n";
   cout << "         1   2   3\n";
   cout << "       -------------\n";
   cout << "Row 1: | " << board[0] << " | " << board[1] << " | " << board[2] << " |\n";
   cout << "       -------------\n";
   cout << "Row 2: | " << board[3] << " | " << board[4] << " | " << board[5] << " |\n";
   cout << "       -------------\n";
   cout << "Row 3: | " << board[6] << " | " << board[7] << " | " << board[8] << " |\n";
   cout << "       -------------\n\n"; 
}

bool TicTac::GameOver ()
{    
    //PLAYER GETS VICTORY BY Vertical
    if(board[0]==player&&board[3]==player&&board[6]==player || 
      board[1]==player&&board[4]==player&&board[7]==player || 
        board[2]==player&&board[5]==player&&board[8]==player) {
        TicTac::draw_board();
        printf("You win!\n\n");
        system("pause");
        return true;           //FUNCTION SHOULD RETURN TRUE TO EXIT GAME LOOP
        }
    //Victory by horizontal
    if(board[0]==player&&board[1]==player&&board[2]==player || 
      board[3]==player&&board[4]==player&&board[5]==player || 
        board[6]==player&&board[7]==player&&board[8]==player) {
        TicTac::draw_board();
        printf("You win!\n\n");
        system("pause");
        return true;
        }
    //Victory By criss or cross
    if(board[0]==player&&board[4]==player&&board[8]==player || 
      board[6]==player&&board[4]==player&&board[2]==player) {
        TicTac::draw_board();
        printf("You win!\n\n");
        system("pause");
        return true;
        }
    
    //COMPUTER GETS VICTORY BY HORIZONTAL
     if(board[0]==computer&&board[1]==computer&&board[2]==computer || 
      board[3]==computer&&board[4]==computer&&board[5]==computer || 
        board[6]==computer&&board[7]==computer&&board[8]==computer){
        TicTac::draw_board();
        printf("Computer Wins!\n\n");
        system("Pause");
        return true;
        }
    //Computer victory by vertical
    if(board[0]==computer&&board[3]==computer&&board[6]==computer || 
      board[1]==computer&&board[4]==computer&&board[7]==computer || 
        board[2]==computer&&board[5]==computer&&board[8]==computer){
        TicTac::draw_board();
        printf("Computer Wins!\n\n");
        system("Pause");
        return true;
        }
    //computer victory by criss cross   
    if(board[0]==computer&&board[4]==computer&&board[8]==computer || 
      board[6]==computer&&board[4]==computer&&board[2]==computer){
        TicTac::draw_board();
        printf("Computer Wins!\n\n");
        system("Pause");
        return true;
        }
        
    return false;
    
}

int main()
{          
       cout << "\nWelcome to Tic Tac Toe.\n";
       cout << "\nWhat character would you like to represent you? (Enter any letter.) ";
       cin >> player;
       cout << "\nWhat character would you like to represent your computer opponent? ";
       cin >> computer;

       TicTac my_game;
       
       srand((unsigned)time(0));
       int playerorder = (rand()%2) +1; 
       
       while(!my_game.GameOver ())
       {
          if(playerorder == 1)
          {
           my_game.draw_board();
           system("pause");
           my_game.getmove ();
           my_game.draw_board();
           my_game.computermove();
           
           }
           
           if(playerorder == 2)
           {
           my_game.draw_board();
           system("pause");
           my_game.computermove();
           my_game.draw_board();
           my_game.getmove ();
           
           }              
       }
       return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.