I have this code for a tic tac toe game, everything works fine, but only two player can play, I`d like to make it so the user can enter the number of players, and if there`s only one player, the user can play agains the computer, how do I get the computer to fill in a box after each time the user plays?

this is the code I have right now.

// Laelzio Mosca
// 12/09/09
// Tic Tac Toe game

#include <iostream>
#include <iomanip>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

using std::setw;

//global variables
const int row = 3; //size of array
const int column = 3; // size of array
string BLANK = " ";
string ticTac[row][column];

static int nspots = 9; // number of possible spots

void ticTacToe(const string ticTacToe[][column]); //Function prototypes
void player1(string ticTacToe[][column]);
void player2(string ticTac[][column]);
void checkWinner(string ticTac[][column]);

// program execution begins
int main()
{
	string ticTac[row][column] = {{BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}}; //number display for rows and columns 
	cout << "Welcome to the tic tac toe game "<<endl << endl; // welcome message
	ticTacToe( ticTac ); // function call

		   while (nspots > 0) 	
			{		
				player1(ticTac);	
				checkWinner(ticTac);

				if (nspots < 0) break;
				if (nspots == 0) {
					cout << "DRAW" << endl;
				    break;
				}
				player2(ticTac);

				checkWinner(ticTac);
				// the following should never happen
				if (nspots == 0) {
					cout << "DRAW" << endl;
				    break;
				}
			//	cout << "nspots: " << nspots << endl;
			}
		   cout << endl;
		
		   fflush(stdin); // clear the buffer, and wait to exit.
		   cout << "\nPress enter to exit " << endl;
		   getc(stdin);

	return 0;
}

//Function ticTacToe
void ticTacToe(const string ticTacToe[][column])
{
	cout << setw(5)<<"|"<<setw(5)<< "|" <<endl;

	//for loop-continuation condition and increment
	for (int i = 0; i < row; i ++)
	{
		for (int j = 0; j < column; j++)
			//check to output '|' only in between the numbers, not at the end
			if ( j < column - 1)
			{
				cout << setw(3)<< ticTacToe[i][j] << setw(2)<<"|";
			}
			else					
				cout << setw(3)<<ticTacToe[i][j];
							
			cout << endl;

			// check to make sure the horizontal line in only printed in between
			// the 3 rows, not on the bottom fo the picture
			if ( i < row -1)
			{
				cout << "____|____|____"<<endl;
				cout << setw(5) << "|" << setw(5) << "|" << endl;
			}
			else
				cout << setw(5) << "|" << setw(5) << "|" << endl;		
			
	}
}

void player1(string ticTac[][column])
{
	int x = 0;
	int y = 0;
	string p1 = "X";

	cout << "Player one can enter your coordinates for X." << endl;
		cin >> x >> y ;
		x--, y--;
		while (x >= row || y >= column)
		{
			cout << "Invalit entry, try a number from 1 to 3.";
			cin >> x >> y;
			x--, y--;
		}
		if (ticTac[x][y] != BLANK)
		{
			cout << "That spot is taken." << "\nEnter different coordinates for 'X'." << endl;
			player1(ticTac);
		}
		else {
			ticTac[x][y] = p1;
			nspots--;
		}
		ticTacToe( ticTac );
		
}

void player2(string ticTac[][column])
{
	int x = 0;
	int y = 0;
	string p2 = "O";

	cout << "Player two can enter you coordinates for 'O'. ";
		cin >> x >> y;
	x--,y--;
		while  (x >= row || y >= column)
		{
			cout << "Invalit entry, try a number from 1 to 3.";
			cin >> x >> y;
			x--, y--;
		}
		if (ticTac[x][y] != BLANK)
		{
			cout << "That spot is taken." << "\nEnter different coordinates for 'O'." << endl;
			player2(ticTac);
		}
		else {
			ticTac[x][y] = p2;
			nspots--;
		}
		ticTacToe( ticTac );
}

