# how can I make a tic tac toe program? From this specification

Tic Tac Toe (also known as "Naughts and Crosses" and "Three-In-A-Row") is a simple game played on a 3 x 3 grid (i.e. 9 squares), where 2 players take turns at adding their pieces (a naught or a cross) until either :
? One of the players gets three of their pieces in a straight line (in any row, column, or diagonal). The player who does this first is the winner.
? Or, there are no more free squares to move into, in which case the game is a draw.
Your task for this assignment is to write a program in C++ that enables you (or another user of your program) to play Tic Tac Toe against a computer opponent.
The rules for the game are as follows :
1. The human player will always be Naughts (0?s).
2. The computer player will always be Crosses (X?s).
3. The human player (i.e. the program?s user) will initially go first.
4. In all subsequent games, the player who won the last game will go first. If the game was a draw, then the last player who won a game will go first.
An example of the game in action is as follows :
For your next move: Enter the Row (1-3) : 1
Enter the Column (1-3) : 2
Computer Grabs the Next Empty Square !
(Row = 1, Col = 3)
------+-----+------
| X | O | X |
------+-----+------
| O | X | |
------+-----+------
| O | X | O |
------+-----+------
Computer = X Human = O
Your Tic Tac Toe program should contain the following functions :
1. Initialise_Game : a function to initialise / start the game, so that the game 3 x 3 grid is empty (i.e. contains no player or computer pieces), and a new game is ready to start.
2. Draw_Game_Board : a function to draw the game 3 x 3 grid, with the human and computer players? pieces in the grid.
3. Get_Humans_Move : a function to prompt for, validate, and process a turn or move for the human player. You can do this a number of ways. For example, one way is to prompt the user for a row and column for their move. This function should then check that the selected square is valid and free, and if it isn?t then it should display appropriate error messages and re-prompt for the move. When a valid move has been made, then this function should insert the human player?s piece where required in the grid.
4. Get_Computers_Move : a function to determine a reasonable move for the computer player, as follows :
a. See if middle square is empty / free - the best thing to do is grab the center square, if it is available.
b. Otherwise, use next available empty square. If the computer player still hasn't moved (i.e. it hasn't taken the center square) then all it can do is grab the next available empty square.
5. Check_Game_Status : a function to determine if we have a winner yet (either the human or computer player has 3 in a line), or whether the game is a draw (no more empty squares, and no player has 3 in a line).
In addition, you should develop a main program to call each of the above functions (and any other functions you develop) as required. To given you an idea of some of the basic processing your main program will need to perform, the following pseudo-code has been provided, but please note that this does not take into account all of the processing that is required :
Initialise_Game
while (game != over)
{
Draw_Game_Board
Get_Humans_Move
Check_Game_Status
Get_Computers_Move
Check_Game_Status
}
At the end of any game, your program should increment and display the number of wins, losses, and draws for the human player, depending on who won, or whether the game was a draw.
All of this code should be brought together within a DOS standard or EasyWin EXEcutable Project.
Development Hints and Tips : The Smoothest Path to Success !!
1. Check your notes and text for code and examples that may be useful to you in doing this assignment.
2. Writing dozens or hundreds of lines of code, without careful and thorough testing at each step of the way, will likely leave you with a mess of code that will take a great deal of effort to get working or with code that you cannot get to work at all. Developing code in this way is a very bad practice. Expecting a lecturer or tutor or somebody else to fix such carelessly and recklessly written code is not fair on them or you. Do not do this !!
3. The smoothest path to success is to start of very simply, build functionality into your program piece by piece, and then test it thoroughly before attempting to add further functionality.
4. Before you start, stop and think about things :
a. How you are going to store the game board ? A 1 D array is OK, or you can use a 2 D array.
b. How are you going to determine whether a square is free, or human player occupied, or computer player occupied ? i.e. what will you store in your array to indicate this ?
c. etc.
5. The two functions you should start off with are also the most simple : Initialise_Game and Draw_Game_Board. When you have written these, you can call these functions and run your program and you can ensure that the very basics are working before you proceed further. Don?t worry too much about making your output attractive at this stage ? this is something you should do right at the end (if you have time).
6. The next easiest function to develop is : Get_Humans_Move. When you have written this function, you can run your program and have a simple one-sided game to check that your Draw_Game_Board is working properly and showing pieces where the player has moved them, and that the Get_Humans_Move function is working properly and doesn?t allow you to move into invalid squares or squares that are already occupied.
7. The next easiest function to develop is : Check_Game_Status. In this function, you need to determine if there is a winner or if the game is a draw :
a. To determine if there is a winner, you need to check all rows, columns, and diagonals, to see if any player (human or computer) has 3 pieces in a line. This isn?t particularly difficult to achieve, but you will find that your code can become complex quite quickly, so look for common functionality, and start off as simple as possible ! To start of with, just try and see if the human player has 3 pieces in a line in the first row. Then, test your program, and put 3 human player pieces into the top row and ensure that this function determines a win. Then, expand this code to work with all rows, and test this works. Then, write further code to determine if the human player has 3 pieces in a line in the first column, and test this works. Then extend this to all columns, and test this works. Next, add in diagonal checking, and test this. Finally, make the above code generic so you can use it for human and computer pieces, and test this works.
b. If there is no winner, then the function needs to determine if there is a draw. To do this, you should count the number of empty squares in your game?s 3 x 3 grid. If no squares are free, then (because we didn?t find a winner above) we have a draw.
8. A hard function to develop is : Get_Computers_Move. This function will require careful development and testing at each step of the way to ensure that each bit works before moving onto the next. To start with, this function may simply grab the first empty square that it finds in the game grid. You can then add the more advanced movement strategies in piece by piece as you go. Test things out at each stage before you proceed !!
9. As you develop the above functions, you should always keep an eye out for common functionality that can be used by other functions. This common functionality should be moved into its own function to enable other parts of your program to use it as required.
11. Make sure your program exhibits the Quality Program Features. Always comment your code - especially during development - so you will know what you have done and why. The use of Global Constants are highly recommended. Also, the use of Enumerated Types (enums) and Typedefs are also highly recommended, and you should use these wherever appropriate.
###### Who is Participating?

