Anyone want to look over my Tic-Tac-Toe game for improvements?

I made this last semester for my intro to C++ class. It works great and I got a good grade, but I want to make improvements to it. I really would like to add classes and make it more OO, but I've always had problems with classes. I know the syntax and completed my homework assignments dealing with them, its just a rough spot for me and I know they are EXTREMELY important in C++ programming.

So I was wondering if anyone could take a look at this and give me some ideas on what to improve and maybe even small examples to start me off / get me thinking about what to do. Like I said classes would be nice to add, I just have no idea where to start. But I'm open to any other suggestions as well, not just classes. I want to keep improving this until there's not much left to do with it before I move onto my next project.

Thank you all very much =)

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
//Tic-Tac-Toe Game by Lee J. Robison
//[email protected]  

#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

void printBoard();
void checkMark();
void moveInput();
void checkWin();
void getPlayerInput();
void swapTurns();

char grid[3][3] = {' ',' ',' ',' ',' ',' ',' ',' ',' '};
int playerTurn = 1;
char playerMark;
char replay;
bool isMoveValid;
bool isGameOver;
bool isGameWon = false;

int main() // main loop uses a do while loop and continues until the game is over and the player does not wish to start a new game.
{	
	do
	{
		system("CLS"); //clears the screen
		printBoard();
		checkMark();
		getPlayerInput();
		system("CLS"); //clears the screen
		checkWin();
		swapTurns();
	}while (isGameOver != true);
	
	return 0;
}

void printBoard() //standard function to print the tic tac toe board.
{
	cout << endl;
	cout << setiosflags(ios::right) << setw(3) << "" << "1" << setiosflags(ios::right) << setw(3) << "" << "2" << setw(3) << setiosflags(ios::right) << "3" << setw(3) << "" << endl;
	cout << endl;
	cout << setw(3)<< setiosflags(ios::left) << "1" << setw(2) << grid[0][0] << "|" << setw(2) << grid[0][1] << "|" << setw(2) << grid[0][2] << endl;
	cout << "   " << "--+--+--"<< endl;
	cout << setw(3) << setiosflags(ios::left) << "2" << setw(2) << grid[1][0] << "|" << setw(2) << grid[1][1] << "|" << setw(2) << grid[1][2] << endl;
	cout << "   " << "--+--+--"<< endl;
	cout << setw(3) << setiosflags(ios::left) << "3" << setw(2) << grid[2][0] << "|" << setw(2) << grid[2][1] << "|" << setw(2) << grid[2][2] << endl;
	cout << endl;
}

void checkMark() // set the mark the player will be using on the board by which player's turn it is.
{
	if (playerTurn == 1) 
			playerMark = 'X';
	else
			playerMark = 'O';
}

