TicTacToe not determining winner

the program seems to take input till the max moves are done it does not check to see if a person has won the game. Any idea what I am missing?


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
#include <iostream>
using namespace std;

class TicTacToe{
    private:
        char theBoard [3][3];

    public:
        TicTacToe(void);
        void playOneGame(void);
        void switchPlayer(char &);
        void showBoard(void);
        void postMove(int, int, char);
        char determineWinner(void);
};
int main (void){
    //test the class by playing one game
        TicTacToe Game1;
        Game1.playOneGame();
}

void TicTacToe::playOneGame(void){    
    //start a game and play until someone wins or a draw occurs...    
        const int MaxMoves = 9;    
        char currentPlayer = 'O';    
        int row = 0;    
        int clmn = 0;    
        char theWinner = ' ';    
        int nmbrOfMoves = 0; //keep track of the number of moves max is 9

        do {    
            switchPlayer(currentPlayer); //change player from x to o or vice versa        
            showBoard();        
                cout << "\n\nPlayer " << currentPlayer << endl; //get the players move    
                cout << "Enter row of move (1, 2, 3): ";    
                cin >> row;    
                cout << "Enter column of move (1, 2, 3): ";    
                cin >> clmn;  
            postMove(row -1, clmn -1, currentPlayer); //post the move to the board
            theWinner = determineWinner();  //see if anyone won the game
            nmbrOfMoves++;  //keep track of the number of moves    

        } while ((theWinner != 'D') && (nmbrOfMoves != MaxMoves));
        showBoard(); //show the ending board    

    if (theWinner == 'D')  //declare a winner    
        cout << "\n\nThe Game was a Draw" << endl;    
    else    
        cout << "\n\nThe Winner is player " << theWinner << endl;
} 
TicTacToe::TicTacToe(void){
    //intialize the array contents
        for (int row = 0; row < 3; row++){
            for (int clmn = 0; clmn < 3; clmn++){
                theBoard[row][clmn] = '-';
            }
        }
}
void TicTacToe::switchPlayer(char &currentPlayer){
    //switches the current player
        if (currentPlayer == 'O'){
            currentPlayer = 'X';
        }
        else (currentPlayer = 'O');
}
void TicTacToe::showBoard(){
    //displays the board
        cout << endl;
        for (int row=0; row<3; row++){
            for (int clmn = 0; clmn < 3; clmn++){
                cout << "["<< theBoard[row][clmn] << "]";
            }
            cout << endl;
        }
        cout << endl;
}
void TicTacToe::postMove(int row, int clmn, char value){
    //gets the users move and posts it to the board
        theBoard[row][clmn] = value;
}

char TicTacToe::determineWinner(void){
    //analyzes the board to see if there is a winner
    //returns a X, O indicating the winner
    //if the game is a draw then D is returned

    //check the rows
        for (int i = 0; i < 3; i++){
            if (theBoard[i][0] == theBoard[i][1]
                && theBoard[i][1] == theBoard[i][2]
                    && theBoard[i][0] != ' '){
                return theBoard[i][0];
            }
}
    //check the clmns
        for (int i = 0; i < 3; i++){
            if (theBoard[0][i] == theBoard[1][i]
                && theBoard[1][i] == theBoard[2][i]
                    && theBoard[0][i] != ' '){
            return theBoard[0][i];
        }
}
    //check the diagnals
        if (theBoard[0][0] == theBoard[1][1]
            && theBoard[1][1] == theBoard[2][2]
                && theBoard[0][0] != ' ') {
            return theBoard[0][0];
        }
        if (theBoard[2][0] == theBoard[1][1]
            && theBoard[1][1] == theBoard[0][2]
                && theBoard[2][0] != ' ') {
            return theBoard[2][0];
        }
return 'D';
}
Last edited on
Only because I'm feeling nice and this is ridiculously easy to spend more than five seconds explaining how to do it:
1
2
3
4
5
6
7
8
9
10
for (char a=0;a<3;a++){
	if (board[a][0]==board[a][1] && board[a][0]==board[a][2])
		return board[a][0];
	if (board[0][a]==board[1][a] && board[0][a]==board[2][a])
		return board[0][a];
}
if (board[0][0]==board[1][1] && board[0][0]==board[2][2])
	return board[0][0];
