Using a char arrays that change inside class members

Pages: 12
EDITED and UPDATED On Sept 27 at 2PM

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.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

#include <iostream>	
#include <string>

using namespace 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;
	else if (box[4] == box[5] && box[5] == box[6])

		return 1;
	else if (box[7] == box[8] && box[8] == box[9])

		return 1;
	else if (box[1] == box[4] && box[4] == box[7])

		return 1;
	else if (box[2] == box[5] && box[5] == box[8])

		return 1;
	else if (box[3] == box[6] && box[6] == box[9])

		return 1;
	else if (box[1] == box[5] && box[5] == box[9])

		return 1;
	else if (box[3] == box[5] && box[5] == box[7])

		return 1;
	else if (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;
	else
		return -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;
		else if (choice == 2 && box[2] == '2')

			box[2] = space;
		else if (choice == 3 && box[3] == '3')

			box[3] = space;
		else if (choice == 4 && box[4] == '4')

			box[4] = space;
		else if (choice == 5 && box[5] == '5')

			box[5] = space;
		else if (choice == 6 && box[6] == '6')

			box[6] = space;
		else if (choice == 7 && box[7] == '7')

			box[7] = space;
		else if (choice == 8 && box[8] == '8')

			box[8] = space;
		else if (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;
}
Last edited on
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.
Last edited on
You have to initialise your data members in constructor
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 put char box[10] = { 'o','1','2','3','4','5','6','7','8','9' };

in my BoardView, GameWinner, and spaceCheck members
You are creating local variables inside methods which shadows member one. You need to initialize member variable in constructor

http://www.learncpp.com/cpp-tutorial/85-constructors/
http://www.cplusplus.com/doc/tutorial/classes/
http://www.cplusplus.com/doc/tutorial/classes2/
Last edited on
I'm dumb, I didn't make a constructor.

Ok I made a default constructor and it's:

BoardGame() // default constructor
{

box[10] = 'o','1','2','3','4','5','6','7','8','9';
}

I have to use a return command in order for the members to see it though right?

because when i tried to put box[10] as { 'o','1','2','3','4','5','6','7','8','9'; } with brackets it gave me an " expected an expression " error.
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
Last edited on
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.
box[10] is the 11th element of array containing 10 elements.

When you get to the body of the constructor, elements are already initialized. In short it looks like:
1
2
3
4
5
//Cannot change anythig here
char box[10];

//Add your code here
???
As you cannot assign whole array in normal code, you cannot do that in the body of the constructor.

TO solve that there is constructor initializer list. In my previous post I posted a link with example of how to use that.
1
2
3
4
5
6
7
8
9
10
11
//using init list:
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}

//using assigment
BoardGame()
{
    const char* tmp = "o123456789";
    for (int i = 0; i < 10; ++i)
        box[i] = tmp[i];
}
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.
I use Visual C++ program and I don't see a compiler list. I'll try using c++ shell.

Ok I tried your code and have some errors:

It says:
 
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})


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.

This is my current BoardGame class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 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'}) {}
		const char* tmp = "o123456789";
		for (int i = 0; i < 10; ++i)
        box[i] = tmp[i];
		}
	
		
	

}; // end of BoardGame class 
Last edited on
Line 33: where did that line come from? It wasnt in any of my examples.

Why did you deleted box from member list? It was fine here.
1
2
3
4
5
6
7
class foo
{
    char box[2]; //Declaration of member variable

    foo() : box({'a', 'b'}) //Initialization in constructor
    {}
}
Oops sorry was trying to edit to different copies of this program in different programs and much have got them mixed up.

Ok here is my class but I still get the error, even with char box in there. Are my public and private objects (or whatever its called0 messing it up?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// 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()
    {
    const char* tmp = "o123456789";
    for (int i = 0; i < 10; ++i)
        box[i] = tmp[i];
}
	

}; // end of BoardGame class 
Last edited on
Which errors do you get? (And I hope you do not have 2 default constructor at once.)
I'll re-submit my entire code on my first post.

That's the error I'm getting when I use C++ shell which is used to edit code on this website. You don't get this error when you use that?

Why do you have 2 constructors? Select one and use it.


1
2
3
4
5
6
7
8
9
10
11
//using init list:
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}

//using assigment
BoardGame()
{
    const char* tmp = "o123456789";
    for (int i = 0; i < 10; ++i)
        box[i] = tmp[i];
}


Oh you meant chose one of these or the other? Haha I was using both.

Ok just using the

1
2
3
//using init list:
BoardGame() : box({'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
{}


Hm although when I type 1 I still get no change to X or O.
1
2
		BoardGame currentBoard;
		currentBoard.GameShow();
Here you are creating new empty board and trying to show it. Call GameShow on current board:

GameShow(); //You do not need anything else
Pages: 12