void checkWinner(string ticTac[][column])
{
   
//	for (int i = 0; i < row; i++)
//	{
//		for (int j = 0; j < column; j++)
//		{
			//check columns for winner // column 1
		   if ((ticTac[0][0] == ticTac[1][0]) && (ticTac[1][0] == ticTac[2][0]) && (ticTac[0][0] != BLANK))
		   {
			   cout << "YOU ARE THE WINNER!";
			   nspots = -1;
		   } // column 2
		   else if (ticTac[0][1] == ticTac[1][1] && ticTac[1][1] == ticTac[2][1] && (ticTac[0][1] != BLANK))
		   {
			   cout << "YOU ARE THE WINNER!";
			   nspots = -1;
		   } // column 3
		   else if (ticTac[0][2] == ticTac[1][2] && ticTac[1][2] == ticTac[2][2] && (ticTac[0][2] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
		   //check for winner diagnally
		   else if (ticTac[2][0] == ticTac[1][1] && ticTac[1][1] == ticTac[0][2] && (ticTac[2][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
		   else if (ticTac[0][0] == ticTac[1][1] && ticTac[1][1] == ticTac[2][2] && (ticTac[0][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
			//check rows for winner  // row 1
		   else if (ticTac[0][0] == ticTac[0][1] && ticTac[0][1] == ticTac[0][2] && (ticTac[0][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   } // row 2 
		   else if (ticTac[1][0] == ticTac[1][1] && ticTac[1][1] == ticTac[1][2] && (ticTac[1][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   } // row 3
		   else if (ticTac[2][0] == ticTac[2][1] && ticTac[2][1] == ticTac[2][2] && (ticTac[2][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
//		}
//	}
}

thanks

Recommended Answers

All 13 Replies

It would depend on how smart you want the computer to play. The smarter you want the computer to be, the more work it will be.

You will likely end up adding a function that will 'make a move' like the player1() and player2() do. A simple implementation for the function might be to randomly generate coordinates until an available space was located.

A more complex algorigthm would be multi-part, possibly something like the following:

  • look to see if the computer can win on this move, if so, make that move and win.
  • look to see if the player can win on their next move, if so block that move.
  • randomly select another location

The most complex algorithm would replace the last 'randomly select a location' with a make the 'best' move instead.

I trying to add a function generateNumber() so the computer can play after player1(), I just started the function, but there`s something wrong, my program breaks everytime I choose one player.
This is What I added in my code:

void generateNumber(string ticTac[][column])
{

	int a; // generate number 1
	int b;// generate number 2
	string gn = "O";
	
	while (nspots > 0)
	{
		a = (rand() % 3) - 1; 
		b = (rand() % 3) - 1; 

		if (ticTac[a][b] != BLANK)
		{
			generateNumber(ticTac);
		}
		else
			ticTac[a][b] = gn;	
	}
	nspots--;
	ticTacToe( ticTac );
}

and my main is now like this:

int main()
{
	int numberOfPlayers;

	string ticTac[row][column] = {{BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}}; //number display for rows and columns 
	cout << "Welcome to the tic tac toe game "<<endl << endl; // welcome message
	cout << "Enter the number of players with a max of 2 and press enter: ";
	cin >> numberOfPlayers;
	if (numberOfPlayers == 2)
	{
		ticTacToe( ticTac ); // function call

			   while (nspots > 0) 	
				{		
					player1(ticTac);	
					checkWinner(ticTac);

					if (nspots < 0) break;
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
					player2(ticTac);

					checkWinner(ticTac);
					// the following should never happen
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
				//	cout << "nspots: " << nspots << endl;
				}
			   cout << endl;
			
			   fflush(stdin); // clear the buffer, and wait to exit.
			   cout << "\nPress enter to exit " << endl;
			   getc(stdin);
	}
	else
	{
		ticTacToe( ticTac ); // function call

			   while (nspots > 0) 	
				{		
					player1(ticTac);	
					checkWinner(ticTac);

					if (nspots < 0) break;
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
					generateNumber(ticTac);	

					checkWinner(ticTac);
					// the following should never happen
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
				//	cout << "nspots: " << nspots << endl;
				}
			   cout << endl;
			
			   fflush(stdin); // clear the buffer, and wait to exit.
			   cout << "\nPress enter to exit " << endl;
			   getc(stdin);
	}

	return 0;
}

the rest remains the same

can anyone please tell me what should I do to make it work.

a = (rand() % 3) - 1; generates numbers in the range -1 to 1, is that what you intended?

oh, so in order to get numbers from 0 to 2 all I need is a = (rand() % 3) ?

yes

This code is working pretty good now, but the problem is that when the player chooses to play against the computer he has to press 1, so even though I using srand() to generate the numbers, 1 is always the seed, and it puts an "O" in the boxes in the same order everytime the program runs.

this is my generateNumber() function:

{

	int a; // number 1
	int b; // number 2
	string gn = "O";
	
	
		a = (rand() % 3); // generate number 1
		b = (rand() % 3); // generate number 2

		if (ticTac[a][b] != BLANK)
		{
			generateNumber(ticTac);
		}
		else
		{
			ticTac[a][b] = gn;	
		}
	nspots--;
	ticTacToe( ticTac );
}

You mention srand() but I don't see where you call it...

Take a peek at this and see if it gives you any ideas.

I`m just about done with this code, all I need to do is print out who won, right now it only prints " You are the winner!" but I don`t know what to do to print who is the winner, player1, player 2, or the computer.

can anyone help me please?

// Laelzio Mosca
// 12/09/09
// Tic Tac Toe game

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

#include <iomanip>
using std::setw;

#include <string>
using std::string;

#include <cstdlib>
using std::rand;
using std::srand;

#include <ctime>
using std::time;

//global variables
const int row = 3; //size of array
const int column = 3; // size of array
string BLANK = " ";
string ticTac[row][column];

static int nspots = 9; // number of possible spots

void ticTacToe(const string ticTacToe[][column]); //Function prototypes
void player1(string ticTacToe[][column]);
void player2(string ticTac[][column]);
void generateNumber(string ticTac[][column]);
void checkWinner(string ticTac[][column]);

// program execution begins
int main()
{
	srand( time(0));
	int numberOfPlayers;

	string ticTac[row][column] = {{BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}, {BLANK,BLANK,BLANK}}; //number display for rows and columns 
	cout << "Welcome to the tic tac toe game "<<endl << endl; // welcome message
	cout << "Enter the number of players with a max of 2 and press enter: ";
	cin >> numberOfPlayers;
	if (numberOfPlayers == 2)
	{
		ticTacToe( ticTac ); // function call

			   while (nspots > 0) 	
				{		
					player1(ticTac);	
					checkWinner(ticTac);

					if (nspots < 0) break;
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
					player2(ticTac);

					checkWinner(ticTac);
					// the following should never happen
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
				//	cout << "nspots: " << nspots << endl;
				}
			   cout << endl;
			
			   fflush(stdin); // clear the buffer, and wait to exit.
			   cout << "\nPress enter to exit " << endl;
			   getc(stdin);
	}
	else
	{
		ticTacToe( ticTac ); // function call

			   while (nspots > 0) 	
				{		
					player1(ticTac);	
					checkWinner(ticTac);

					if (nspots < 0) break;
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
					generateNumber(ticTac);	

					checkWinner(ticTac);
					// the following should never happen
					if (nspots == 0) {
						cout << "DRAW" << endl;
						break;
					}
				}
			   cout << endl;
			
			   fflush(stdin); // clear the buffer, and wait to exit.
			   cout << "\nPress enter to exit " << endl;
			   getc(stdin);
	}

	return 0;
}

//Function ticTacToe
void ticTacToe(const string ticTacToe[][column])
{
	cout << setw(5)<<"|"<<setw(5)<< "|" <<endl;

	//for loop-continuation condition and increment
	for (int i = 0; i < row; i ++)
	{
		for (int j = 0; j < column; j++)
			//check to output '|' only in between the numbers, not at the end
			if ( j < column - 1)
			{
				cout << setw(3)<< ticTacToe[i][j] << setw(2)<<"|";
			}
			else					
				cout << setw(3)<<ticTacToe[i][j];
							
			cout << endl;

			// check to make sure the horizontal line in only printed in between
			// the 3 rows, not on the bottom fo the picture
			if ( i < row -1)
			{
				cout << "____|____|____"<<endl;
				cout << setw(5) << "|" << setw(5) << "|" << endl;
			}
			else
				cout << setw(5) << "|" << setw(5) << "|" << endl;		
			
	}
}

void player1(string ticTac[][column])
{
	int x = 0;
	int y = 0;
	string p1 = "X";

	cout << "Player one can enter your coordinates for X." << endl;
		cin >> x >> y ;
		x--, y--;
		while (x >= row || y >= column)
		{
			cout << "Invalit entry, try a number from 1 to 3.";
			cin >> x >> y;
			x--, y--;
		}
		if (ticTac[x][y] != BLANK)
		{
			cout << "That spot is taken." << "\nEnter different coordinates for 'X'." << endl;
			player1(ticTac);
		}
		else {
			ticTac[x][y] = p1;
			nspots--;
		}
		ticTacToe( ticTac );
		
}

void player2(string ticTac[][column])
{
	int x = 0;
	int y = 0;
	string p2 = "O";

	cout << "Player two can enter you coordinates for 'O'. ";
		cin >> x >> y;
	x--,y--;
		while  (x >= row || y >= column)
		{
			cout << "Invalit entry, try a number from 1 to 3.";
			cin >> x >> y;
			x--, y--;
		}
		if (ticTac[x][y] != BLANK)
		{
			cout << "That spot is taken." << "\nEnter different coordinates for 'O'." << endl;
			player2(ticTac);
		}
		else {
			ticTac[x][y] = p2;
			nspots--;
		}
		ticTacToe( ticTac );
}

void generateNumber(string ticTac[][column])
{

	int a; // number 1
	int b; // number 2
	string gn = "O";
	
	
	do {
		a = (rand() % 3); // generate number 1
	} while (a > 2);
	do {
		b = (rand() % 3); // generate number 2
	} while (b > 2);


		if (ticTac[a][b] != BLANK)
		{
			generateNumber(ticTac);
		}
		else
		{
			ticTac[a][b] = gn;	
			nspots--;
		}
	ticTacToe( ticTac );
}
void checkWinner(string ticTac[][column])
{
			//check columns for winner // column 1
		   if ((ticTac[0][0] == ticTac[1][0]) && (ticTac[1][0] == ticTac[2][0]) && (ticTac[0][0] != BLANK))
		   {
			   cout << "YOU ARE THE WINNER!";
			   nspots = -1;
		   } // column 2
		   else if (ticTac[0][1] == ticTac[1][1] && ticTac[1][1] == ticTac[2][1] && (ticTac[0][1] != BLANK))
		   {
			   cout << "YOU ARE THE WINNER!";
			   nspots = -1;
		   } // column 3
		   else if (ticTac[0][2] == ticTac[1][2] && ticTac[1][2] == ticTac[2][2] && (ticTac[0][2] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
		   //check for winner diagnally
		   else if (ticTac[2][0] == ticTac[1][1] && ticTac[1][1] == ticTac[0][2] && (ticTac[2][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
		   else if (ticTac[0][0] == ticTac[1][1] && ticTac[1][1] == ticTac[2][2] && (ticTac[0][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
			//check rows for winner  // row 1
		   else if (ticTac[0][0] == ticTac[0][1] && ticTac[0][1] == ticTac[0][2] && (ticTac[0][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   } // row 2 
		   else if (ticTac[1][0] == ticTac[1][1] && ticTac[1][1] == ticTac[1][2] && (ticTac[1][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   } // row 3
		   else if (ticTac[2][0] == ticTac[2][1] && ticTac[2][1] == ticTac[2][2] && (ticTac[2][0] != BLANK))
		   {
				cout << "YOU ARE THE WINNER!";
				nspots = -1;
		   }
}

Well, if you check for the winner after every move, the only one that could have won would have been the last one to make a move.

Could you pass a string to the check win to tell which player it is checking for?

Or could check win return true or false (without printing) and let the code that called check win display the outcome?

my code is working good, but I`d like to make the computer play a little harder, right now it`s only generating random numbers to fill in the empty slots, I`d like to check rows and colomns first to see if the computer can win, and mark the winning square, if computer can`t win then check to see is player one can win, if so, check the square so the player can`t win, if neither one can win, then generate a random square, I`m not sure how to do that, I just started my checkToWin() function, but I`m not sure how to check every row, every column, and across, this is what I started

void checkToWin(string ticTac[][column]
{
	for (int i = 0, i < row; i++)
	{
		for(int j = 0; j < column; j++)

	}
}

My code works good now, but the computer plays to easy, I want to make it so the computer check to see the the computer can win, if yes than mark that spot, if not, check to see if player can win, and check the box to block it , if if neither of the options are true, then call the function to generate a random number.
I don`t know how to check for "X", I have to check rows, columns, and diagonal, I starter a for loop, I don`t know if its right, and if it is, I don`t know how to proceed.

please help me

the variable nx is initialized to 0 and it mean number of X`s.
row and column =3;

void checkToWin(string ticTac[][column]
{
	int nx = 0;
	for (int i = 0; i < row; i++)
	{
		for(int j = 0; j < column; j++)
		{
			if (ticTac[][])= "X";
			nx++;
			
		}

	}
}

You aren't going to check each row/column set...this function will be very much like your 'check for a winner' function that finds when someone wins.

You need to go through all of the possible wins looking for one that is 'almost' there. A lot of your win check and partial win check code would have been easier if you had 'flattened' the game board. As I mentioned on a couple of other Tic-Tac-Toe threads (I think one was yours) just because the board is displayed as a 3 x 3 matrix does NOT mean you have to store it that way.

Regardless, if you had an array (or list) of the possible ways to win, the check for a real winner code could use them to find a winner, and the check for an almost winner could use the same list.

// presuming that ax, ay, bx, by, cx and cy are all integers
// and have been initialized to a set of coordinates for a winning path

// presuming this function has access to ticTac -- the board array

if ((ticTac[ax][ay] == ticTax[bx][by]) && (ticTac[cx][cy] == BLANK))
    // cx,cy either wins or blocks a win
else if ((ticTac[ax][ay] == ticTax[cx][cy]) && (ticTac[bx][by] == BLANK))
    // bx,by either wins or blocks a win
else if ((ticTac[bx][by] == ticTax[cx][cy]) && (ticTac[ax][ay] == BLANK))
    // ax,ay either wins or blocks a win

If the board were 'flat' then the same code would look like:

// presuming that a, b and c are all integers
// and have been initialized to a set of coordinates for a winning path

// presuming this function has access to ticTac -- the board array

if ((ticTac[a] == ticTax[b]) && (ticTac[c] == BLANK))
    // c either wins or blocks a win
else if ((ticTac[a] == ticTax[c]) && (ticTac[b] == BLANK))
    // b either wins or blocks a win
else if ((ticTac[b] == ticTax[c]) && (ticTac[a] == BLANK))
    // a either wins or blocks a win

The array or list of possible wins is also simplified for a 'flat' board, but you can still make it work for the board you have. (Sometimes those early design decisions make a lot of difference on the back end.)

Your project is to build the array or list of 'winning paths' as well as adapt the above code to look for a particular winner. It would be pretty stupid of the computer to block one of the players winning paths instead of winning itself, so you can't check for both at once. You have to check all winning paths to see if the computer can win first (and if it can it should), then you can check to see if the player might win and you can move to block it. (Make sure your win / block / random code can't make more than one move, that wouldn't be fair.)

If you have trouble with the above, post your 'winning path' array and your check for partial win function and we'll examine them for problems.

Tic tac toe is a small game compared to a game like chess.
It is good to write a recursive function that will try out all the moves possible and choose the best one.
This will simplify the code and make the program very efficient.

If you find that hard,you can make the computer think just 2 moves ahead(which can be achieved using a couple of nested for loops).

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.