if (board[0][2]==board[1][1] && board[0][2]==board[2][0])
	return board[1][1];
Last edited on
I only used a one dimensional array when I made this program, so I came up with this function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for(int x = 1; x < 3; x++)
			{
				if(win[0] == x)
				{
					if(win[1] == x) { if(win[2] == x) { winner = x; return true; } }
					if(win[4] == x) { if(win[8] == x) { winner = x; return true; } }
					if(win[3] == x) { if(win[6] == x) { winner = x; return true; } }
				}
				if(win[1] == x)
				{ if(win[4] == x) { if(win[7] == x) { winner = x; return true; } } }
				if(win[2] == x)
				{
					if(win[5] == x) { if(win[8] == x) { winner = x; return true; } }
					if(win[4] == x) { if(win[6] == x) { winner = x; return true; } }
				}
				if(win[3] == x)
				{ if(win[4] == x) { if(win[5] == x) { winner = x; return true; } } }
				if(win[6] == x)
				{ if(win[7] == x) { if(win[8] == x) { winner = x; return true; } } }
			}

I like the way you did yours though, but I tried to keep it a little simpler, to see the whole program check out: http://www.cplusplus.com/forum/lounge/2824/
With this macro, you can access the elements of a linear array as if it was a rectangular matrix:
1
2
3
4
5
/*
If you have a an Array[12], but want to access it as if it was an Array[4][3]
(4 rows and 3 columns) you use ARRAY_TO_MATRIX(Array,1,2,3)
*/
#define ARRAY_TO_MATRIX(array,y,x,width) (array)[(x)+(y)*(width)] 
Last edited on
Not sure I understand.
Line 43: } while ((theWinner != 'D') && (nmbrOfMoves != MaxMoves));

This will only trigger if the Winner is a Draw, or the box is filled. There is no clause here for is O or X the winner.
Zaita-

can you give me some pointers on how I would fix that part? I want to do it myself so I will learn, but that just confuses me abit.
raven123

What Zaita is saying is that you need to not only check to see if theWinner equal to D, but also check if it is equal to is X or O.

Let me explain in an example:

X beats O so you assign theWinner to X on line 40. Then line 40 will exectute then execution goes to line 43 where the line would evaluate to read:

while(("X' != 'D') && (nmbrOfMoves != MaxMoves));

assuming that you are not our of moves, X != D returns true thus the loop iterates again.

To fix this you must add a clause (another (___ != ___ ) || (____ !=____ ) statement) within the while conditional of the while loop on 43. HINT: it will look a lot like the first clause, but with diffrent letters)

Hope this helps!!
Last edited on
("X' != 'D')
LOL WUT?
} while ((theWinner != 'D') && (theWinner != 'X') && (theWinner != 'O') && (nmbrOfMoves != MaxMoves));

Although. I would look at changing what your determineWinner function returns.
It should return ' ' if it cannot determine a winner. And should check if all spaces are filled, and be able to declare a draw. Then you could just have

} while (theWinner != ' ');
@helios,

What I am trying to say is that if theWinner is set to X, X != D evaluates to true, thus the loop iterates again (assuming you are not out of moves).

Does that clarify it?
You don't necessarily have to check every possible placement. Once you postMove( row, col, players_piece );
immediately check to see whether it was a winning move:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool TickTackToe::IsWinningMove( int row, int col )
  {
  int count[ 4 ] = { 0 };
  char c = board[ row ][ col ];
  for (int n = 0; n < 3; n++)
    {
    count[ 0 ] += board[ row ][   n ] == c;
    count[ 1 ] += board[   n ][ col ] == c;
    count[ 3 ] += board[   n ][   n ] == c;
    count[ 4 ] += board[ 2-n ][   n ] == c;
    }
  for (int n = 0; n < 4; n++) 
    if (count[ n ] == 3) return true;
  return false;
  }

To determine if the game is a draw, just keep track of the number of moves posted. If the ninth move doesn't provide a winner, then the game is a draw.

Hope this helps.

[edit] fixed typo
Last edited on
Topic archived. No new replies allowed.