//---------------------------------------------------------------------------
// Program: prog5.cpp
// Purpose: This will be an implementation of a tic-tac-toe game.
// This is a 2 player version of tic-tac-toe where 'X' goes first
// followed by 'O'. When it is player 1's turn, (s)he places an 'X'
// on a 3x3 grid; player 2 places an 'O' on the grid. The first
// player to get 3 characters ('X' or 'O') in a row wins. If
// the board fills up with no winner, the game ends in a tie.
//---------------------------------------------------------------------------
#include <iostream>
usingnamespace std;
// Global variables
constchar BLANK = ' ';
constchar X = 'X';
constchar O = 'O';
constchar TIE = 'T';
constint rows = 3;
constint col = 3;
//---------------------------------------------------------------------------
// Name: PlayX
// Parameters: game board 2d array
// Returns: void
// Purpose: Asks for a position and places an X on the grid at a position and returns true.
// Also performs error checking
//---------------------------------------------------------------------------
void PlayX(char board[3][3])
{
int row, col;
// Ask for the position to place an X.
cout << "Player 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = X;
}
//---------------------------------------------------------------------------
// Name: PlayO
// Parameters:
// Returns:
// Purpose: Similar to the PlayX function
//---------------------------------------------------------------------------
void PlayO(char board[3][3])
{
int row, col;
// Ask for the position to place an O.
cout << "Player 2's turn. Enter the position you'd like to place an O as row col" << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 2's turn. Enter the position you'd like to place an O as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = O;
}
//---------------------------------------------------------------------------
// Name: CheckWinner
// Parameters: 2d array for game board
// Returns: char
// Purpose: return 'X' if x wins, 'O' if o wins, 'T' if
// the game has ended in a tie.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Name: ConfirmPlayAgain
// Parameters: none
// Returns: bool
// Purpose: Once the game has ended, this function asks if the player wants to
// play again.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Name: PrintBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Output current tic-tac-toe game board
//---------------------------------------------------------------------------
void PrintBoard()
{
constint row = 3;
constint col = 3;
char board[row][col] = {' '};
cout << " ___ ___ ___\n";
cout << "| " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " |\n";
cout << "|___|___|___|\n";
}
//---------------------------------------------------------------------------
// Name: InitializeBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Sets tic-tac-toe game board to blank
//---------------------------------------------------------------------------
void InitializeBoard(char board[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = BLANK;
}
}
}
// Main should be used to call the functions above to complete the tic-tac-toe game.
int main ()
{
InitializeBoard();
PrintBoard();
PlayX(board);
PlayO(board);
return 0;
}
I'm having trouble knowing what to pass into the InitializeBoard, PlayX, and PlayO functions. Also I'm not quite understanding how to get the program to redraw the board with the player's input (X or O) in the designated space. Any help is appreciated. Thanks!
That should redraw the screen everytime you call the function. Notice how I defined the center of each square. Each one is defined as a square array element containing the number 1-9 so the user can select a move to make. There's no need for a bi-dimensional array. When the user makes a move (every other move is X and inbetween O) the square array records into that square the character of the player who just moved. So it can dynamically change as outside variables change.
Squares[array] is of char data type
EDIT* I actually forgot I used a struct to hold player 1 and player 2 moves for this project to practice using data structures. Your multidimensional array will work.
Okay thanks! I think that helps! How do I call these functions with array parameters in main?
More specifically, what do I need to put in the parenthesis when I call InitializeBoard in main. I don't know how to call them correctly. Thanks again!
I would redefine char board[][] array inside of int main(), and pass it to necessary functions by reference. That way all your functions will have the chance to use it. Then you can use
The redefining char board in main helped the functions compile, but I'm not sure if it's working correctly.
I'm going to create the checkwinner function and use a while loop to redraw the board every time. But for now, just to test it out, I'm manually calling PrintBoard after every PlayX and PlayO function call. But for some reason, It's still printing a blank board.
That's my main function. Shouldn't the PlayX function be placing an X in one place of the board, so when the second PrintBoard function is called, it displays it with that X in its place? I'm not sure what I'm doing wrong.
You're going to want to put all of the functions in main, within a loop to keep regenerating the board.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
int main ()
{
constint row = 3;
constint col = 3;
char board[row][col] = {' '};
InitializeBoard(board);
PrintBoard(board);
while (true) {
PlayX(board);
PrintBoard(board);
PlayO(board);
PrintBoard(board);
}
return 0;
}
*EDITED CODE ABOVE. RE PASTE
Don't forget to add system("cls"); as the first statement within the PrintBoard function body
To make it more efficient, change PlayX and PlayO to one function, with the player character generated from a dynamic variable that changes every other turn. Modulo (%) can help with that.
Combined PlayX and PlayO into Play(char board[3][3], char& symbol):
Sorry to keep bugging you, and thanks for all the help, but that's all compiling correctly, but I'm still not getting it to redisplay the board with the users' inputs being displayed.
Also, did you mean to put "board" inside of PrintBoard? Because that made it fail to compile.
Here's what I have now: (mostly what you wrote in your last post)
___ ___ ___
| | | |
|___|___|___|
| | | |
|___|___|___|
| | | |
|___|___|___|
Player 1's turn. Enter the position you'd like to place an X as row col
0 1
___ ___ ___
| | | |
|___|___|___|
| | | |
|___|___|___|
| | | |
|___|___|___|
Player 2's turn. Enter the position you'd like to place an O as row col
0 2
___ ___ ___
| | | |
|___|___|___|
| | | |
|___|___|___|
| | | |
|___|___|___|
Player 1's turn. Enter the position you'd like to place an X as row col
As you can see, it's doing everything correctly except placing the choice in the corresponding square. This is what I've been stuck on for so long.
Thank you so much for taking the time to help me. It's made a huge difference!
//---------------------------------------------------------------------------
// Program: prog5.cpp
// Purpose: This will be an implementation of a tic-tac-toe game.
// This is a 2 player version of tic-tac-toe where 'X' goes first
// followed by 'O'. When it is player 1's turn, (s)he places an 'X'
// on a 3x3 grid; player 2 places an 'O' on the grid. The first
// player to get 3 characters ('X' or 'O') in a row wins. If
// the board fills up with no winner, the game ends in a tie.
//---------------------------------------------------------------------------
#include "stdafx.h"
#include <iostream>
usingnamespace std;
// Global variables
constchar BLANK = ' ';
constchar X = 'X';
constchar O = 'O';
constchar TIE = 'T';
constint rows = 3;
constint col = 3;
//---------------------------------------------------------------------------
// Name: PlayX
// Parameters: game board 2d array
// Returns: void
// Purpose: Asks for a position and places an X on the grid at a position and returns true.
// Also performs error checking
//---------------------------------------------------------------------------
void Play(char board[3][3], char& symbol)
{
int row, col;
// Ask for the position to place an X.
cout << "Player 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = symbol;
}
//---------------------------------------------------------------------------
// Name: CheckWinner
// Parameters: 2d array for game board
// Returns: char
// Purpose: return 'X' if x wins, 'O' if o wins, 'T' if
// the game has ended in a tie.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Name: ConfirmPlayAgain
// Parameters: none
// Returns: bool
// Purpose: Once the game has ended, this function asks if the player wants to
// play again.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Name: PrintBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Output current tic-tac-toe game board
//---------------------------------------------------------------------------
void PrintBoard(char board[3][3])
{
system("cls");
cout << " ___ ___ ___\n";
cout << "| " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " |\n";
cout << "|___|___|___|\n";
}
//---------------------------------------------------------------------------
// Name: InitializeBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Sets tic-tac-toe game board to blank
//---------------------------------------------------------------------------
void InitializeBoard(char board[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = BLANK;
}
}
}
// Main should be used to call the functions above to complete the tic-tac-toe game.
int main ()
{
constint row = 3;
constint col = 3;
char symbol = 'X';
int count = 1;
char board[row][col] = {' '};
InitializeBoard(board);
PrintBoard(board);
while (true) {
if (count % 2 != 0)
symbol = 'X';
else
symbol = 'O';
Play(board, symbol);
PrintBoard(board);
count++;
}
return 0;
}
One very small question though. I noticed you combined the PlayX and PlayO functions into 1. Is there anyway I can expand those back into two functions and use your general design or keep them as one function and make it switch between saying "Player 1's turn" and "Player 2's turn?" Because as of right now, it says player 1's turn over and over.
Sure, from int main() just pass the symbol variable to the function that checks for a winner. If it's 'X' when the winning condition is met than player 1 wins, and vice versa.
EDIT* I read your question wrong, above is the solution to name the final winner. Below is code for player turn display
void Play(char board[3][3], char& symbol)
{
int row, col, player;
// Ask for the position to place an X.
if (symbol == 'X')
player = 1;
else
player = 2;
cout << "Player " << player << "'s turn." << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = symbol;
}
Thanks again! I got it work by going back to individual functions for PlayX and PlayO. Your method worked great, I just think the teacher wanted us to have two separate functions. Unfortunately I've run into another problem. I've created the CheckWinner function and can't get it to act correctly.
//---------------------------------------------------------------------------
// Program: prog5.cpp
// Purpose: This will be an implementation of a tic-tac-toe game.
// This is a 2 player version of tic-tac-toe where 'X' goes first
// followed by 'O'. When it is player 1's turn, (s)he places an 'X'
// on a 3x3 grid; player 2 places an 'O' on the grid. The first
// player to get 3 characters ('X' or 'O') in a row wins. If
// the board fills up with no winner, the game ends in a tie.
//---------------------------------------------------------------------------
#include <iostream>
usingnamespace std;
// Global variables
constchar BLANK = ' ';
constchar X = 'X';
constchar O = 'O';
constchar TIE = 'T';
constint rows = 3;
constint col = 3;
//---------------------------------------------------------------------------
// Name: PlayX
// Parameters: game board 2d array
// Returns: void
// Purpose: Asks for a position and places an X on the grid at a position and returns true.
// Also performs error checking
//---------------------------------------------------------------------------
void PlayX(char board[3][3])
{
int row, col;
// Ask for the position to place an X.
cout << "Player 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = X;
}
void PlayO(char board[3][3])
{
int row, col;
// Ask for the position to place an X.
cout << "Player 2's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
while (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != BLANK)
{
cout << "\nNot a valid play. \nPlayer 1's turn. Enter the position you'd like to place an X as row col" << endl;
cin >> row >> col;
}
// set the position on the board to X
board[row][col] = O;
}
//---------------------------------------------------------------------------
// Name: CheckWinner
// Parameters: 2d array for game board
// Returns: char
// Purpose: return 'X' if x wins, 'O' if o wins, 'T' if
// the game has ended in a tie.
//---------------------------------------------------------------------------
int CheckWinner(char board[3][3])
{
//check to see if X won
if(board[0][0] == X && board[0][1] == X && board[0][2] == X)
return 1;
if(board[1][0] == X && board[1][1] == X && board[1][2] == X)
return 1;
if(board[2][0] == X && board[2][1] == X && board[2][2] == X)
return 1;
if(board[0][0] == X && board[1][0] == X && board[2][0] == X)
return 1;
if(board[0][1] == X && board[1][1] == X && board[2][1] == X)
return 1;
if(board[0][2] == X && board[1][2] == X && board[2][2] == X)
return 1;
if(board[0][0] == X && board[1][1] == X && board[2][2] == X)
return 1;
if(board[2][0] == X && board[1][1] == X && board[0][2] == X)
return 1;
//check to see if O won
if(board[0][0] == O && board[0][1] == O && board[0][2] == O)
return 0;
if(board[1][0] == O && board[1][1] == O && board[1][2] == O)
return 0;
if(board[2][0] == O && board[2][1] == O && board[2][2] == O)
return 0;
if(board[0][0] == O && board[1][0] == O && board[2][0] == O)
return 0;
if(board[0][1] == O && board[1][1] == O && board[2][1] == O)
return 0;
if(board[0][2] == O && board[1][2] == O && board[2][2] == O)
return 0;
if(board[0][0] == O && board[1][1] == O && board[2][2] == O)
return 0;
if(board[2][0] == O && board[1][1] == O && board[0][2] == O)
return 0;
}
//---------------------------------------------------------------------------
// Name: ConfirmPlayAgain
// Parameters: none
// Returns: bool
// Purpose: Once the game has ended, this function asks if the player wants to
// play again.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Name: PrintBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Output current tic-tac-toe game board
//---------------------------------------------------------------------------
void PrintBoard(char board[3][3])
{
cout << " ___ ___ ___\n";
cout << "| " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " |\n";
cout << "|___|___|___|\n";
cout << "| " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " |\n";
cout << "|___|___|___|\n";
}
//---------------------------------------------------------------------------
// Name: InitializeBoard
// Parameters: 2d array game board
// Returns: void
// Purpose: Sets tic-tac-toe game board to blank
//---------------------------------------------------------------------------
void InitializeBoard(char board[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
board[i][j] = BLANK;
}
}
}
// Main should be used to call the functions above to complete the tic-tac-toe game.
int main ()
{
constint row = 3;
constint col = 3;
int count = 1;
char board[row][col] = {BLANK};
int checkwin = CheckWinner(board);
InitializeBoard(board);
PrintBoard(board);
while (checkwin != 1 && checkwin!= 2)
{
cout << checkwin << endl;
PlayX(board);
PrintBoard(board);
PlayO(board);
PrintBoard(board);
}
if (checkwin == 1)
{
cout << "Player 1 has won!" << endl;
}
return 0;
}
In main, I put cout << checkwin << endl; just for debugging purposes. But I'm getting some weird results.
___ ___ ___
| | | |
|___|___|___|
| | | |
|___|___|___|
| | | |
|___|___|___|
1629969280
Player 1's turn. Enter the position you'd like to place an X as row col
so the value of checkwin is 1629969280, which I'm guessing is its memory location, but I don't know why that's turning up.
// Check tie
bool tie = true;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] == ' ')
{
tie = false;
break;
}
}
}
if (tie) return'T';
// A winner can be found as such, it works for both X and Y:
if (board[0][0] == board[0][1] && board[0][0] == board[0][2])
return board[0][0];
// Check the rest the same way.
// If we get here, there is no tie or a winner, so
return'N';
// In main, loose the while(true)
bool Xturn = true;
while (checkWinner(board) == 'N')
{
printBoard(board);
if (Xturn) playX(board);
else playO(board);
Xturn = !Xturn;
}
switch(checkWinner(board))
{
case'X': cout << "X wins\n"; break;
//...
}
I made some modifications and accomplished basically what you were talking about (although yours is a bit simpler). Now i'm just trying to implement a loop in main for the boolean value of whether they want to play again.
int main ()
{
constint row = 3;
constint col = 3;
int count = 1;
char board[row][col] = {BLANK};
int checkwin = CheckWinner(board);
do
{
getNames();
InitializeBoard(board);
PrintBoard(board);
while (true)
{
PlayX(board);
PrintBoard(board);
checkwin = CheckWinner(board);
if ((checkwin == X)||(checkwin == BLANK))
break;
PlayO(board);
PrintBoard(board);
checkwin = CheckWinner(board);
if ((checkwin == O)||(checkwin == BLANK))
break;
}
if (checkwin == X)
{
cout << name1 << " has won!" << endl;
}
elseif (checkwin == O) {
cout << name2 << " has won!" << endl;
}
elseif (checkwin == BLANK){
cout << "The game ends in a tie!" << endl;
}
while (playAgain == true)
}
return 0;
}
I'm getting an unexpected token error at lines 50 and 53. I'm guessing it has something to do with the while loop already present. is a while loop inside the do portion of a do while loop forbidden?