x

Commented:
Much simplified version:

#include <math.h>
#include <ctype.h>
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>

int random(int m)
{
return rand() % m;
}

void clrscr(void)
{
}

void gotoxy(int x, int y)
{
}

// function prototypes
void draw();
void userchoice();
void compchoice();
int win();

// global variables
char ttt[6][6] = {    // matrix to store tic-tac-toe board
{'|', '-', '+', '-', '+', '-'},
{'|', '1', '|', '2', '|', '3'},
{'|', '-' ,'+', '-', '+', '-'},
{'|', '4', '|', '5', '|', '6'},
{'|', '-' ,'+', '-', '+', '-'},
{'|', '7', '|', '8', '|', '9'}
};

// main function
int main()
{
int done = 0;

// draw the initial tic-tac-toe board
draw();

// loop until a winner is found
do
{
if (done == 0)      // if no winner
{
userchoice();   // get players move
done = win();   // check to see if winner
}

if(done == 0)      // if no winner
{
compchoice();   // generate computers move
done = win();   // check to see if winner
}

if (done == 'X')
{
cout << "You have won!!!\n\n\n";
}
else if ( done=='O' )
{
cout << "The computer has beaten you...\nYOU MORON!!!!!!\n\n\n";
}
else if ( done==2 )
{
cout << "The game is a draw, there is no winner.\n\n\n";
}
}
while(done == 0);

return 1;
}

// function to draw the starting tic-tac-toe screen
void draw()
{
clrscr();

for (int r = 0; r <= 5; r++)
{
for(int c = 0; c <= 5; c++)
{
cout << ttt[r][c];
}
cout << endl;
}

cout<<"\n"<<"\t"<<"Computer = 0"<<"\t"<<"Human = X"<<endl;
}

