Need help with Tic Tac Toe game program (specifically the while loop)

Hi,

I have no idea why the while loop of my program isn't working. When my code is like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
    while (gameState == 0) {
        player = i % 2;
        if (player == 0) {
            mark = 'X';
        } else {
            mark = 'O';
        }
        board();
        getUserInput();

        i++;

        gameState = checkWin();
    }

    if (gameState == 0) {
        cout << "draw";
    } else {
        cout << "win";
    }
    return 0;
}


The console windows pop up and nothing happens.

But when the condition of my while loop is changed to (counter < 9), the program sort of works (except I can't check the win condition). Just in case anyone want to see the full code:

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

//will add more to checkWin() once loop works

#include <iostream>
#include <string>

using namespace std;

void board();
int checkWin();
int findIndexI(int array[][3]);
int findIndexJ(int array[][3]);
void getUserInput();

int index_i_1 = 0;
int index_j_1 = 0;
int i = 1;

//create board array
char square[3][3] =
{
    {'1', '2', '3'},
    {'4', '5', '6'},
    {'7', '8', '9'},
};

int counter = 0;
int player, gameState;
char mark;

int main()
{
    while (gameState == 0) {
        player = i % 2;
        if (player == 0) {
            mark = 'X';
        } else {
            mark = 'O';
        }
        board();
        getUserInput();

        i++;

        gameState = checkWin();
    }

    if (gameState == 0) {
        cout << "draw";
    } else {
        cout << "win";
    }
    return 0;
}

int findIndexI(char array[][3], int indexi)
{
    int index_i = 0;
    for (int j = 0; j < 3; j ++) {
        for (int i = indexi; i < 3; i++) {
            if (array[i][j] == 'X' | array[i][j] == 'O') {
                index_i = i;
                break;
            }
        }
    }
    return index_i;
}

int findIndexJ (char array[][3], int indexj)
{
    int index_j = 0;
    for (int i = 0; i < 3; i ++) {
        for (int j = indexj; j < 3; j++) {
            if (array[i][j] == 'X' | array[i][j] == 'O') {
                index_j = j;
                break;
            }
        }
    }
    return index_j;
}

void board()
{
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << square[i][j] << " " ;
            if (j == 2) {
                cout << endl;
            }
        }
    }
}

int checkWin () {
    index_i_1=findIndexI(square, 0);
    index_j_1=findIndexJ(square, 0);
    if (square[index_i_1][index_j_1] == square[index_i_1][index_j_1 + 1] && square[index_i_1][index_j_1 + 1] == square[index_i_1][index_j_1 + 2] == 1) {
        cout << "end" << endl;
        return 1;
    } return 0;
}

void getUserInput()
{
    cout << "Choose a square" << endl;
    int input;
    cin >> input;
    counter++;
    switch(input)
    {
    case 1:
        if (square[0][0] != mark) {
            square[0][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 2:
        if (square[0][1] != mark) {
            square[0][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 3:
        if ((square[0][2] != mark)) {
            square[0][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 4:
        if (square[1][0] != mark) {
            square[1][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 5:
        if (square[1][1] != mark) {
            square[1][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 6:
        if (square[1][2] != mark) {
            square[1][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 7:
        if (square[2][0] != mark) {
            square[2][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 8:
        if (square[2][1] != mark) {
            square[2][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 9:
        if (square[2][2] != mark) {
            square[2][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    }
}


Thanks in advance
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
int findIndexI(char array[][3], int indexi)
{
    int index_i = 0;
    for (int j = 0; j < 3; j ++) {
        for (int i = indexi; i < 3; i++) {
            if (array[i][j] == 'X' | array[i][j] == 'O') {
                index_i = i;
                break;
            }
        }
    }
    return index_i;
}

int findIndexJ (char array[][3], int indexj)
{
    int index_j = 0;
    for (int i = 0; i < 3; i ++) {
        for (int j = indexj; j < 3; j++) {
            if (array[i][j] == 'X' | array[i][j] == 'O') {
                index_j = j;
                break;
            }
        }
    }
    return index_j;
}
these two functions look exactly the same to me. As for your problem you should use a do/while or initialize gamestate.
Do while doesn't work either. And gameState was initialized at the beginning (otherwise I get compiler error).

My do while looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    do {
        player = i % 2;
        if (player == 0) {
            mark = 'X';
        } else {
            mark = 'O';
        }
        board();
        getUserInput();

        i++;

        gameState = checkWin();
    } while (gameState == 0);

    cout << "win";
    
    return 0;
}
Last edited on
And gameState was initialized at the beginning (otherwise I get compiler error). initializing would be defining it a value not declaring it as a variable. So it would compile anyways. Also, I think your logic is wrong. You make it so you only win if they are vertical what if they are horizontal or diagonal?

By the way
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
    switch(input)
    {
    case 1:
        if (square[0][0] != mark) {
            square[0][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 2:
        if (square[0][1] != mark) {
            square[0][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 3:
        if ((square[0][2] != mark)) {
            square[0][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 4:
        if (square[1][0] != mark) {
            square[1][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 5:
        if (square[1][1] != mark) {
            square[1][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 6:
        if (square[1][2] != mark) {
            square[1][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 7:
        if (square[2][0] != mark) {
            square[2][0] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 8:
        if (square[2][1] != mark) {
            square[2][1] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    case 9:
        if (square[2][2] != mark) {
            square[2][2] = mark;
            break;
        } else {
            i = i - 1;
            break;
        }
    }
can be written as
1
2
3
4
5
6
7
8
9
10
11
12
13
if(input > 0 && input < 10)//[1,9]
{
    int row = input / 3;
    int column = input % 3;
    if(square[row][column] != mark)
    {
        square[row][column] = mark;
    }
    else
    {
        --i;
    }
}


I would also advise you not to use global variables.
I tried giving gameState a value of 0 before the loop but it's still not working.

Also I know the checkWin logic is wrong (only works for horizontal + have a few other major problems) but it shouldn't prevent stuff from showing up on the console window. I don't want to fix the checkWin logic until I can get the loop to work so I can test easier.

btw thanks for the suggestion for the user input thing
Last edited on
but it shouldn't prevent stuff from showing up on the console window. I don't want to fix the checkWin logic until I can get the loop to work so I can test easier. I'm not sure the exact problem you are having with text not showing to the output.

Though there are a few problems I noticed. In your input function.
1
2
3
4
    if(square[row][column] != mark)
    {
        square[row][column] = mark;
    }
This has a few problems. Say for example the current mark is 'O' if there is an X there they can place over it. I would check to see if the current is a 1->9 or is not a 'O' or 'X'

You could do either if(square[row][column] > '0' && square[row][column] <= '9') or if(isdigit(square[row][column])) //http://www.cplusplus.com/reference/cctype/

Line 61 and 75 you probably mean || and not | as | is a bitwise operator. Though, these functions aren't needed and I don't know what they are even doing.

Line 99 why are you comparing it equal to 1? I would remove that.

Then there are global variables in play which should be avoided and just pass them into functions using parameters.

Topic archived. No new replies allowed.