Connect 4 Program with AI :)

Hey this is connect 4 program with Minimax algorithm using NegaMax algorithm and I don't know actually if I implemented it correctly ... The problem is I don't know how to evaluate neutral moves please check it out and tell me how to implement it better
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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include <ctime>
using namespace std;
bool provocation = false; // used to display a provocative screen
char input[43]; // There are 42 places to play in the board .. this array represent them
void Board();
int PlayOut = 0;
int EVA = 0;
// EVA and PlayOut are working while NegaMax Function is working .. in NegaMax's way it will definitely make any winning move
// as it goes deep so when this happens PlayOut increases by 1 and EVA increases by 1 if its a winnning move or decreases by 1 if it the opposite
// so we can evaluate neutral moves for MiniMax by dividing EVA / PlayOut * 100 so we get a percentage
int winning();
int GetValue(int t);
int AIManager();
int NegaMax(int Depth);
void clean()
{
    provocation = false;
    for(int i = 0 ; i<= 80 ; i++)
        input[i]=' ';
}

int GetValue(int column) // pass this function a column that you want to play in and it will return its value in input array ..
{
    if(column > 7)
        return 0;
    int n;
    for(int i = 0 ; i<= 6 ; i++)
    {
        if( input[column+7*i] == ' '  )
        {
            n = column+7*i;
            break;
        }
    }
    if ( n > 42 )
        return 0;
    return n;
}

int winning() // Winning algorithm
{
    int temp=0;
    for(int i = 1 ; i<= 42 ; i++)
    {
        if(input[i] != ' ')
        {
            temp++;
            if( i - int((i-1)/7) * 7 <= 4  )
                if( input[i] == input [i+1] && input[i] == input[i+2] && input[i] == input[i+3] )
                    if(input[i] == 'X' )
                        return 1 ;
                    else
                        return 2;
            if( i <= 21 )
                if ( input[i] == input[i+7] && input[i] == input[i+14] && input[i] == input[i+21]  )
                    if(input[i] == 'X' )
                        return 1 ;
                    else
                        return 2;
            if( i - int((i-1)/7) * 7 <= 4 && i<=18  )
                if(input[i] == input[i+8] && input[i] == input[i+16] && input[i]==input[i+24])
                    if(input[i] == 'X' )
                        return 1 ;
                    else
                        return 2;
            if( i - int((i-1)/7) * 7 >= 4 && i <= 21   )
                if(input[i] == input[i+6] && input[i] == input[i+12] && input[i]==input[i+18])
                    if(input[i] == 'X' )
                        return 1 ;
                    else
                        return 2;
        }

    }
    if (temp == 42)
        return 3;
    return 0;
}
void Board() // Draw board
{
    cout<<endl<<"    1   "<<"    2   "<<"    3   "<<"    4   "<<"    5   "<<"    6   "<<"    7   "<<endl;

    int j = 42;
    for(int i = 0 ; i<= 23 ; i++)
    {
        if(i % 4 == 0)
            cout<<string(57,'-');
        else
        {
            if( (i - 2) % 4 == 0)
            {
                j=42-(0.25*i+0.5)*6-((0.25*i+0.5)-1) ;
                for(int i = 0 ; i<=6 ; i++)
                {
                    cout<<"|"<<"   "<<input[j]<<"   ";
                    j++;
                }
                cout<<"|";
            }
            else
            {
                for(int i = 0 ; i<=6 ; i++)
                    cout<<"|"<<string(7,' ');
                cout<<"|";
            }
        }
        cout<<endl;
    }
    cout<<string(57,'-');
    if(provocation == true)
        cout<<endl<<"Hehe I'm sure of my winning :D "<<endl;
}

void PlayPosition(char XO) // Function that asks you to enter where you like to play
{
    int sth;
    cout<<endl<<"where would you like to play"<<endl;
    while(true)
    {
        cin>>sth;
        sth=GetValue(sth);
        if( sth != 0 )
        {
            input[sth] = XO;
            return ;
        }
        else
            cout<<"ERROR"<<endl;
    }
}