// function to get the users choice
void userchoice()
{
while ( true )
{
int choice;
gotoxy(1, 10);

cout << "\n\n\nPlease enter the number of the square\n"
<< "that you wish to put an X in: ";
cin >> choice;  // get users choice

// process users choice
if ( (choice>=1) && (choice<=9) )
{
int x = (choice-1) / 3 * 2 + 1;  // 1 3 5
int y = (choice-1) % 3 * 2 + 1;  // 1 3 5

if ((ttt[x][y] != 'X') && (ttt[x][y] != 'O'))  // if move valid
{
ttt[x][y] = 'X';
draw();
return;
}
}

char temp;
cout << "Enter a key, followed by\n<Enter>, to continue...\n";
cin >> temp;
clrscr();
draw();
}
}

bool Move(char & c1, char & c2, char & c3)
{
if ( (c1==c2) && isdigit(c3) )
{
c3 = 'O';

draw(); return true;
}

if ( (c1==c3) && isdigit(c2) )
{
c2 = 'O';

draw(); return true;
}

if ( isdigit(c1) && (c2==c3) )
{
c1 = 'O';

draw(); return true;
}

return false;
}

void compchoice()
{
for (int i=1; i<=5; i+=2)
{
if ( Move(ttt[i][1], ttt[i][3], ttt[i][5]) )
return;

if ( Move(ttt[1][i], ttt[3][i], ttt[5][i]) )
return;
}

if ( Move(ttt[1][1], ttt[3][3], ttt[5][5]) )
return;

if ( Move(ttt[1][5], ttt[3][3], ttt[5][1]) )
return;

// if no 2 in a row availiable, make a random move
while ( true )
{
int x = random(3) * 2 + 1;
int y = random(3) * 2 + 1;

if ( isdigit(ttt[x][y]) )
{
ttt[x][y] = 'O';
draw();
break;
}
}
}

// function to check to see if there is a winner;
int win()
{
for (int i=1; i<=5; i+=2)
{
// see if there are 3 Xs or 3 Os in a row
if ( (ttt[i][1] == ttt[i][3]) && (ttt[i][3] == ttt[i][5]) )
return ttt[i][1];

if ( (ttt[1][i] == ttt[3][i]) && (ttt[3][i] == ttt[5][i]) )
return ttt[1][i];
}

if ( (ttt[1][1] == ttt[3][3]) && (ttt[3][3] == ttt[5][5]) )
return ttt[1][1];

if ( (ttt[1][5] == ttt[3][3]) && (ttt[3][3] == ttt[5][1] ) )
return ttt[1][5];

for (int x=1; x<=5; x+=2)
for (int y=1; y<=5; y+=2)
if ( isdigit(ttt[x][y]) )
return 0;

return 2;
}

0

Author Commented:
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>

// function prototypes
void draw();
void userchoice();
void compchoice();
int win();

// global variables
int done = 0;
char ttt[6][6] = {    // matrix to store tic-tac-toe board
{'|', '- ', '+ ', '-', '+', '-'},
{'|', '1', '|', '2', '|', '3'},
{'|', '-' ,'+', '-', '+', '-'},
{'|', '4', '|', '5', '|', '6'},
{'|', '-' ,'+', '-', '+', '-'},
{'|', '7', '|', '8', '|', '9'}
};

// main function
int main()
{
char temp;

// draw the initial tic-tac-toe board
draw();

// loop until a winner is found
do
{
if(done == 0)      // if no winner
{
userchoice();   // get players move
done = win();   // check to see if winner
}

if(done == 0)      // if no winner
{
compchoice();   // generate computers move
done = win();   // check to see if winner
}
else               // if winner found
{
if(done == 1)
{cout << "You have won!!!\n\n\n";}
else
{cout << "The game is a draw, there is no winner.\n\n\n"; done++;}
}

if(done == 1)
{cout << "The computer has beaten you...\nYOU MORON!!!!!!\n\n\n";}
if(done == 2)
{cout << "The game is a draw, there is no winner.\n\n\n";}
} while(done == 0);

// end the program
cout << "Enter a key, followed by\n<Enter>, to quit...\n";
cin >> temp;
return 0;
}

