Tic Tac Toe, Need Help

Whenever I run the code, It asks for the players names, player 1 then 2.
Then asks the player that wins the coin toss to make a move.
Then the next player goes. Then it says Tie game and ends.
Im sure its some silly mistake I made, and after an hour of poking around and changing things, I figured I'd ask a fresh set of eyes.

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
//Main.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include "Player.h"

using namespace std;

int main(void) {
	string name1, name2;
	TTT game;
	TTT();
	
	cout << "Welcome to Tic-Tac-Toe" << endl
		 << "----------------------" << endl
		 << "First player, enter your name: ";
	getline(cin, name1);
	Player player1(name1, 1);
	cout << endl
		 << "Second player, enter your name: ";
	getline(cin, name2);
	Player player2(name2, 2);
	
	//random toss
	unsigned seed = time(0);
	srand(seed);
	
	int x = rand() % 100 + 1;
	
	int index = 0;
	if(x > 50) {
		cout << player2.getName() << " won the toss." << endl;
		game.displayBoard();
		do {
			index = player2.getIndex();
			cout << player2.getName();
			player2.nextMove(game);
			game.displayBoard();
			index = player1.getIndex();
			cout << player1.getName();
			player1.nextMove(game);
			game.displayBoard();
		}while(game.getStatus() == 3);
	}
	else if(x <= 50) {
		cout << player1.getName() << " won the toss." << endl;
		game.displayBoard();
		do {
			index = player1.getIndex();
			cout << player1.getName();
			player1.nextMove(game);
			game.displayBoard();
			index = player2.getIndex();
			cout << player2.getName();
			player2.nextMove(game);
			game.displayBoard();
		}while(game.getStatus() == 3);
	}
	if(game.getStatus() == 0) {
		cout << "The game is a tie!" << endl;
	}
	else if(game.getStatus() == 1) {
		cout << player1.getName() << " has won the game! Congratulations!" << endl;
	}
	else if(game.getStatus() == 2) {
		cout << player2.getName() << " has won the game! Congratulations!" << endl;
	}
	else {
		cout << "Unknown error.";
	}

	system("pause");
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Player.h

#include <string>
#include "TicTacToe.h"

using namespace std;

class Player {
private:
	string name;
	int playerNumber;
public:
	Player(string tempName, int tempPlayerNumber);
	int getIndex();
	string getName();
	void nextMove(TTT &object);
};


1
2
3
4
5
6
7
8
9
10
11
12
13
14
//TicTacToe.h

#include <iostream>
using namespace std;

class TTT {
private:
	char board[3][3];
public:	
	TTT();
	void displayBoard();
	bool setValue(int row, int column, int playerNumber);
	int getStatus();
};


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
//player.cpp

#include <iostream>
#include <string>
#include "Player.h"

using namespace std;

Player::Player(string tempName, int tempPlayerNumber) {
	name = tempName;
	playerNumber = tempPlayerNumber;
}

int Player::getIndex() {
	return playerNumber;
}

string Player::getName() {
	return name;
}

void Player::nextMove(TTT &game) {
	int row, column;
	cout << ", make your move(Ex. 1(space)2): ";
	cin >> row >> column;
	while(row > 2 || row < 0 || column > 2 || column < 0) {
		cout << "Invalid entry. Please try again: ";
		cin >> row >> column;
	}
	while(game.setValue(row, column, playerNumber) == ' ') {
		cout << "That space has already been taken. Please make another selection: ";
	}
	game.setValue(row, column, playerNumber);
}


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
//TicTacToe.cpp

#include <iostream>
#include "TicTacToe.h"

using namespace std;

TTT::TTT() {

int row = 0;
int column = 0;
int playerNumber = '\0';
for (int i = 0; i < 3; i++)
{
for (int k = 0; k < 3; k++)
{
board[i][k] = playerNumber;
}
}	
}

void TTT::displayBoard() {
	cout << " " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << endl
		 << "-----------" << endl
		 << " " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << endl
		 << "-----------" << endl
		 << " " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << endl;
}

bool TTT::setValue(int row, int column, int playerNumber) {
	char i;
	if(playerNumber == 1) {
		i = 'X';
	}
	else if(playerNumber == 2) {
		i = 'O';
	}
	if(board[row][column] == '\0') {
		board[row][column] = i;
		return true;
	}
	else if(board[row][column] != '\0') {
		return false;
	}
}

int TTT::getStatus() {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < 3; j++) {
			if(board[i][j] == '\0') {
				return 0;
			}
		}
	}
	
	if(board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X' && 
	   board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X' && 
	   board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X' &&
	   board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X' && 
	   board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X' && 
	   board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X' &&
	   board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X' && 
	   board[0][2] == 'X' && board[1][1] == 'X' && board[0][2] == 'X') {
		return 1;
	}
	else if(board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O' && 
			board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O' && 
			board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O' &&
			board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O' && 
			board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O' && 
			board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O' &&
			board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O' && 
			board[0][2] == 'O' && board[1][1] == 'O' && board[0][2] == 'O') {
			return 2;
		}
	else {
		return 3;
	}
}


Any Hints are welcome too, Just one can only look at something so long. :)
I need to write an article on debugging.

Staring at a block of code trying to find a problem is difficult. Especially when you wrote the code (because you tend to see what you want the code to do.... rather than what it actually does). Blindly poking around and changing things usually doesn't lead to a solution either.

So instead of looking at the code with human eyes... look at it with the computer's eyes! You can do this by stepping through it with a debugger.


I go through the basics of using a debugger in this post:
http://www.cplusplus.com/forum/beginner/75304/#msg403990


For you, it sounds like the program flow is not going the way you expect. So I would just set a breakpoint on the very first line in main... and just start stepping through the whole program and make sure it does what you want it to. When it does something you didn't intend, you'll be able to see why by looking at the code that's actually executing as it's being executed.
Last edited on
The logic of your GetStatus function is entirely incorrect. For example, the cases for returning 1 and 2 check whether the entire board is X or O respectively, which is an impossible condition.

also, as for the reason why you get to a tie state immediately:
1
2
3
4
5
6
7
8
for(int i = 0; i < 3; i++)
{
    for(int j = 0; j < 3; j++)
    {
        if(board[i][j] == '\0')
        	return 0;
    }
}

This part of your GetStatus function returns 0 if ANY of the spaces are '\0'. After your players make moves and your code calls GetStatus(), it is guaranteed to return 0 since the board is mostly still filled with null characters.
Last edited on
Topic archived. No new replies allowed.