I am currently trying to make a tic tac toe game that uses char arrays as a way for a user to change a number inside a 3x3 grid to an X or an O when a user inputs the corresponding number (for example, in the top left grid space has a 1. if a user inputs 1, it should change into an X).
The code does display the box game and asks a user to input a number but whatever number is input, the numbers inside the 3x3 grid (my BoardView class member) do not change. I don't want them to be constant because it won't change, but I've read online that I have to set it as a constant inside of a class member...Although that was for a different program.
I have been told by my instructor that I CANNOT move my char array as a global variable (which made it work perfectly) so it has to be inside the class or it's members.
#include <iostream>
#include <string>
usingnamespace std;
// start of BoardGame class
class BoardGame
{
// playerOne data field checks the input used in the choice data field and computates which number and symbol to display in the spaces on the board.
int playerOne;
// choice data field asks user what number to input so it can check the corresponding number in the char array and playerOne/allPlayers data field
int choice;
// checkAction data field that calls the spaceCheck member that computes if there are three spaces that match the same symbol
int checkAction;
public:
// delcares public data fields
void BoardView();
void playerOneAction();
void GameShow();
void GameWinner(int);
int spaceCheck();
char box[10];
//using init list:
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}
}; // end of BoardGame class
// BoardView member that shows the game board
void BoardGame::BoardView()
{
cout << " | | " << endl;
cout << " " << box[1] << " | " << box[2] << " | " << box[3] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << box[4] << " | " << box[5] << " | " << box[6] << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << box[7] << " | " << box[8] << " | " << box[9] << endl;
cout << " | | " << endl << endl;
}
// didWin constructor function that determines how a the spaces match up.
int BoardGame::spaceCheck()
{
if (box[1] == box[2] && box[2] == box[3])
return 1;
elseif (box[4] == box[5] && box[5] == box[6])
return 1;
elseif (box[7] == box[8] && box[8] == box[9])
return 1;
elseif (box[1] == box[4] && box[4] == box[7])
return 1;
elseif (box[2] == box[5] && box[5] == box[8])
return 1;
elseif (box[3] == box[6] && box[6] == box[9])
return 1;
elseif (box[1] == box[5] && box[5] == box[9])
return 1;
elseif (box[3] == box[5] && box[5] == box[7])
return 1;
elseif (box[1] != '1' && box[2] != '2' && box[3] != '3'
&& box[4] != '4' && box[5] != '5' && box[6] != '6'
&& box[7] != '7' && box[8] != '8' && box[9] != '9')
return 0;
elsereturn -1;
}
// Game winner method to decide how a player wins by using if else statements to see which boxes match up.
void BoardGame::GameWinner(int allPlayers)
{
// accesses and mutates the data members playerOne, choice, and checkAction to allPlayers.
playerOne = allPlayers;
allPlayers = 1, choice, checkAction;
char space;
do
{
// calls Game Show member to update the user by showing the board after a player outputs a number
GameShow();
allPlayers=(allPlayers%2)?1:2;
cout << "Player " << allPlayers << ", please enter a number\nin an empty space: ";
cin >> choice;
cout << "" << endl;
space = (allPlayers == 1) ? 'X' : 'O';
if (choice == 1 && box[1] == '1')
box[1] = space;
elseif (choice == 2 && box[2] == '2')
box[2] = space;
elseif (choice == 3 && box[3] == '3')
box[3] = space;
elseif (choice == 4 && box[4] == '4')
box[4] = space;
elseif (choice == 5 && box[5] == '5')
box[5] = space;
elseif (choice == 6 && box[6] == '6')
box[6] = space;
elseif (choice == 7 && box[7] == '7')
box[7] = space;
elseif (choice == 8 && box[8] == '8')
box[8] = space;
elseif (choice == 9 && box[9] == '9')
box[9] = space;
else
{
cout<<"That isn't allowed! Please enter a number! ";
allPlayers--;
cin.ignore();
cin.get();
system("PAUSE");
}
checkAction = spaceCheck();
allPlayers++;
} while (checkAction==-1);
BoardGame::BoardView();
if (checkAction==1)
cout<<"GAME OVER!\nPLAYER "<<--allPlayers<<" WINS!!!! ";
else
cout<<"THE GAME IS A DRAW!!!";
cin.ignore();
cin.get();
system("PAUSE");
} // end of GameWinner constructor function
// function that calls the board game to be shown everytime an action is completed (is inside GameWinner member)
void BoardGame::GameShow()
{
if (playerOne = 1)
cout << "The game board status is currently:" << endl;
cout << "" << endl;
return BoardView();
}
int main ()
{
int allPlayers = 0;
// Describes the game
cout << "Welcome to a tic-tac-toe game!" << endl;
cout << "" << endl;
cout << "The goal is for one player to get their symbol across three spaces!" << endl;
cout << "Player X will start first.\nPlayer O will be after." << endl;
cout << "The game will end when a single player wins." << endl;
cout << "" << endl;
cout << "Player 1 is the 'X' and Player 2 is the 'O'" << endl << endl;
cout << "Player 1 or 'X' will start first." << endl;
cout << "" << endl;
// asks the player to enter an option
BoardGame playerGo;
playerGo.GameWinner(allPlayers);
cin.get();
system("PAUSE");
return 0;
}
Line 44: you are declaring local variable which hides actual class member.
Same in other methods. In the end, your class member is not used at all. And your comiler should warn you about it.
Ok. I moved my char arrays out locally but when I try and initialize it in my public or private section of my class I get an "data member initializer is not allowed" error in both places and can't run my program anymore.
My compiler only says that it didn't find PDB file or something when I ran it before this recent update. It still ran before but you're right the class member wasn't being used because the X and O wasn't showing up even when I entered the right numbers in my output.
I want to have my char array work so that my BoardView, GameWinner, and spaceCheck class member's can use them.
I did that, I put char box[10] = { 'o','1','2','3','4','5','6','7','8','9' };
in my BoardView, GameWinner, and spaceCheck members instead of that and it does run, but when I type the numbers 1-9 it doesn't change the number inside the box and doesn't seem to work at all. I'll update it.
I have to use a return command in order for the members to see it though right?
No. Constructors does not have a return type and in fact cannot return anything.
i tried to put box[10] as { 'o','1','2','3','4','5','6','7','8','9'; }
What with that semicolon at the end? Also you need either assign values in a loop (as it is already initialized) or initialize box in a member init list: http://ideone.com/41JPPO
My bad, i mean to have the semi-colon after the closing bracket.
But why do I need to assign the values inside the members? Shouldn't the box[10] in the constructor already work since all these members are from the same class? having to go box[1] = '1'; in my members kills the point of my constructor right?
Do I have to get of the members entirely and put them all in one giant class? I think I tried that before though and it made the entire program messy looking.
My code before worked with my box array having that many elements so I'm not worried about that at the moment.
I made my constructor like this:
BoardGame() // default constructor
{
int playerOne;
int allPlayers = 0;
char box[10] = {'o','1','2','3','4','5','6','7','8','9'};
} // end of constructor
inside my BoardGame class with my char box array in my private section.
However it still doesn't link up with my class members. So I tried to put one of my computations in it. It worked with the computations using the char array inside the constructor but it won't take my space check class member because it returns values.
My BoardView class member also doesn't show up in my main at all. I think I messed something up when I moved my GameWinner class member in my constructor.
I think I have to overload my constructor according to this site's tutorial page but I'm not sure how to do it with my code. (Do I name all my members BoardGame? That would seem very hard to read and understand.)
I'll post an updated code in my first post.
Thanks for bearing with me, I am really having a hard game understanding C++. (although I had the same problem with advanced JAVA programs as well.)
char box[10] = {'o','1','2','3','4','5','6','7','8','9'};This is local variable. It has no relation to member one. Do you actually read compiler warnings? Because it should warn you about it.
Use one of the two approach I posted.
You should not have your game logic inside constructor. Constructors should be used only to initialize your object.
list-initializer for non-class type must be parathentisized [enabled by default] so I got rid of my char box[10]; in my class but I STILL get an error saying:
" Board Game does not have any field named 'box' "
I also get in your second BoardGame() constructor with a "cannot be overloaded" error.
// start of BoardGame class
class BoardGame
{
// playerOne data field checks the input used in the choice data field and computates which number and symbol to display in the spaces on the board.
int playerOne;
// choice data field asks user what number to input so it can check the corresponding number in the char array and playerOne/allPlayers data field
int choice;
// checkAction data field that calls the spaceCheck member that computes if there are three spaces that match the same symbol
int checkAction;
public:
// delcares public data fields
void BoardView();
void playerOneAction();
void GameShow();
void GameWinner(int);
int spaceCheck();
//using init list:
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}
//using assigment
BoardGame()
{
box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'}) {}
constchar* tmp = "o123456789";
for (int i = 0; i < 10; ++i)
box[i] = tmp[i];
}
}; // end of BoardGame class
// start of BoardGame class
class BoardGame
{
// playerOne data field checks the input used in the choice data field and computates which number and symbol to display in the spaces on the board.
int playerOne;
// choice data field asks user what number to input so it can check the corresponding number in the char array and playerOne/allPlayers data field
int choice;
// checkAction data field that calls the spaceCheck member that computes if there are three spaces that match the same symbol
int checkAction;
public:
// delcares public data fields
void BoardView();
void playerOneAction();
void GameShow();
void GameWinner(int);
int spaceCheck();
// declaration of member variable
char box[10];
//using init list:
// here I get error: I still get the :
// list-initializer for non-class type must be parathentisized [enabled by default] error
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}
//using assigment
BoardGame()
{
constchar* tmp = "o123456789";
for (int i = 0; i < 10; ++i)
box[i] = tmp[i];
}
}; // end of BoardGame class