int main() // main function
{
    srand(time(0));
    clean();
    while(true)
    {
        input[AIManager()]='O';
        system("cls");
        Board();
        int winningtemp = winning();
        if(winningtemp!=0)
        {
            if(winningtemp == 1)
                cout<<endl<<"Player 2 WON !";
            else if (winningtemp == 2)
                cout<<endl<<"Player 1 WON ! " ;
            else if (winningtemp == 3)
                cout<<"You Tie ! ";
            getch();
            clean();
        }
        else
            PlayPosition('X');
    }
}
int AIManager() // AI Algorithm
{
    float chance[2] = {9999999 , 0 };
    for(int column = 1 ; column <= 7 ; column ++)
    {
        PlayOut = 0;
        EVA=0;
        int PlayNumber = GetValue(column);
        if( PlayNumber != 0 )
        {

            input[PlayNumber] = 'O';
            if(winning()==2)
               {
                   input[PlayNumber]=' ';
                   return PlayNumber ;
               }
            float temp = -(100*NegaMax(1));
            if(PlayOut != 0)
                temp -= ((100*EVA)/PlayOut);
            if(-temp >= 100)
                provocation = true;
            if( chance[0] > temp  )
            {
                chance[0] = temp  ;
                chance[1] = PlayNumber;
            }
             //  cout<<endl<<-temp<<"   "<<EVA << "   " <<PlayOut;
            input[PlayNumber] = ' ';
        }
    }
    return chance[1];
}
int NegaMax(int Depth) // MiniMax algorithm in NegaMax form
{
    char XO;
    int PlayNumber[8] = {0,0,0,0,0,0,0,0}; // The values of the input[] for every column
    int chance=0;
    if(Depth % 2 != 0)
        XO='X';
    else
        XO='O';
    for(int column = 1 ; column <= 7 ; column ++)
        PlayNumber[column]=GetValue(column);
    for(int column = 1 ; column <= 7 ; column++)
    {
        if(PlayNumber[column] != 0)
        {
            input[PlayNumber[column]]=XO;
            if( winning() != 0 )
            {
                PlayOut ++;
                if(XO=='O')
                    EVA ++;
                else
                    EVA --;
                input[PlayNumber[column]]=' ';
                return -1;
            }
            input[PlayNumber[column]]=' ';
        }
    }
    if(Depth <= 6)
    {

        for(int column = 1 ; column <= 7 ; column ++)
        {
            int temp=0;
            if( PlayNumber[column] != 0 )
            {
                input[PlayNumber[column]]=XO;
                if( winning() != 0 )
                {
                    PlayOut++;
                    if(XO=='O')
                        EVA++;
                    else
                        EVA--;
                    input[PlayNumber[column]]=' ';
                    return -1;
                }
                temp = NegaMax(Depth+1);
                if(column == 1)
                    chance = temp;
                if(chance < temp)
                    chance = temp;
                input[PlayNumber[column]]=' ';
            }
        }
    }
    return -chance;

}
Last edited on
first of all, good job!.

I made it run and it beat me. I never claimed that I was good at connect 4.
But you have successfully created a program that is smarter then me :)

I did have a little problem running it though. INFINITE wasnt defined and you didnt include <string>, and in function getValue() n wasn't initialized which resulted in a run time error. did you run it on Linux? or maybe an IDE that includes those automatically for you, and auto initializes variables?

this line is very dangerousfloat temp = -(100*NegaMax(1)+( (100*EVA)/PlayOut));

you see when this line of code is called PlayOut is 0; which means that you devide by 0. That would be the case but NegaMax() function is evaluated first and changes PlayOut to not be zero. However how can you be so sure that NegaMax() will be called before the devision? It might just be that a different compiler or a new version of the same, or given some optimization flags, the devision will be evaluated before the NegaMax() function. Basically this should be split into 2 lines of code, with perhaps checking for devision by 0



Anyways, an improvement could be a more file oriented design, using object oriented programming. If you would like I am going to be working on a tutorial for a chess program sometime in the future. It will be posted on my site www.proswaggrammer.com its under construction.

If you want to continue to develop AI algorithms. Then you should pick up a book for AI programming/data mining/statistics. Its a very hot and promising programming field, used heavily in advertising campaigns, and statistical predictions, and image processing.

If you want to continue to develop more complex video games on C++, then you should start learning new programming technologies such as SDL/SFML/OpenGL look for tutorials online, there are a lot of very complicated algorithms, (MinMax, shortest path), that video games use. And lots of design patterns that create a good game environment. A simple game can easily exceed 10,000 lines of code. And as you now know, it will be impossible to create without a good design of code. However this field is the MOST difficult path to succeed in, you will become a very good programmer though.

If you want to however just have some fun on modern devices(IPhones,Galaxies). Just try some Java or C# for those stuff. I personally am not attracted to that way.

good luck and keep at it!
Hi :)
Thanks for your reply.
I did have a little problem running it though. INFINITE wasnt defined and you didnt include <string>, and in function getValue() n wasn't initialized which resulted in a run time error. did you run it on Linux? or maybe an IDE that includes those automatically for you, and auto initializes variables?

INFINITE is defined in math.h library but any ways you're right :D I'll define it or I will just put a huge number ..
and about GetValue function its already initialized or I maybe didn't get what you mean :D sry still beginner
1
2
3
4
int winning();
int GetValue(int t);
int AIManager();
int NegaMax(int Depth);



this line is very dangerous float temp = -(100*NegaMax(1)+( (100*EVA)/PlayOut));

you see when this line of code is called PlayOut is 0; which means that you devide by 0

you are absolutely right :D I even had some bugs I never knew the cause .... NegaMax is evaluated first cuz temp = NegaMax().... so its evaluated first and NegaMax changes the Values of PlayOut and EVA but in some cases the value of PlayOut become 0 at the end of the board ... I should check first whether PlayOut is zero or not

unfortunately I know nothing about object oriented programming I'm still beginner .. but I will learn :D

If you want to continue to develop more complex video games on C++


yeah I want to .. I will learn first more about C++ cuz I'm not fully acquainted with it then I'll start with OpenGl
Last edited on
C++ is a great language, and object oriented programming is very important. However for beginners it might be very intimidating learning object oriented programming rules. Truth is that you only really need a small portion of these rules :). If you understand how to make classes/constructors/destructors/inheriting/and polymorphism. Then you will be able to make most designs out there.

however only knowing classes and their constructors will be plenty sufficient for programming games.

OpenGL is a VERY advanced library, famously known for being very hard to begin in, you need many math skills. good luck with that :)
Thanks ^_^
Topic archived. No new replies allowed.