// function to draw the starting tic-tac-toe screen
void draw()
{

int r, c;
clrscr();
for(r = 0; r <= 5; r++)
{
for(c = 0; c <= 5; c++)
{cout << ttt[r][c];}
cout << endl;
}
cout<<"\n"<<"\t"<<"Computer = 0"<<"\t"<<"Human = X"<<endl;
}

// function to get the users choice
void userchoice()
{
int choice, error;
char temp;
do
{
choice = 1;
error = 0;
gotoxy(1, 10);
cout << "\n\n\nPlease enter the number of the square\n"
<< "that you wish to put an X in: ";
cin >> choice;  // get users choice

// process users choice
switch (choice)
{
case 1:
if((ttt[1][1] == 'X') || (ttt[1][1] == 'O'))  // if move invalid
{error++;}
else                   // if move valid
{ttt[1][1] = 'X';}
break;
case 2:
if((ttt[1][3] == 'X') || (ttt[1][3] == 'O'))
{error++;}
else
{ttt[1][3] = 'X';}
break;
case 3:
if((ttt[1][5] == 'X') || (ttt[1][5] == 'O'))
{error++;}
else
{ttt[1][5] = 'X';}
break;
case 4:
if((ttt[3][1] == 'X') || (ttt[3][1] == 'O'))
{error++;}
else
{ttt[3][1] = 'X';}
break;
case 5:
if((ttt[3][3] == 'X') || (ttt[3][3] == 'O'))
{error++;}
else
{ttt[3][3] = 'X';}
break;
case 6:
if((ttt[3][5] == 'X') || (ttt[3][5] == 'O'))
{error++;}
else
{ttt[3][5] = 'X';}
break;
case 7:
if((ttt[5][1] == 'X') || (ttt[5][1] == 'O'))
{error++;}
else
{ttt[5][1] = 'X';}
break;
case 8:
if((ttt[5][3] == 'X') || (ttt[5][3] == 'O'))
{error++;}
else
{ttt[5][3] = 'X';}
break;
case 9:
if((ttt[5][5] == 'X') || (ttt[5][5] == 'O'))
{error++;}
else
{ttt[5][5] = 'X';}
break;
default:
error++;
break;
}
if(error != 0)  // if invalid move entered
{
cout << "Enter a key, followed by\n<Enter>, to continue...\n";
cin >> temp;
clrscr();
draw();
}
} while(error != 0);

draw();
error = 0;
}

