Tic-Tac-Toe: Validating whether position has already been taken!

I am trying to make the player have to try to select a position again if a spot has already been occupied previously by Player 1 or Player 2. I am not sure why this little class member function I made will not work. What the program does when it runs is that it allows Player 1 (when you select Player 1 to be (X)) to select the first position, then no matter what Player 2 selects it will keep looping and outputting for the user to try again...

If the vector element locations store anything else (such as X or O) it should return true back to main() and start the validation loop to prompt the user to pick a different spot.

Even if all except for one element location have numbers, it still acts as if these spots are already occupied with an X or O.

The class member function I am referring to is bool Game::CheckPosition()
Please help.

Thanks,
MisterTams

Here is the full .cpp file

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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#include <iostream>
#include "Game.h"
using namespace std;

//function prototype
void titleFormatting();
void SetGameColor();
int SetPlayerXorO();
void ClearScreen();

int main()
{
	int PlayerXorO;
	bool GameOver = false;
	bool IsItOccupied;
	int Position;

	//function calls
	titleFormatting();
	SetGameColor();
	titleFormatting();
	PlayerXorO = SetPlayerXorO();

	Game TicTacToe(PlayerXorO); //create NewGame object
	
	if (PlayerXorO == 1)
	{
		while (GameOver != true)
		{
			TicTacToe.ShowGameBoard();
			Position = TicTacToe.Player1Xselection();
			IsItOccupied = TicTacToe.CheckPosition();

			while (IsItOccupied == true)
			{
				cout << "This spot has already been chosen!" << endl;
				cout << "Please try again!" << endl;
				Position = TicTacToe.Player1Xselection();
				IsItOccupied = TicTacToe.CheckPosition();
			}

			TicTacToe.setLocationX();
			GameOver = TicTacToe.CheckForWinner();
			ClearScreen();

			TicTacToe.ShowGameBoard();
			Position = TicTacToe.Player2Oselection();
			IsItOccupied = TicTacToe.CheckPosition();

			while (IsItOccupied == true)
			{
				cout << "This spot has already been chosen!" << endl;
				cout << "Please try again!" << endl;
				Position = TicTacToe.Player2Oselection();
				IsItOccupied = TicTacToe.CheckPosition();
			}

			TicTacToe.setLocationO();
			GameOver = TicTacToe.CheckForWinner();

			ClearScreen();
		}

	}
	else if (PlayerXorO == 2)
		cout << endl;
	
	system("pause");
	return 0;
}

/*
FORMATS THE TITLE SCREEN
*/
void titleFormatting()
{
	const int SIZE = 23;
	char TitleTOP[SIZE];
	char TitleBOTTOM[SIZE];

	for (int x = 0; x < SIZE; x++)
	{
		TitleTOP[x] = '-';
		cout << TitleTOP[x];
	}

	cout << "\n******TIC TAC TOE******" << endl;

	for (int x = 0; x < SIZE; x++)
	{
		TitleBOTTOM[x] = '-';
		cout << TitleBOTTOM[x];
	}

	cout << endl;


}
/*
SETS THE GAME SCREEN BACKGROUND AND FONT COLOR
*/
void SetGameColor()
{
	int ColorChoice;
	cout << "\n1. Black Background, White Text" << endl;
	cout << "2. Light Aqua Background, Black Text" << endl;
	cout << "3. Blue Background, Light Aqua Text\n" << endl;

	cout << "Please set a game color: ";
	cin >> ColorChoice;

	if (ColorChoice == 1)
		cin.ignore();
	else if (ColorChoice == 2)
		system("color B0");
	else if (ColorChoice == 3)
		system("color 1B");

	cin.ignore();

	system("cls");
}

/*
SETS AND RETURNS THE PLAYER CHOICE 
RETURNED VALUE IS USED WITH AN OBJECT TO SET
EACH PLAYERS SYMBOL
*/
int SetPlayerXorO()
{
	int choice;
	cout << "\nPlayer 1" << endl;
	cout << "Please choose (X) or (O)" << endl;
	cout << "\n1. Choice: (X)" << endl;
	cout << "2. Choice: (O)" << endl;
	cout << "\nEnter 1 or 2: " << endl;
	cin >> choice;

	while (choice != 1 && choice != 2)
	{
		cout << "\nInvalid! Enter only 1 or 2!";
		cin.clear();
		cin.ignore();
		cin >> choice;
	}
	
	system("cls");
	return choice;
}

void ClearScreen()
{
	system("cls");
}


