Help with project

Hi folks,

Browsed this forum for a while, been a member but don't post, but I need some help with a project of mine.

I have been learning C++ off and on for several years now, and get tired of reading up on tutorials on stuff that I already know about, so I figured it's time to actually put my knowledge of the language to use and figure out myself how it works instead of reading how it works, and I'm starting by creating Tic-Tac toe for console. When I started yesterday, I was able to have a one player game and find a winner when the user reaches 3 in a row.

I was able to turn the game into a two player game with 'X' and 'O' values. The game can input and output the locations of the user input. Here's my problem though - I cannot for the life of me figure out how to end the game when an 'X' or an 'O' reaches 3 in a row. It was simpler to do it with 1 player. I have a variable called "result" that defaults to -1, and if a winning combination was found, return 1 for player1, or return 2 if player2 wins, but for whatever reason the compiler is always returning -1. I have a suspicion it's because I have result default to -1 but I tried changing that to 0 and NULL but that didn't work either.

I would appreciate any help out. Will post code shortly. It would be nice to not be given the answer, just an idea of what I need to be doing.
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
#include <iostream>
using std::cout;
using std::cin;

void DrawBoard(char tiles[]);
int findWinner(char tiles[]);
enum state {CHOOSEPLAYER, DRAWBOARD, INPUT, FINDWINNER, ENDGAME};

int main()
{

	char tiles[10] = { '0','1','2','3','4','5','6','7','8','9' };
	char player1 = NULL;
	char player2 = NULL;
	int result = -1;
	int playerMove = 1;
	int stateOfGame = CHOOSEPLAYER;

	while (true)
	{
		switch (stateOfGame)
		{

			case CHOOSEPLAYER:
			{
				int chooseplayer;
				cout << "Choose who goes first:\n";
				cin >> chooseplayer;
	
				if (chooseplayer == 1)
				{
					player1 = 'X';
					player2 = 'O';
	
				}
	
				else
				{
					player1 = 'O';
					player2 = 'X';
	
				}
	
				stateOfGame = DRAWBOARD;
				break;
			}
	
			case DRAWBOARD:
			{
				DrawBoard(tiles);
				stateOfGame = INPUT;
				break;
			}
	
			case INPUT:
			{
				if (playerMove == 1)
				{
					int nextMove;
					cout << "Player1 Enter Move: ";
					cin >> nextMove;
					tiles[nextMove] = player1;
					playerMove++;
				}
	
				else if (playerMove == 2)
				{
					int nextMove2;
					cout << "Player2 Enter Move: ";
					cin >> nextMove2;
					tiles[nextMove2] = player2;
					playerMove--;
				}
	
				DrawBoard(tiles);
				stateOfGame = FINDWINNER;
				break;
			}
	
			case FINDWINNER:
			{
				result = findWinner(tiles);
	
				if (result != -1)
					stateOfGame = ENDGAME;
				else
					stateOfGame = INPUT;
				break;
			}
	
			case ENDGAME:
			{
				if (result == 1)
				{
	
					cout << "Player1 Wins!";
				}
				else if (result == 2)
				{
	
					cout << "Player1 Wins!";
				}
			}

		}
	}
		
	cin.ignore();
	return 0;
}

void DrawBoard(char tiles[])
{
	system("cls");
	cout << "\n\n";

	cout << "     " << tiles[1] << "    |" << "     " << tiles[2] << "    |" << "     " << tiles[3] << "    \n";
	cout << "          |          |          \n";
	cout << "----------|----------|----------\n";

	cout << "     " << tiles[4] << "    |" << "     " << tiles[5] << "    |" << "     " << tiles[6] << "    \n";
	cout << "          |          |          \n";
	cout << "----------|----------|----------\n";
	cout << "     " << tiles[7] << "    |" << "     " << tiles[8] << "    |" << "     " << tiles[9] << "    \n";
	cout << "          |          |          \n";

	cout << " \n\n";
}

