TicTacToe

hi all, just finished tictactoe practice program and i would love to hear what you guyz think i could do to improve the code, also somehow it looks to me like this is a hell lot of code lines for a game as simple as tictactoe, is this amount of code lines normal? BTW, these series of beginner excercises, once one finishes them what does that mean for a rookie for me, is it good progress if i'm able to write all this programs in first 3 mounths of learning c++? Got one more left to do, Dungeon Crawl.

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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include <iostream>
#include <ctime>
using namespace std;

void displayXOBoard(char myArray[]); //used to print XOBoard on screen
void switchPlayerMark(char &p, int &f); //used to switch player mark
char writeToXOBoard(char myArray[], int a, char x); //used to write the player mark to player specified XOBoard field
void scanXOBoard(char myArray[], int &z, int &x); //used to scan XOBoard to see if there's a winner, if yes then end the main loop
void aboutToWin(char myArray[], int &X, int &choice); //Computer player AI - attempt to win before player or try to prevent player to win


int main()
{
	int X = 0; //used to condition the computer main loop and to internally count how many X marks are there in lines in AI function
	srand(time(0)); //generate "truly" random number
	char XOBoard[9] = {'1','2','3','4','5','6','7','8','9'}; //XO board fields
	char player = 'X'; //player marks
	int fieldsLeft = 9; //used to store number of fields left on XO board
	int choice; //players input
	int win = 0; // used to determine a win state

	//welcome and players legend message
	cout << "XO game by IronMan!" << endl;
	cout << "Player (X), Computer (O)!" << endl;

	//show XOboard
	displayXOBoard(XOBoard);

	do
	{
		///PLAYER ACTION///
		//ask for user input
		cout << "Player " << player << ":";
		cin >> choice;

		//if player choice is valid(1-9) do this
		if(choice >= 1 && choice <= 9)
		{
			//if field is available do this and then switch player mark
			if(XOBoard[(choice-1)] != 'X' && XOBoard[(choice-1)] != 'O')
			{
				fieldsLeft--;

				//player has played his turn
				writeToXOBoard(XOBoard, choice, player);

				scanXOBoard(XOBoard, fieldsLeft, win);

				//switch player mark
				switchPlayerMark(player, fieldsLeft);

			}
			//else, field is already taken notify player
			else
			{
				cout << "That field is already taken,\ntry another one!" << endl;
			}

		}
		//else, player choice wasn't valid notify user
		else
		{
			cout << "Invalid input, try again!" << endl;
		}
		///END OF PLAYER ACTION///




		///COMPUTER ACTION///
		if(player != 'X')
		{
			cout << "Computer " << player << ":";

			//if computer is about to win than make a mark to achieve victory, else if player is about to win, neutralize it
			aboutToWin(XOBoard, X, choice);

			//if X is greater than 1 it means aboutToWin function was successful, proceed with AI move
			if(X > 1)
			{
				fieldsLeft--;
				cout << choice;

				//computer player has played his turn
				writeToXOBoard(XOBoard, choice, player);

				scanXOBoard(XOBoard, fieldsLeft, win);

				//switch player mark
				switchPlayerMark(player, fieldsLeft);

			}

			//if X is zero then aboutToWin function didn't find any threat or opportunity, instead do random mark on board
			if(X == 0)
			{
				//generate random number for field choice
				int computerChoice = 1 + (rand()%9);
				choice = computerChoice;

				//if the field which computer chose is available then do this and then switch player mark
				if(XOBoard[(choice-1)] != 'X' && XOBoard[(choice-1)] != 'O')
				{
					cout << choice;
					fieldsLeft--;
					writeToXOBoard(XOBoard, choice, player);
					scanXOBoard(XOBoard, fieldsLeft, win);

					//switch player mark
					switchPlayerMark(player, fieldsLeft);
				}

				//else if the field which computer picked is already taken then do this
				else
				{
					//scan the XOBoard and when you find empty field put the computer player mark,
					//end the search and switch player mark
					for(int x = 0; x < 9; x++)
					{
						//if field is empty do this
						if(XOBoard[x] != 'X' && XOBoard[x] != 'O')
						{
							fieldsLeft--;
							choice = (x+1);
							cout << choice;

							//computer player has played his turn
							writeToXOBoard(XOBoard, choice, player);

							scanXOBoard(XOBoard, fieldsLeft, win);

							//end the for loop
							x = 8;

							//switch player mark
							switchPlayerMark(player, fieldsLeft);

						}
					}
				}

			}
		}
		///END OF COMPUTER ACTION///

		displayXOBoard(XOBoard);
	}
	while(fieldsLeft > 0);


	//if there is a winner, show the winner
	if(win == 1 )
	{
		if(player == 'X')
		{
			cout << "Player wins!" << endl;
		}
		else
		{
			cout << "Computer wins!" << endl;
		}
	}

	//if there is no field left and there is no winner then game over
	else if(fieldsLeft == 0 && win == 0)
	{
		cout << "No fields left, Game Over" << endl;
	}

}