/*
Class Member Function that checks to see if the game is finally over
*/
bool Game::CheckForWinner()
{
		if (PrintBoard[0][0] == PrintBoard[0][1] && PrintBoard[0][1] == PrintBoard[0][2])
		{
			if (PrintBoard[0][0] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[0][0] == PrintBoard[1][1] && PrintBoard[1][1] == PrintBoard[2][2])
		{
			if (PrintBoard[0][0] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[1][0] == PrintBoard[1][1] && PrintBoard[1][1] == PrintBoard[1][2])
		{
			if (PrintBoard[1][0] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[2][0] == PrintBoard[2][1] && PrintBoard[2][1] == PrintBoard[2][2])
		{
			if (PrintBoard[2][0] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[0][2] == PrintBoard[1][1] && PrintBoard[1][1] == PrintBoard[2][0])
		{
			if (PrintBoard[0][2] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[0][0] == PrintBoard[1][0] && PrintBoard[1][0] == PrintBoard[2][0])
		{
			if (PrintBoard[0][0] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[0][1] == PrintBoard[1][1] && PrintBoard[1][1] == PrintBoard[2][1])
		{
			if (PrintBoard[0][1] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else if (PrintBoard[0][2] == PrintBoard[1][2] && PrintBoard[1][2] == PrintBoard[2][2])
		{
			if (PrintBoard[0][2] == 'O')
			{
				cout << "\nWinner: O" << endl;
				cout << "Loser: X" << endl;
			}
			else
			{
				cout << "\nWinner: X" << endl;
				cout << "Loser: O" << endl;
			}
			return true;
		}
		else
		{
			return false;
		}
}

bool Game::CheckPosition()
{
	if (PrintBoard[0][0] != '1')
		return true;
	if (PrintBoard[0][1] != '2')
		return true;
	if (PrintBoard[0][2] != '3')
		return true;
	if (PrintBoard[1][0] != '4')
		return true;
	if (PrintBoard[1][1] != '5')
		return true;
	if (PrintBoard[1][2] != '6')
		return true;
	if (PrintBoard[2][0] != '7')
		return true;
	if (PrintBoard[2][1] != '8')
		return true;
	if (PrintBoard[2][2] != '9')
		return true;

	return false;
}


Last edited on


This is my header file
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
#ifndef GAME_H
#define GAME_H
#include <vector>
#include <iostream>
using namespace std;

class Game
{

private:
	int location;
	int TotalPicks;
	char Player1Symbol;
	char Player2Symbol;
	vector <vector<char>> PrintBoard = // provide a default member initialiser (equivalent to 2D Array)
	{
		{ '1', '2', '3' },
		{ '4', '5', '6' },
		{ '7', '8', '9' }
	};

public:
	Game(int PlayerChoice)
	{
		if (PlayerChoice == 1)
		{
			Player1Symbol = 'X';
			Player2Symbol = 'O';
		}
		else if (PlayerChoice == 2)
		{
			Player1Symbol = 'O';
			Player2Symbol = 'X';
		}
		
		TotalPicks = 0;
		location = 0;
	}

	bool CheckForWinner();
	bool CheckPosition();
	
	void ShowGameBoard()
	{
		cout << endl;

		for (int x = 0; x < 3; x++)
		{
			for (int y = 0; y < 3; y++)
			{
				cout << "|" << PrintBoard[x][y];
			}
			cout << "|" << endl;
		}
	}

	int Player1Xselection()
	{
		int location;
		cout << "\nPlayer 1 (X)" << endl;
		cout << "Please choose a location (1-9): " << endl;
		cin >> location;

		while (location < 1 || location > 9)
		{
			cout << "Invalid! Please choose 1-9 only!" << endl;
			cout << "Enter: " << endl;
			cin.clear();
			cin.ignore();
			cin >> location;
		}
		
		this->location = location;
		return location;
	}

	int Player1Oselection()
	{
		int location;
		cout << "\nPlayer 1 (O)" << endl;
		cout << "Please choose a location (1-9): " << endl;
		cin >> location;

		while (location < 1 || location > 9)
		{
			cout << "Invalid! Please choose 1-9 only!" << endl;
			cout << "Enter: " << endl;
			cin.clear();
			cin.ignore();
			cin >> location;
		}

		this->location = location;
		return location;
	}

	int Player2Xselection()
	{
		int location;
		cout << "\nPlayer 2 (X)" << endl;
		cout << "Please choose a location (1-9): " << endl;
		cin >> location;

		while (location < 1 || location > 9)
		{
			cout << "Invalid! Please choose 1-9 only!" << endl;
			cout << "Enter: " << endl;
			cin.clear();
			cin.ignore();
			cin >> location;
		}

		this->location = location;
		return location;
	}

	int Player2Oselection()
	{
		int location;
		cout << "\nPlayer 2 (O)" << endl;
		cout << "Please choose a location (1-9): " << endl;
		cin >> location;

		while (location < 1 || location > 9)
		{
			cout << "Invalid! Please choose 1-9 only!" << endl;
			cout << "Enter: " << endl;
			cin.clear();
			cin.ignore();
			cin >> location;
		}

		this->location = location;
		return location;
	}

	void setLocationX()
	{
		if (Player1Symbol == 'X' || Player2Symbol == 'X')
		{
			if (location == 1)
				PrintBoard[0][0] = 'X';
			else if (location == 2)
				PrintBoard[0][1] = 'X';
			else if (location == 3)
				PrintBoard[0][2] = 'X';
			else if (location == 4)
				PrintBoard[1][0] = 'X';
			else if (location == 5)
				PrintBoard[1][1] = 'X';
			else if (location == 6)
				PrintBoard[1][2] = 'X';
			else if (location == 7)
				PrintBoard[2][0] = 'X';
			else if (location == 8)
				PrintBoard[2][1] = 'X';
			else if (location == 9)
				PrintBoard[2][2] = 'X';
		}

	}

	void setLocationO()
	{
		if (Player1Symbol == 'O' || Player2Symbol == 'O')
		{
			if (location == 1)
				PrintBoard[0][0] = 'O';
			else if (location == 2)
				PrintBoard[0][1] = 'O';
			else if (location == 3)
				PrintBoard[0][2] = 'O';
			else if (location == 4)
				PrintBoard[1][0] = 'O';
			else if (location == 5)
				PrintBoard[1][1] = 'O';
			else if (location == 6)
				PrintBoard[1][2] = 'O';
			else if (location == 7)
				PrintBoard[2][0] = 'O';
			else if (location == 8)
				PrintBoard[2][1] = 'O';
			else if (location == 9)
				PrintBoard[2][2] = 'O';
		}

	}
};

#endif 

closed account (48T7M4Gy)
if the game position != '1' then return true.

What happens if it contains '9'??

Why not just initialize the grid to '-' everywhere? The cell is vacant if it contains '-' otherwise it is not vacant?
kemort,

But I am not really interested in doing that.
It is user friendly to just select a number 1 through 9 from a display.

My if statements look good to me. I used the debugger as well. I have no idea why IsItOccupied keeps changing to true regardless of what Player 2 chooses for the first move with (O).
Something along these lines, perhaps:

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
#include <vector>
#include <iostream>

struct Game
{
    const char player_one_symbol = 'X' ;
    const char player_two_symbol = 'O' ;

    std::vector< std::vector<char> > board = // provide a default member initialiser
    {
        {'1', '2', '3'},
        {'4', '5', '6'},
        {'7', '8', '9'}
    };

    char at( int loc ) const // return char at location loc [1,9]
    {
        --loc ; // make zero-based
        return board[loc/3][loc%3] ;
    }

    char& at( int loc ) // return char at location loc [1,9]
    {
        --loc ; // make zero-based
        return board[loc/3][loc%3] ;
    }

    bool available( int loc ) const // return true if 'loc' is available
    { return loc > 0 && loc < 10 && at(loc) == loc + '0' ; }

    bool game_over() const { return /* win detected || */ num_availacle() == 0 ; }

    int num_availacle() const // return count of available locations
    {
        int cnt = 0 ;
        for( int loc = 1 ; loc < 10 ; ++loc ) if( available(loc) ) ++cnt ;
        return cnt ;
    }

    int player_one_selection() { return selection(player_one_symbol) ; }
    int player_two_selection() { return selection(player_two_symbol) ; }

    int selection( char player_symbol )
    {
        std::cout << "Please choose a location (1-9): " ;

        int loc ;
        if( std::cin >> loc && available(loc) )
        {
            at(loc) = player_symbol ;
            return loc ;
        }

        std::cin.clear() ; // clear possible failed state (eg. user may not have entered a number)
        std::cin.ignore( 1000, '\n' ) ; // discard the characters in the input buffer
        std::cout << "invalid location / location is already taken. try again\n" ;
        return selection(player_symbol) ;
    }

    std::ostream& print_board( std::ostream& stm = std::cout ) const
    {
        for( const auto& row : board )
        {
            for( char c : row ) stm << c << ' ' ;
            stm << '\n' ;
        }
        return stm << '\n' ;
    }
};

int main()
{
    Game g ;
    g.print_board() ;

    bool player_one_next = true ;
    while( !g.game_over() ) // testing: no checks for win
    {
        if( player_one_next ) g.player_one_selection() ;
        else g.player_two_selection() ;
        g.print_board() ;
        player_one_next = !player_one_next ; // toggle player
    }
}
Topic archived. No new replies allowed.