int findWinner(char tiles[])
{
	int success = -1;

	//Player1
	if (tiles[1] == 'X' && tiles[2] == 'X' && tiles[3] == 'X')
	{
		success = 1;
	}
	else if (tiles[4] == 'X' && tiles[5] == 'X' && tiles[6] == 'X')
	{
		success = 1;
	}

	else if (tiles[7] == 'X' && tiles[8] == 'X' && tiles[9] == 'X')
	{
		success = 1;
	}

	else if (tiles[1] == 'X' && tiles[3] == 'X' && tiles[5] == 'X')
	{
		success = 1;
	}

	else if (tiles[2] == 'X' && tiles[4] == 'X' && tiles[6] == 'X')
	{
		success = 1;
	}

	else if (tiles[3] == 'X' && tiles[6] == 'X' && tiles[9] == 'X')
	{
		success = 1;
	}

	else if (tiles[1] == 'X' && tiles[5] == 'X' && tiles[5] == 'X')
	{
		success = 1;
	}

	//Player 2
	if (tiles[1] == 'O' && tiles[2] == 'O' && tiles[3] == 'O')
	{
		success = 2;
	}
	else if (tiles[4] == 'O' && tiles[5] == 'O' && tiles[6] == 'O')
	{
		success = 2;
	}

	else if (tiles[7] == 'O' && tiles[8] == '0' && tiles[9] == 'O')
	{
		success = 2;
	}

	else if (tiles[1] == 'O' && tiles[3] == 'O' && tiles[5] == 'O')
	{
		success = 2;
	}

	else if (tiles[2] == 'O' && tiles[4] == 'O' && tiles[6] == 'O')
	{
		success = 2;
	}

	else if (tiles[3] == 'O' && tiles[6] == 'O' && tiles[9] == 'O')
	{
		success = 2;
	}

	else if (tiles[1] == 'O' && tiles[5] == 'O' && tiles[5] == 'O')
	{
		success = 2;
	}
		
	return success;
}


Feel free to comment, edit, critique my code and give me ideas on how to improve it.

Thanks!
Last edited on
Well as it turns out I had the wrong combinations which explains why the game wouldn't figure out correctly who the winner is. That answers the first question.

Now, my next question is, When I print out who wins, cout << "Player1 wins" prints out infinitely. Not sure what's going on. Here's my updated code:
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
#include <iostream>
using std::cout;
using std::cin;

void DrawBoard(char tiles[]);
int findWinner(char tiles[]);
enum state {CHOOSEPLAYER, DRAWBOARD, INPUT, FINDWINNER, ENDGAME};

int main()
{

	char tiles[10] = { '0','1','2','3','4','5','6','7','8','9' };
	char player1 = NULL;
	char player2 = NULL;
	int result = -1;
	int playerMove = 1;
	int stateOfGame = CHOOSEPLAYER;

	while (true)
	{
		switch (stateOfGame)
		{

			case CHOOSEPLAYER:
			{
				int chooseplayer;
				cout << "Choose who goes first:\n";
				cin >> chooseplayer;
	
				if (chooseplayer == 1)
				{
					player1 = 'X';
					player2 = 'O';	
				}
	
				else
				{
					player1 = 'O';
					player2 = 'X';	
				}
	
				stateOfGame = DRAWBOARD;
				break;
			}
	
			case DRAWBOARD:
			{
				DrawBoard(tiles);
				stateOfGame = INPUT;
				break;
			}
	
			case INPUT:
			{
				if (playerMove == 1)
				{
					int nextMove;
					cout << "Player1 Enter Move: ";
					cin >> nextMove;
					tiles[nextMove] = player1;
					playerMove++;
				}
	
				else if (playerMove == 2)
				{
					int nextMove2;
					cout << "Player2 Enter Move: ";
					cin >> nextMove2;
					tiles[nextMove2] = player2;
					playerMove--;
				}
	
				DrawBoard(tiles);
				stateOfGame = FINDWINNER;
				break;
			}
	
			case FINDWINNER:
			{
				result = findWinner(tiles);
	
				if (result != -1)
					stateOfGame = ENDGAME;
				else
					stateOfGame = INPUT;
				break;
			}
	
			case ENDGAME:
			{
				if (result == 1)
				{	
					cout << "Player1 Wins!";
				}
				else if (result == 2)
				{	
					cout << "Player2 Wins!";
				}
				break;
			}

		}
	}
		
	cin.ignore();
	return 0;
}

void DrawBoard(char tiles[])
{
	system("cls");
	cout << "\n\n";

	cout << "     " << tiles[1] << "    |" << "     " << tiles[2] << "    |" << "     " << tiles[3] << "    \n";
	cout << "          |          |          \n";
	cout << "----------|----------|----------\n";
	cout << "     " << tiles[4] << "    |" << "     " << tiles[5] << "    |" << "     " << tiles[6] << "    \n";
	cout << "          |          |          \n";
	cout << "----------|----------|----------\n";
	cout << "     " << tiles[7] << "    |" << "     " << tiles[8] << "    |" << "     " << tiles[9] << "    \n";
	cout << "          |          |          \n";

	cout << " \n\n";
}

