TicTacToe not determining winner

Aug 17, 2008 at 3:44am
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 Aug 17, 2008 at 3:54am
Aug 17, 2008 at 4:06am
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 Aug 17, 2008 at 4:14am
Aug 18, 2008 at 12:34am
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/
Aug 18, 2008 at 12:49am
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 Aug 18, 2008 at 12:50am
Aug 18, 2008 at 12:54am
Not sure I understand.
Aug 18, 2008 at 1:12am
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.
Aug 18, 2008 at 2:25am
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.
Aug 18, 2008 at 9:02am
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 Aug 18, 2008 at 9:04am
Aug 18, 2008 at 5:48pm
("X' != 'D')
LOL WUT?
Aug 18, 2008 at 8:26pm
} 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 != ' ');
Aug 19, 2008 at 1:10am
@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?
Aug 19, 2008 at 1:37am
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 Aug 19, 2008 at 1:46am
Topic archived. No new replies allowed.