void compchoice()
{
int move = 0, x;

// if 2 Xs in a row, block 3 in a row or
// if 2 Os in a row, place 3rd and win if able
if ((ttt[1][1] == ttt[1][3]) &&
(move == 0) && (ttt[1][5] == '3'))
{ttt[1][5] = 'O';
move++;
}
if ((ttt[1][1] == ttt[1][5]) &&
(move == 0) && (ttt[1][3] == '2'))
{ttt[1][3] = 'O';
move++;
}
if ((ttt[1][5] == ttt[1][3]) &&
(move == 0) && (ttt[1][1] == '1'))
{ttt[1][1] = 'O';
move++;}

if ((ttt[3][1] ==ttt[3][3]) &&
(move == 0) && (ttt[3][5] == '6'))
{ttt[3][5] = 'O';
move++;}
if ((ttt[3][1] == ttt[3][5]) &&
(move == 0) && (ttt[3][3] == '5'))
{ttt[3][3] = 'O';
move++;}
if ((ttt[3][3] == ttt[3][5]) &&
(move == 0) && (ttt[3][1] == '4'))
{ttt[3][1] = 'O';
move++;}

if ((ttt[5][1] == ttt[5][3]) &&
(move == 0) && (ttt[5][5] == '9'))
{ttt[5][5] = 'O';
move++;}
if ((ttt[5][1] == ttt[5][5]) &&
(move == 0) && (ttt[5][3] == '8'))
{ttt[5][3] = 'O';
move++;}
if ((ttt[5][3] == ttt[5][5]) &&
(move == 0) && (ttt[5][1] == '7'))
{ttt[5][1] = 'O';
move++;}

if ((ttt[1][1] == ttt[3][1]) &&
(move == 0) && (ttt[5][1] == '7'))
{ttt[5][1] = 'O';
move++;}
if ((ttt[1][1] == ttt[5][1]) &&
(move == 0) && (ttt[3][1] == '4'))
{ttt[3][1] = 'O';
move++;}
if ((ttt[5][1] == ttt[3][1]) &&
(move == 0) && (ttt[1][1] == '1'))
{ttt[1][1] = 'O';
move++;}

if ((ttt[1][3] == ttt[3][3]) &&
(move == 0) && (ttt[5][3] == '8'))
{ttt[5][3] = 'O';
move++;}
if ((ttt[1][3] == ttt[5][3]) &&
(move == 0) && (ttt[3][3] == '5'))
{ttt[3][3] = 'O';
move++;}
if ((ttt[5][3] == ttt[3][3]) &&
(move == 0) && (ttt[1][3] == '2'))
{ttt[1][3] = 'O';
move++;}

if ((ttt[1][5] == ttt[3][5]) &&
(move == 0) && (ttt[5][5] == '9'))
{ttt[5][5] = 'O';
move++;}
if ((ttt[1][5] == ttt[5][5]) &&
(move == 0) && (ttt[3][5] == '6'))
{ttt[3][5] = 'O';
move++;}
if ((ttt[5][5] == ttt[3][5]) &&
(move == 0) && (ttt[1][5] == '3'))
{ttt[1][5] = 'O';
move++;}

if ((ttt[1][1] == ttt[5][5]) &&
(move == 0) && (ttt[3][3] == '5'))
{ttt[3][3] = 'O';
move++;}
if ((ttt[1][1] == ttt[3][3]) &&
(move == 0) && (ttt[5][5] == '9'))
{ttt[5][5] = 'O';
move++;}
if ((ttt[3][3] == ttt[5][5]) &&
(move == 0) && (ttt[1][1] == '1'))
{ttt[1][1] = 'O';
move++;}

if ((ttt[1][5] == ttt[3][3]) &&
(move == 0) && (ttt[5][1] == '7'))
{ttt[5][1] = 'O';
move++;}
if ((ttt[1][5] == ttt[5][1]) &&
(move == 0) && (ttt[3][3] == '5'))
{ttt[3][3] = 'O';
move++;}
if ((ttt[3][3] == ttt[5][1]) &&
(move == 0) && (ttt[1][5] == '3'))
{ttt[1][5] = 'O';
move++;}

// if no 2 in a row availiable, make a random move
while (move == 0)
{
x = random(9);
x++;
switch (x)
{
case 1:
if(ttt[1][1] == '1')
{ttt[1][1] = 'O'; move++;}
break;
case 2:
if(ttt[1][3] == '2')
{ttt[1][3] = 'O'; move++;}
break;
case 3:
if(ttt[1][5] == '3')
{ttt[1][5] = 'O'; move++;}
break;
case 4:
if(ttt[3][1] == '4')
{ttt[3][1] = 'O'; move++;}
break;
case 5:
if(ttt[3][3] == '5')
{ttt[3][3] = 'O'; move++;}
break;
case 6:
if(ttt[3][5] == '6')
{ttt[3][5] = 'O'; move++;}
break;
case 7:
if(ttt[5][1] == '7')
{ttt[5][1] = 'O'; move++;}
break;
case 8:
if(ttt[5][3] == '8')
{ttt[5][3] = 'O'; move++;}
break;
case 9:
if(ttt[5][5] == '9')
{ttt[5][5] = 'O'; move++;}
break;
}
}

draw();
}