void getPlayerInput()
{
	int x, y;
	cout << "\nPlayer " << playerTurn << "'s turn" << endl;
		
	// Ask player for his move.
	cout << "Enter x-coordinate for your move: ";
	cin >> x;
	cout << "Enter y-coordinate for your move: ";
	cin >> y;

	//subtract 1 from x and y values to allow the values to work with an array.
	x = x - 1;
	y = y - 1;


	// Check the move to see if its valid. If not, recall the function.
			
	if (grid[y][x] == ' ') // if move is valid.. (note: it is grid[y][x] because I needed to flip the axis.
		grid[y][x] = playerMark; //change the value of the array to the players mark (X or O).

	else 
	{
		cout << "Invalid input. (Either the spot you entered was taken or was an invalid number)" << endl;
		system("PAUSE"); //add a pause in so the user can see his/her mistake.
		system("CLS"); //clear the screen.
		printBoard();
		getPlayerInput();
	}

}
void checkWin()
{
	//check all possible combinations for winning using if statements
		if (grid[0][0] != ' ') 
		{
			if (grid[0][1] == grid[0][0] && grid[0][2] == grid[0][0])
			{
				isGameOver = true;
				isGameWon = true;
			}
	
			if (grid[1][0] == grid[0][0] && grid[2][0] == grid[0][0])
			{
				isGameOver = true;
				isGameWon = true;
			}

		}

		if (grid[1][1] != ' ') 
		{
			if (grid[0][0] == grid[1][1] && grid[2][2] == grid[1][1])
			{
				isGameOver = true;
				isGameWon = true;
			}

			if (grid[0][1] == grid[1][1] && grid[2][1] == grid[1][1])
			{
				isGameOver = true;
				isGameWon = true;
			}
				
			if (grid[1][0] == grid[1][1] && grid[1][2] == grid[1][1])
			{
				isGameOver = true;
				isGameWon = true;
			}

			if (grid[0][2] == grid[1][1] && grid[2][0] == grid[1][1])
			{
				isGameOver = true;
				isGameWon = true;
			}
		
		}
		
		if (grid[2][2] != ' ') 
		{
			if (grid[0][2] == grid[2][2] && grid[1][2] == grid[2][2])
			{
				isGameOver = true;
				isGameWon = true;
			}
	
			if (grid[2][0] == grid[2][2] && grid[2][1] == grid[2][2]) 
			{
				isGameOver = true;
				isGameWon = true;
			}
				
		}
		// Check the board for a draw (full board has X or O and Game is Over)
		if (grid[0][0] != ' ' && grid[0][1] != ' ' && grid[0][2] != ' ' &&
			grid[1][0] != ' ' && grid[1][1] != ' ' && grid[1][2] != ' ' &&
			grid[2][0] != ' ' && grid[2][1] != ' ' && grid[2][2] != ' ' && isGameOver == false)
		{
			isGameOver = true;
			isGameWon = false;
		}
		//Display Win/Draw Message and ask for New Game
		if (isGameOver == true) 
		{
			printBoard();

			if (isGameWon == false)
			{
				cout << "Tie game! Too bad.";
			}

			if (isGameWon)
			cout << "\nCongratulations Player " << playerTurn << ". You won!" << endl;

			cout << "\nGame Over." << endl;
			cout << "Do you wish to play again? (y/n)" << endl;
			cin >> replay;

			if (replay == 'y' || replay  == 'Y')
			{
				isGameOver = false;
				grid[0][0] = ' ';
				grid[0][1] = ' ';
				grid[0][2] = ' ';
				grid[1][0] = ' ';
				grid[1][1] = ' ';
				grid[1][2] = ' ';
				grid[2][0] = ' ';
				grid[2][1] = ' ';
				grid[2][2] = ' ';
			}
			
			else
			{
				system("CLS"); // clear the screen
				cout << "Thanks for playing!" << endl;
				isGameOver = true;
			}

			swapTurns();
		}
}

void swapTurns() //Switches the playerTurn variable which also changes the playerMark variable in the next loop.
{
	if (playerTurn == 1)
		playerTurn = 2;
	else 
		playerTurn = 1;
}
Well if you'd like a real challenge, you could go read a tutorial on graphical programming and make a form application for it or take it to the next level and program it in Allegro or OpenGL.
That's way beyond OP's level of expertise given the original request.

Here are some ideas:

1) Make a class named "Grid" that encapsulates the playing board. Before you even start, think about what functions might Grid have.

2) Make a class named "Player" that encapsulates one of the two players. What member functions might Player have?

2a) Make the computer play by modifying Player to support a computer player. Don't worry too much about the computer logic;
having it move randomly (but legally) is sufficient for now.

2b) Once you've finished (2a), make Player an abstract base class, then create two derived classes: "Human" and "Computer".

2c) Make the computer play with optimal strategy.

3) Your checkWin() function is quite long because you had to write lines of code for each different way you could win. Consider
using a data-driven implementation that allows you to reduce the function body to a for() loop with a single if() inside it. Can you
think of how to do this?

4) Now take everything you did above and make a Connect Four game instead. Here's where you'll really reap the benefits of
(3), even though you'll have to change the function a bit, because there are quite a number of ways to win in Connect Four.
Topic archived. No new replies allowed.