//print XOBoard on screen
void displayXOBoard(char myArray[])
{
	cout << endl << "____________" << endl;
	for(int x = 0; x < 9; x += 3)
	{
		cout << " " << myArray[x] << " | " << myArray[(x+1)] << " | " << myArray[(x+2)] << endl;

		if (x != 6)
		{
				cout << "-----------" << endl;
		}

	}
	cout << "____________" << endl;
}

//used to switch player mark
void switchPlayerMark(char &p, int &f)
{
	if(p == 'X' && f != 0)
	{
		p = 'O';
	}
	else if(p == 'O' && f != 0)
	{
		p = 'X';
	}
}

//used to write the player mark to player specified XOBoard field
char writeToXOBoard(char myArray[], int a, char x)
{
	return myArray[(a-1)] = x;
}

//scan XOBoard array to see if there is a winner or not
//if there is, then change the value of FieldsLeft and Win variable to end the main loop and to skip no fields left message
void scanXOBoard(char myArray[], int &z, int &w)
{
	//scan array for winner condition
	for(int x = 0; x < 1; x++)
	{
		//check right diagonal
		if(myArray[(x+2)] == myArray[(x+4)] && myArray[(x+4)] == myArray[(x+6)])
		{
			z = 0;
			w = 1;
		}

		//check left diagonal
		else if(myArray[x] == myArray[(x+4)] && myArray[(x+4)] == myArray[(x+8)])
		{
			z = 0;
			w = 1;
		}

		for(int a = 0; a < 9; a +=3)
		{
			//check all horizontal fields
			if(myArray[a] == myArray[(a+1)] && myArray[(a+1)] == myArray[(a+2)])
			{
				z = 0;
				w = 1;
			}

			//check all vertical fields
			if(myArray[(a/3)] == myArray[((a/3)+3)] && myArray[((a/3)+3)] == myArray[((a/3)+6)])
			{
				z = 0;
				w = 1;
			}

		}
	}
}
Last edited on
and one more function

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
//Computer player AI, if computer has 2 O's then prefer making a third to win instead preventing player to make a third X in line,
//else if player is about to win, i.e 2 X's in line put O to prevent him
void aboutToWin(char myArray[], int &X, int &choice)
{
	int z = 0; //used to count how many fields are occupied with O
	int b = 0; //used to pass an empty field id to computer choice
	choice = 0;
	X = 0; //used to count how many fields are occupied with X

	//if X, z and choice equal zero then also check left diagonal field ( 1, 5, 9)
	if(X == 0 && z == 0 && choice == 0)
	{
		for(int x = 0; x < 1; x ++)
		{
			for(int c = 0; c < 9; c += 4)
			{
				if(myArray[(x+c)] == 'X') //if you find X, add 1 to X variable
				{
					X++;
				}

				else if(myArray[(x+c)] == 'O') //if you find O, add 1 to z variable
				{
					z++;
				}

				else //if field is empty memorize the field id and store in in b variable
				{
					b = (x+c);
				}
			}

			if(X == 2 && z == 0) //if there is 2 X's and none O's then write O to prevent player win
			{
				choice = (b+1);
				x = 8; //stop the main for loop
			}

			else if(X == 0 && z == 2) //else if there is 2 O's and 3rd field is empty in the row, write O to make computer win
			{
				choice = (b+1);
				x = 8; //stop the main for loop
			}

			//if no criteria has been fulfilled then reset all variables to 0
			else
			{
				b = 0;
				z = 0;
				X = 0;
				choice = 0;
			}
		}
	}

	//if X, z and choice equal zero then also check right diagonal field (3, 5, 7)
	if(X == 0 && z == 0 && choice == 0)
	{
		for(int x = 0; x < 1; x++)
		{
			for(int c = 2; c < 7; c += 2)
			{
				if(myArray[(x+c)] == 'X') //if you find X, add 1 to X variable
				{
					X++;
				}

				else if(myArray[(x+c)] == 'O') //if you find O, add 1 to z variable
				{
					z++;
				}

				else //if field is empty memorize the field id and store in in b variable
				{
					b = (x+c);
				}
			}

			if(X == 2 && z == 0) //if there is 2 X's and none O's then write O to prevent player win
			{
				choice = (b+1);
				x = 8; //stop the main for loop

			}

			else if(X == 0 && z == 2) //else if there is 2 O's and 3rd field is empty in the row, write O to make computer win
			{
				choice = (b+1);
				x = 8; //stop the main for loop
			}

			//if no criteria has been fulfilled then reset all variables to 0
			else
			{
				b = 0;
				z = 0;
				X = 0;
				choice = 0;
			}
		}
	}

	//if X, z and choice equal zero then also check all horizontal fields (1, 2, 3), (4, 5, 6), (7, 8, 9)
	if(X == 0 && z == 0 && choice == 0)
	{
		for(int a = 0; a < 10; a +=3)
		{
			for(int x = 0; x < 3; x++)
			{
				if(myArray[(x+a)] == 'X') //if you find X, add 1 to X variable
				{
				X++;
				}

				else if(myArray[(x+a)] == 'O') //if you find O, add 1 to z variable
				{
					z++;
				}

				else //if field is empty memorize the field id and store in in b variable
				{
					b = (x+a);
				}
			}

			if(X == 2 && z == 0) //if there is 2 X's and none O's then write O to prevent player win
			{
				choice = (b+1);
				a = 9; //stop the main for loop
			}

			else if(X == 0 && z == 2) //else if there is 2 O's and 3rd field is empty in the row, write O to make computer win
			{
				choice = (b+1);
				a = 9; //stop the main for loop
			}

			//if no criteria has been fulfilled then reset all variables to 0
			else
			{
				b = 0;
				z = 0;
				X = 0;
				choice = 0;
			}
		}
	}

	//if X, z and choice equal zero then also check all vertical columns fields (1, 4, 7), (2, 5, 8), (3, 6, 9)
	if(X == 0 && z == 0 && choice == 0)
	{
		for(int x = 0; x < 3; x ++)
		{
			for(int c = 0; c < 9; c += 3)
			{
				if(myArray[(x+c)] == 'X') //if you find X, add 1 to X variable
				{
					X++;
				}

				else if(myArray[(x+c)] == 'O') //if you find O, add 1 to z variable
				{
					z++;
				}

				else //if field is empty memorize the field id and store in in b variable
				{
					b = (x+c);
				}
			}

			if(X == 2 && z == 0) //if there is 2 X's and none O's then write O to prevent player win
			{
				choice = (b+1);
				x = 2; //stop the main for loop
			}

			else if(X == 0 && z == 2) //else if there is 2 O's and 3rd field is empty in the row, write O to make computer win
			{
				choice = b
				x = 2; //stop the main for loop
			}

			//if no criteria has been fulfilled then reset all variables to 0
			else
			{
				b = 0;
				z = 0;
				X = 0;
				choice = 0;
			}
		}
	}
}
Last edited on
Maybe, and just maybe, you should think board as integer array (which is initialized as 0's) so checking if there is mark.
1
2
if (board[row][col]) //board place occupied
{} //do stuff or not  
Yeah, it would make it a lot more readable, will try and implement it.
btw does it usually really takes so many lines in programing for souch a little program. In console program that is.

much abliged
Topic archived. No new replies allowed.