int findWinner(char tiles[])
{
	int success = -1;

	//Player1
	if (tiles[1] == 'X' && tiles[2] == 'X' && tiles[3] == 'X')
	{
		success = 1;
	}
	
	else if (tiles[4] == 'X' && tiles[5] == 'X' && tiles[6] == 'X')
	{
		success = 1;
	}

	else if (tiles[7] == 'X' && tiles[8] == 'X' && tiles[9] == 'X')
	{
		success = 1;
	}

	else if (tiles[1] == 'X' && tiles[4] == 'X' && tiles[7] == 'X')
	{
		success = 1;
	}

	else if (tiles[2] == 'X' && tiles[5] == 'X' && tiles[8] == 'X')
	{
		success = 1;
	}

	else if (tiles[3] == 'X' && tiles[6] == 'X' && tiles[9] == 'X')
	{
		success = 1;
	}

	else if (tiles[1] == 'X' && tiles[5] == 'X' && tiles[9] == 'X')
	{
		success = 1;
	}

	else if (tiles[3] == 'X' && tiles[5] == 'X' && tiles[7] == 'X')
	{
		success = 1;
	}

	// Player 2

	if (tiles[1] == 'O' && tiles[2] == 'O' && tiles[3] == 'O')
	{
		success = 2;
	}

	else if (tiles[4] == 'O' && tiles[5] == 'O' && tiles[6] == 'O')
	{
		success = 2;
	}

	else if (tiles[7] == 'O' && tiles[8] == 'O' && tiles[9] == 'O')
	{
		success = 2;
	}

	else if (tiles[1] == 'O' && tiles[4] == 'O' && tiles[7] == 'O')
	{
		success = 2;
	}

	else if (tiles[2] == 'O' && tiles[5] == 'O' && tiles[8] == 'O')
	{
		success = 2;
	}

	else if (tiles[3] == 'O' && tiles[6] == 'O' && tiles[9] == 'O')
	{
		success = 2;
	}

	else if (tiles[1] == 'O' && tiles[5] == 'O' && tiles[9] == 'O')
	{
		success = 2;
	}

	else if (tiles[3] == 'O' && tiles[5] == 'O' && tiles[7] == 'O')
	{
		success = 2;
	}

	
		
	return success;
}


edit: Also realizing that my char[] array of spaces don't reset for a new game since I do not have code to do it... How would I do that?

edit2: am now realizing that I can't use brackets around initializers if I intend to reset them again in the future, so that solves that problem. But I still would like to let the program sleep for a few seconds to display who won the previous game before starting a new game. Is that possible?
Last edited on
why u set your result to -1?
When I print out who wins, cout << "Player1 wins" prints out infinitely

At that point the code that executes is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while (true)
	{
		switch (stateOfGame)
		{
		...
		case ENDGAME:
			{
				if (result == 1)
				{	
					cout << "Player1 Wins!";
				}
				else if (result == 2)
				{	
					cout << "Player2 Wins!";
				}
				break;
			}
		}
	}

So since stateOfGame never changes, it just keeps executing that part of the code.

I'd get rid of stateOfGame altogether. Almost every state simply causes the next state to execute. Instead, you could structure the code like this: I've used function calls to indicate the functionality, but you will probably just write the code inline:
1
2
3
4
5
6
7
choosePlayer()
while (!winner) {
	drawBoard();
	input();
	winner = findWinner();
}
endGame();

I would have findWinner() return a char: either 0, 'X' or 'O'. You don't need to check for X and O separately, this code checks to see if someone has won in the top row and returns the winner if so:
1
2
3
if (tiles[1] == tiles[2] && tiles[2] == tiles[3]) {
	return tiles[1];	// return 'X' or 'O'
}


If you put that in a loop, you can check each row.
A similar look can check each column.
That leaves just two special cases for the diagonals. Your entire findWinner() function should be less than 30 lines of code.
-1 is the default result to keep asking for user input. If Player1 wins, or Player2 wins, result will be either 1, or 2, but will return -1 if a winner has not been chosen.

Also of note, I need to write code to process draw results. But I think I can figure out how to do that...

And thanks for the advice, dhayden. I'll see what I can do.
I've got it to be able to check each tile properly now.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
char findWinner(char tiles[])
{
	if (tiles[1] == tiles[2] && tiles[2] == tiles[3])
		return tiles[1];	
	else if (tiles[4] == tiles[5] && tiles[5] == tiles[6])
		return tiles[4];
	else if (tiles[7] == tiles[8] && tiles[8] == tiles[9])
		return tiles[7];
	else if (tiles[1] == tiles[4] && tiles[4] == tiles[7])
		return tiles[1];
	else if (tiles[2] == tiles[5] && tiles[5] == tiles[8])
		return tiles[7];
	else if (tiles[3] == tiles[6] && tiles[6] == tiles[9])
		return tiles[7];
	else if (tiles[1] == tiles[5] && tiles[5] == tiles[9])
		return tiles[7];
	else if (tiles[3] == tiles[5] && tiles[5] == tiles[7])
		return tiles[7];
	else return 0;
}


Any chance I could get a starter loop? Quite stumped how to loop each row/column.
Last edited on
1
2
3
4
5
6
7
8
9
char
findWinner(char tiles[])
{
    for (size_t i = 1; i <= 7; i += 3) {
        if (tiles[i] == tiles[i+1] && tiles[i+1] == tiles[i+2]) {
            return tiles[i];
        }
    }
}

Topic archived. No new replies allowed.