tictactoe with enums and an array. runs ok but I just can't find this bug

This loads and stuff, it just behaves weird. when entering a O or X in cell (y, x) 2, 0 or in 1, 2 it somehow copies to the other. It also does this with cells 0, 2 and 1, 0.

My code has commented out a fn to exclude that. Also added a bunch of couts and print_array to see where the miss-copy is happening.

I have pinned it down to the fn "get_and_filter_input" (defined at the end) on the line "board[input_X][input_Y] = competitor+1;". But I cannot see why it is copying to a second place.

Yes I am new, yes it is a bit messy, yes I am just learning/having a play. Yes some of this fn should be in the main code (doesn't even match the title any more) Yes there is an overuse of enums. (Not even declared right?)

I am using C::B on Linux Mint 15. (and "Jumping into C++")

I think it is because of my enum usage: could someone comment to improve my understanding or their use? Would welcome any other feedback correcting my understanding.

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
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;
void print_board(int board [][2]);
int win_check(int board[][2]);
//void still_winnable_check();
void get_and_filter_input(int competitor, int board[][2]);
int filter_input();

int main()
{
    // intro
    cout << "Hello and welcome to Tic Tac Toe.  This game needs TWO players, \n";
    string play_desire = "Y";

    //setup variables
    int board[2][2];

    enum square_options{
        nothing,
        O,
        X
    };

    enum game_state{
        play_on,
        won_by_O,
        won_by_X,
        not_winnable
    };

    enum player{
        naught,
        cross
    };

    int game = play_on;
    player competitor = naught;


    // initiate outer new_game loop.
    while (play_desire == "Y" || play_desire =="y")
    {

    //wipe board
    for (int i = 0; i<3 ; i++)
    {
        for (int j = 0; j < 3 ; j++)
        {
            board[i][j] = nothing;
        }
    }


    //open inner loop
    while (game == play_on)
    {

    //print board
    print_board(board);
    // check spaces left/ break


    //get player X or O input
    // add to board
    get_and_filter_input(competitor, board);

    // win check/ break
    game = win_check(board);
    // still winnable check /break
    // not written yet

    //swap player for next round of loop
    if (competitor == cross)
    {
        competitor = naught;
    }
    else if (competitor == naught)
    {
        competitor = cross;
    }
    // repeat inner loop
    }
    // annouce result
    //not written yet

    // "game over"
    // repeat outer loop: "play again"
    }

    // bye and tanks for playing

    cout << "Hello world!" << endl;
    return 0;
}

void print_board(int board[][2])
{
    for (int i = 0; i<3 ; i++)
    {
        for (int j = 0; j < 3 ; j++)
        {
            if(board[i][j] == 0)
            {
                cout << "   : ";
                }
            if (board[i][j] == 2)
            {
                cout << " X : ";
            }
           if (board[i][j] == 1)
            {
                cout << " O : ";
            }

        }
        cout <<"\n";
    }
    }

void get_and_filter_input(int competitor, int board[][2])
{
    // variables for this fn
    string player_name;
    bool query_good_square_choice = false;
    int input_X, input_Y;
    
    // set up loop to keep looping until an empty square is selected
    while (query_good_square_choice == false)
    {
    // set up some strings for prettier output statements
    if (competitor == 0)
    {
        player_name = "O";
    }
    else if (competitor == 1)
    {
        player_name = "X";
    }
    cout << "Please enter x co-ordinate for player " << player_name << " : " ;
    // filter input
    input_X = filter_input();
    
    // notice lots of cout statements here: I am trying to pin down the line where the errant jump is made
    cout << input_X << "\n";
    cout << "Please enter Y co-ordinate for player " << player_name << " : ";
    input_Y = filter_input();

    cout << input_Y << "\n";
    cout << board[input_X][input_Y] << "\n";
    cout << player_name << "\n";

    if (board[input_X][input_Y] == 0)
    {
    cout << "selected board place content: " << board[input_X][input_Y] <<"\n";
    cout << "competitor code: " << competitor<<"\n";
    cout << " competitor code +1: " << competitor + 1 <<"\n";
    cout << " player name: " << player_name << "\n";
    cout << "board print: \n";
    print_board(board);

//errant jump here
    cout <<"*** now performing cell input*** \n";
    board[input_X][input_Y] = competitor+1;
    cout << "selected board place content: " << board[input_X][input_Y] <<"\n";
//more check statements
    cout << "competitor code: " << competitor<<"\n";
    cout << " competitor code +1: " << competitor + 1 <<"\n";
    cout << " player name: " << player_name << "\n";
    print_board(board);
// back to process flow control
    query_good_square_choice = true;
    }
    else{
    cout <<"That square is already taken! Try again. \n";
    print_board(board);
    }
}}

int filter_input()
{
    int input = 3;
    while (input >2 || input <0)
    {
    cout << "\n(Please use a 0, a 1 or a 2) : ";
    cin >> input;
    }
    return input;
}

int win_check(int board[][2])
{
    int gamey_state = 0;
    /*
    //row check
    for (int i = 0; i<3; i++)
    {
        if (board[i][0] == board[i][1] && board[i][0] == board[i][2])
        {gamey_state = board[i][0];}
    }
    //column check
    for (int i = 0; i<3; i++)
    {
        if (board[0][i] == board[1][i] && board[0][i] == board[2][i])
        {gamey_state = board[0][i];}
    }
    //diag check
    // one diag
    if (board[0][0] == board[1][1] && board[0][0] == board[2][2])
    {gamey_state = board[0][0];}
    if (board[0][2] == board[1][1] && board[0][2] == board[2][0])
    {gamey_state = board[0][2];}
    // still winnable check */
    return gamey_state;
}
You made a mistake in your array declaration and further access.

int board[2][2]; will decrare 2x2 array with valid indexes [0][0], [0][1], [1][0] and [1][1].
1
2
for (int j = 0; j < 3 ; j++)     {
            if(board[i][j] == 0)
Will access out of bounds, which in case of multidimensional arrays can lead to funny behavior: [0][2] can point to the same place as [1][0] depending on implementation.
ooooh. Yeah.

So obvious now I see it. Yeah, on second inspection of the textbook I should have seen this.

Interesting that this error was consistent. Fixed.
Many thanks
Topic archived. No new replies allowed.