Tic Tac Toe AI, problems.

I'm trying to get a simple defensive AI for Tic Tac Toe to work, the problem is that even though it shouldn't be happening, my CPU AI function is escaping my if else statements and returning 0, heres my code board.cpp:

and a zip of my entire project if this isn't enough (codeblocks project, executable compiled in linux but should run on windows)

http://www.mediafire.com/?x37ui1f3lqqdqeb

edit: forgot a line of code in the CPU function that returns 0, this post is updated but I didn't bother re-uploading the project.

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
int Board::SetGrid(int pos, char symbol)
{
         if (pos == 1 && grid[0][0] != 'X' && grid[0][0] != 'O') {grid[0][0] = symbol; return 0;}
    else if (pos == 2 && grid[0][1] != 'X' && grid[0][1] != 'O') {grid[0][1] = symbol; return 0;}
    else if (pos == 3 && grid[0][2] != 'X' && grid[0][2] != 'O') {grid[0][2] = symbol; return 0;}
    else if (pos == 4 && grid[1][0] != 'X' && grid[1][0] != 'O') {grid[1][0] = symbol; return 0;}
    else if (pos == 5 && grid[1][1] != 'X' && grid[1][1] != 'O') {grid[1][1] = symbol; return 0;}
    else if (pos == 6 && grid[1][2] != 'X' && grid[1][2] != 'O') {grid[1][2] = symbol; return 0;}
    else if (pos == 7 && grid[2][0] != 'X' && grid[2][0] != 'O') {grid[2][0] = symbol; return 0;}
    else if (pos == 8 && grid[2][1] != 'X' && grid[2][1] != 'O') {grid[2][1] = symbol; return 0;}
    else if (pos == 9 && grid[2][2] != 'X' && grid[2][2] != 'O') {grid[2][2] = symbol; return 0;}
    else return 1; // invalid position
}

//had to get rid of chunk for post to fit

int Board::Check(char symbol)
{
         if (grid[0][0] == symbol && grid[0][1] == symbol && grid[0][2] == symbol) return 0; // horizontal row one
    else if (grid[1][0] == symbol && grid[1][1] == symbol && grid[1][2] == symbol) return 0; // horizontal row two
    else if (grid[2][0] == symbol && grid[2][1] == symbol && grid[2][2] == symbol) return 0; // horizontal row three
    else
    {
             if (grid[0][0] == symbol && grid[1][0] == symbol && grid[2][0] == symbol) return 0; // vertical collumn one
        else if (grid[0][1] == symbol && grid[1][1] == symbol && grid[2][1] == symbol) return 0; // vertical collumn two
        else if (grid[0][2] == symbol && grid[1][2] == symbol && grid[2][2] == symbol) return 0; // vertical collumn three
        else
        {
                 if (grid[0][0] == symbol && grid[1][1] == symbol && grid[2][2] == symbol) return 0; // diagnol line one
            else if (grid[2][0] == symbol && grid[1][1] == symbol && grid[0][2] == symbol) return 0; // diagnol line two
            else
            {
                return 1; // no one has one
            }
        }
    }
}

int Board::randomize(int max, int min)
{
     // don't forget to seed once in main.
    max = max + 1;
    max = max - min;
    return (rand() % max + min);
}