// function to check to see if there is a winner;
int win()
{

// see if there are 3 Xs or 3 Os in a row
if((ttt[1][1] == ttt[1][3]) && (ttt[1][3] == ttt[1][5]))
{return(1);}
if((ttt[3][1] == ttt[3][3]) && (ttt[3][3] == ttt[3][5]))
{return(1);}
if((ttt[5][1] == ttt[5][3]) && (ttt[5][3] == ttt[5][5]))
{return(1);}
if((ttt[1][1] == ttt[3][1]) && (ttt[3][1] == ttt[5][1]))
{return(1);}
if((ttt[1][3] == ttt[3][3]) && (ttt[3][3] == ttt[5][3]))
{return(1);}
if((ttt[1][5] == ttt[3][5]) && (ttt[3][5] == ttt[5][5]))
{return(1);}
if((ttt[1][1] == ttt[3][3]) && (ttt[3][3] == ttt[5][5]))
{return(1);}
if((ttt[1][5] == ttt[3][3]) && (ttt[3][3] == ttt[5][1]))
{return(1);}

// if entire board full and no winner, it is a draw
if((ttt[1][1] != '1') && (ttt[1][3] != '2') && (ttt[1][5] != '3') &&
(ttt[3][1] != '4') && (ttt[3][3] != '5') && (ttt[3][5] != '6') &&
(ttt[5][1] != '7') && (ttt[5][3] != '8') && (ttt[5][5] != '9'))
{return(2);}

return(0);
}

--------------------------------------------------------------------------------

#include <iostream.h>
#include <conio.h>
#include <stdlib.h>

void Draw_game_board()
{
cout<<"\t|-----+-----+-----|\n";
cout<<"\t|     |     |     |\n";
cout<<"\t|-----+-----+-----|\n";
cout<<"\t|     |     |     |\n";
cout<<"\t|-----+-----+-----|\n";
cout<<"\t|     |     |     |\n";
cout<<"\t|-----+-----+-----|\n"<<endl;
cout<<"\n"<<"\tComputer = X"<<"\t"<<"Human = O"<<endl;
};
void get_humans_move() {
int row,col;
cout<<"\n\n\t Enter the Row (1-3):";
cin>>row;
cout<<"\t Enter the column (1-3):";
cin>>col;

}
void main(void)
{
int array[3][3]={{0}};

Draw_game_board();
get_humans_move();
}

THIS IS WHAT I CAME UP WITH BUT ITS NOT REALLY RUNNING
DER_23
0

Commented:
Homework again - *sigh*!!!

Why can't these people at least take time to rephrase the assignments?
0

Author Commented:
hehehe, I tried but it didn't work
0

Commented:
> Why can't these people at least take time to rephrase the assignments?

at least he had a go at it before asking - which is better than most

0

Commented:
der_23 - where do you think are having a problem - lets help you debug it rather than do the task for you - actually the last time I did TicTacToe I used Prolog
0

Commented:
im sorry all
two things

a)NO homework at EE - when you signed in you obligated not !!solving any HW just giving pointers

b) my pointer is : the two programs given here are wrong from the "root" meaning -- what if the board was 20X20
,than what?
the proccess will not end,and this is not the way
(i have written a full DOS version) so here goes:

1)you should build a "decision tree" - it's a tree every node is the current situation - and the tree evolves through each step ,,there is a scoring method --and the computer knows which move is the best:EX:

out status is now XXXXXX ( never mind just for the demo)
and it's the computer's turn -- so it takes the board and places it on the tree root it now opens a node for EACH step he can do --every step gets it's node -- so now we have a root and level one(all the options)--now the computer "plays for the man" - for every step in level one on the tree it builds a tree for all the human options -- this will be level 2 ..and going on building a big tree with steps one for the computer one for the human-- ( lets say YOU ,the programmer decided that 10 levels are enough) -- now we use a speciel scoring funtion we have -- wich gives points to every node in the tree acoording to some critiria ( how many it flipped ,how close to the edge and so on...)
the last step is closing the tree --this is done be looking at the move with the highest score for the computer and lowest for the man -- and this will be the move the computer will do.

2) hold a counter for the human and the computer points--this will allow you to decide who won--when the board is full

it's not easy -- but it's an amazing practive in recursive actions and secision trees

tomer
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.