int Board::CPU()
{
    // horizontal defense row 1
         if (grid[0][1] == 'X' && grid[0][2] == 'X')
    {
        std::cout << "Horizontal Row One.A" << std::endl;
        if (grid[0][0] != 'X' && grid[0][0] != 'O') {Board::SetGrid(1, 'O'); return 1;}
    }
    else if (grid[0][0] == 'X' && grid[0][2] == 'X')
    {
        std::cout << "Horizontal Row One.B" << std::endl;
        if (grid[0][1] != 'X' && grid[0][1] != 'O') {Board::SetGrid(2, 'O'); return 2;}
    }
    else if (grid[0][0] == 'X' && grid[0][1] == 'X')
    {
        std::cout << "Horizontal Row One.C" << std::endl;
        if (grid[0][2] != 'X' && grid[0][2] != 'O') {Board::SetGrid(3, 'O'); return 3;}
    }
    // horizontal defense row 2
    else if (grid[1][1] == 'X' && grid[1][2] == 'X')
    {
        std::cout << "Horizontal Row Two.A" << std::endl;
        if (grid[1][0] != 'X' && grid[1][0] != 'O') {Board::SetGrid(4, 'O'); return 4;}
    }
    else if (grid[1][0] == 'X' && grid[1][2] == 'X')
    {
        std::cout << "Horizontal Row Two.B" << std::endl;
        if (grid[1][1] != 'X' && grid[1][1] != 'O') {Board::SetGrid(5, 'O'); return 5;}
    }
    else if (grid[1][0] == 'X' && grid[1][1] == 'X')
    {
        std::cout << "Horizontal Row Two.C" << std::endl;
        if (grid[1][2] != 'X' && grid[1][2] != 'O') {Board::SetGrid(6, 'O'); return 6;}
    }
    // horizontal defense row 3
    else if (grid[2][1] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Horizontal Row Three.A" << std::endl;
        if (grid[2][0] != 'X' && grid[2][0] != 'O') {Board::SetGrid(7, 'O'); return 7;}
    }
    else if (grid[2][0] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Horizontal Row Three.B" << std::endl;
        if (grid[2][1] != 'X' && grid[2][1] != 'O') {Board::SetGrid(8, 'O'); return 8;}
    }
    else if (grid[2][0] == 'X' && grid[2][1] == 'X')
    {
        std::cout << "Horizontal Row Three.C" << std::endl;
        if (grid[2][2] != 'O' && grid[2][2] != 'X') {Board::SetGrid(9, 'O'); return 9;}
    }
    // vertical defense collumn 1
    else if (grid[1][0] == 'X' && grid[2][0] == 'X')
    {
        std::cout << "Vertical Column One.A" << std::endl;
        if (grid[0][0] != 'O' && grid[0][0] != 'X') {Board::SetGrid(1, 'O'); return 1;}
    }
    else if (grid[0][0] == 'X' && grid[2][0] == 'X')
    {
        std::cout << "Vertical Column One.B" << std::endl;
        if (grid[1][0] != 'O' && grid[1][0] != 'X') {Board::SetGrid(4, 'O'); return 4;}
    }
    else if (grid[0][0] == 'X' && grid[1][0] == 'X')
    {
        std::cout << "Vertical Column One.C" << std::endl;
        if (grid[2][0] != 'O' && grid[2][0] != 'X') {Board::SetGrid(7, 'O'); return 7;}
    }
    // vertical defense collumn 2
    else if (grid[1][1] == 'X' && grid[2][1] == 'X')
    {
        std::cout << "Vertical Column Two.A" << std::endl;
        if (grid[0][1] != 'O' && grid[0][1] != 'X') {Board::SetGrid(2, 'O'); return 2;}
    }
    else if (grid[0][1] == 'X' && grid[2][1] == 'X')
    {
        std::cout << "Vertical Column Two.B" << std::endl;
        if (grid[1][1] != 'O' && grid[1][1] != 'X') {Board::SetGrid(5, 'O'); return 5;}
    }
    else if (grid[0][1] == 'X' && grid[1][1] == 'X')
    {
        std::cout << "Vertical Column Two.C" << std::endl;
        if (grid[2][1] != 'O' && grid[2][1] != 'X') {Board::SetGrid(8, 'O'); return 8;}
    }
    // vertical defense collumn 3
    else if (grid[1][2] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Vertical Column Three.A" << std::endl;
        if (grid[0][2] != 'O' && grid[0][2] != 'X') {Board::SetGrid(3, 'O'); return 3;}
    }
    else if (grid[0][2] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Vertical Column Three.B" << std::endl;
        if (grid[1][2] != 'O' && grid[1][2] != 'X') {Board::SetGrid(6, 'O'); return 6;}
    }
    else if (grid[0][2] == 'X' && grid[1][2] == 'X')
    {
        std::cout << "Vertical Column Three.C" << std::endl;
        if (grid[2][2] != 'O' && grid[2][2] != 'X') {Board::SetGrid(9, 'O'); return 9;}
    }
    // diagnol defense line 1
    else if (grid[1][1] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Diagnol Line One.A" << std::endl;
        if (grid[0][0] != 'O' && grid[0][0] != 'X') {Board::SetGrid(1, 'O'); return 1;}
    }
    else if (grid[0][0] == 'X' && grid[2][2] == 'X')
    {
        std::cout << "Diagnol Line One.B" << std::endl;
        if (grid[1][1] != 'O' && grid[1][1] != 'X') {Board::SetGrid(5, 'O'); return 5;}
    }
    else if (grid[0][0] == 'X' && grid[1][1] == 'X')
    {
        std::cout << "Diagnol Line One.C" << std::endl;
        if (grid[2][2] != 'O' && grid[2][2] != 'X') {Board::SetGrid(3, 'O'); return 9;}
    }
    // had to cut out another chunk
    // random
    else
    {
        bool occupied = true;
        while (occupied)
        {
            int randpos = randomize(9, 1);

            if (Board::SetGrid(randpos, 'O') == 0)
            {
                occupied = false;
                std::cout << "[RAND]" << std::endl;
                return randpos;
            }
        }
    }
    return 0;
}

Last edited on
Well, thanks for the help everyone, although I think I discovered the cause, when it detects if there is a possibility of the player getting 3 in a row, it then checks if it is a valid move, if it isn't then all the other if else statements are ignored and it skips straight to return 0, I'll try and add 'continue;' (not sure if they work in if statements, but meh) if that fails I'll figure something out.
Topic archived. No new replies allowed.