More Related Content Similar to C++ Connect Four AI using MiniMax algorithm Similar to C++ Connect Four AI using MiniMax algorithm (20) C++ Connect Four AI using MiniMax algorithm1. #include<iostream>
#include<string>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cmath>
#include<vector>
#include<sstream>
#include<stack>
#include<queue>
#include<cstring>
#include<fstream>
#include<climits>
#define pb push_back
#define LL long long
#define OUTPUT_TO_FILE 1
#define s(n) scanf("%d",&n)
#define sl(n) scanf("%lld",&n)
#define sf(n) scanf("%lf",&n)
#define ss(n) scanf("%s",n)
#define MAX_LEVEL 5
using namespace std;
class node
{
public:
int board[6][7];
};
typedef struct
{
int val,move;
}ret;
int team_no;
void print(node start){
int i,j;
for(i=0;i<6;i++){
for(j=0;j<7;j++)
cout<<start.board[i][j]<<" ";
cout<<endl;
}
}
int weight(vector<int> v){
if(v.size()<=3)
return 0;
int i,j;
int Weights[] = { 1, 5, 100, 10000,2, 6, 200, 15000 };
int score = 0;
for(i=0;i<v.size()-3;i++){
2. int c = 0;
int p = 0;
int dual = 0;
for (j = 0; j < 4; j++){
if (v[i + j] == team_no) c++; //TODO Make sure that it looks at it's own identity
else if (v[i + j] ==3 - team_no) p++;
else if (v[i + j] == 12) dual++;
}
if ((c > 0) && (p == 0))
{
c += dual;
//Computer opportunity
if (c == 4) return Weights[3]; //Win
score += ((c/3)*Weights[2]) + ((c/2)*Weights[1]) + Weights[0];
}
else if ((c == 0) && (p > 0))
{
p += dual;
//Player opportunity
if (p == 4) return -1*Weights[7]; //Win
score -= ((p / 3) * Weights[6]) + ((p / 2) * Weights[5]) + Weights[4];
}
}
return score;
}
int evaluate(node start){
int val = 0;
int i,j,k;
//rows
vector<int> v;
for(i=5;i>=0;i--){
v.clear();
for(j=0;j<=6;j++)
v.pb(start.board[i][j]);
val += weight(v);
}
//cout<<val<<" after rows"<<endl;
//columns
for(j=0;j<=6;j++){
v.clear();
for(i=0;i<=5;i++){
v.pb(start.board[i][j]);
}
val += weight(v);
}
//cout<<val<<" after columns"<<endl;
3. //daigonals
for(k=0;k<=5;k++){
i = k;
j = 0;
v.clear();
while(i>=0){
v.pb(start.board[i][j]);
i--;j++;
}
val += weight(v);
}
for(k=1;k<=6;k++){
i = 5;j = k;
v.clear();
while(j<=6){
v.pb(start.board[i][j]);
j++;i--;
}
val += weight(v);
}
//cout<<val<<" after diagonals"<<endl;
//2nd set of diagonals
for(k=5;k>=0;k--){
i = k;
j = 0;
v.clear();
while(i<=5){
v.pb(start.board[i][j]);
i++;j++;
}
val += weight(v);
}
for(k=1;k<=6;k++){
j = k;
i = 0;
v.clear();
while(j<=6){
v.pb(start.board[i][j]);
i++;j++;
}
val += weight(v);
}
return val;
}
bool endgame(node start){
int temp;
temp = evaluate(start);
4. //cout<<temp<<endl;
if(temp>=7000||temp<=-7000)
return true;
else
return false;
}
bool possible(node start,int j){
int i;
for(i = 0;i <= 5;i++){
if(start.board[i][j]==0)
return true;
}
return false;
}
node makemove(node start,int j,int team,int disc){
int i = 0,k;
while(start.board[i][j]==0&&i<=5)
i++;
i--;
if(disc==5)
start.board[i][j] = team;
else if(disc==4)
start.board[i][j] = 12;
else if(disc==1){
for(j=0;j<=6;j++){
for(k=i-1;k>=0;k--){
start.board[k+1][j] = start.board[k][j];
}
start.board[0][j] = 0;
}
}
else if(disc==2){
for(i=0;i<=5;i++)
start.board[i][j] = 0;
}
else if(disc==3){
start.board[i][j] = 0;
//clear all the neighbours
int t1[] = {0,0,-1,-1,-1,0,1,1,1};
int t2[] = {0,-1,-1,0,1,1,1,0,-1};
for(k=0;k<=8;k++){
int u1,v1;
u1 = t1[k] + i;
v1 = t2[k] + j;
if(u1>=0&&u1<=5&&v1>=0&&v1<=6){
start.board[u1][v1] = 0;
}
}
vector<int> a;
if(j-1>=0){
k = i-2;
5. while(k>=0){
if(start.board[k][j-1]!=0)
a.pb(start.board[k][j-1]);
start.board[k][j-1]=0;
k--;
}
k = i;
if(i+1<=5)
k = k+1;
int l = 0;
while(l<a.size()){
start.board[k][j-1] = a[l];
l++;k--;
}
}
a.clear();
if(j+1<=6){
k = i-2;
while(k>=0){
if(start.board[k][j+1]!=0)
a.pb(start.board[k][j+1]);
start.board[k][j+1]=0;
k--;
}
k = i;
if(i+1<=5)
k = k+1;
int l = 0;
while(l<a.size()){
start.board[k][j+1] = a[l];
l++;k--;
}
}
}
return start;
}
ret Min(node start,int level,int alpha,int beta,int disc);
ret Max(node start,int level,int alpha,int beta,int disc){
//cout<<"Level ="<<level<<endl;
//print(start);
//system("pause");
if(level == MAX_LEVEL||endgame(start)){
//cout<<"ho";
ret leaf;
leaf.val = evaluate(start);
leaf.move = -1;
//cout<<"Value = "<<leaf.val<<endl;
//system("pause");
return leaf;
}
6. ret best;
best.val = INT_MIN;
for(int i = 0;i<7;i++){
if(possible(start,i)){
node newboard;
ret temp;
newboard = makemove(start,i,team_no,disc);
temp = Min(newboard,level+1,alpha,beta,5);
if(temp.val > best.val){
best.val = temp.val;
best.move = i;
}
alpha = max(alpha,temp.val);
if(alpha > beta)
break;
}
}
return best;
}
ret Min(node start,int level,int alpha,int beta,int disc){
//cout<<"Level ="<<level<<endl;
//print(start);
//system("pause");
ret best;
best.val = INT_MAX;
for(int i = 0;i<7;i++){
if(possible(start,i)){
node newboard;
ret temp;
newboard = makemove(start,i,3 - team_no,5);
temp = Max(newboard,level+1,alpha,beta,5);
if(temp.val < best.val){
best.val = temp.val;
best.move = i;
}
beta = min(beta,temp.val);
if(alpha > beta)
break;
}
}
return best;
}
int main()
{
int i,j;
///////////////////////////////////////////////////READING
INPUT////////////////////////////////////////////////////////////////////////////
7. /*SECTION I
Reading Board Number and Team no from the file*/
ifstream fin;
ofstream fout;
fin.open("team_no.txt");
fin>>team_no;
fin.close();
fin.open("board.txt");
node start;
for(i=5;i>=0;i--){
for(j=0;j<7;j++){
int token;
fin>>token;
start.board[i][j] = token;
}
}
fin.close();
/*end*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////
//////////////////////////////////////////////////////MAKING THE DUAL COLOR
MOVE//////////////////////////////////////////////////////////
int moves,column,disc; //This will hold the column and disc of my move
int r,c,n,d;
fin.open("moves.txt");
fin>>moves>>r>>c>>n>>d;
if(moves==0)
disc = 4;
else
disc = 5;
/*if(moves==5)
disc = 4;
else if(moves==6&&d!=1)
disc = 4;
else if(moves==7&&d!=1)
disc = 4;
else if(moves==8&&d!=1)
disc = 4;
else
disc = 5;*/
fin.close();
ret ans = Max(start,1,INT_MIN,INT_MAX,disc);
if(disc==4&&ans.val <= -10000&&moves!=8){
disc = 5;
8. ans = Max(start,1,INT_MIN,INT_MAX,disc);
}
else if(!(disc==4&&moves==8))
{
////////////////////////////////////////////////////MAKING THE CLEAR ROW,COL,NEIGHBOUR
MOVES/////////////////////////////////////////////
//now the dual disc is used
if(ans.val <= -10000){
ret temp;
if(r!=1){
temp = Max(start,1,INT_MIN,INT_MAX,1);
if(temp.val > ans.val){
disc = 1;
ans.val = temp.val;
ans.move = temp.move;
}
}
if(c!=1){
temp = Max(start,1,INT_MIN,INT_MAX,2);
if(temp.val > ans.val){
disc = 2;
ans.val = temp.val;
ans.move = temp.move;
}
}
if(n!=1){
temp = Max(start,1,INT_MIN,INT_MAX,3);
if(temp.val > ans.val){
disc = 3;
ans.val = temp.val;
ans.move = temp.move;
}
}
}
else
{
ret temp;
if(r!=1){
temp = Max(start,1,INT_MIN,INT_MAX,1);
if(temp.val > ans.val && temp.val > 8000){
disc = 1;
ans.val = temp.val;
ans.move = temp.move;
}
}
if(c!=1){
temp = Max(start,1,INT_MIN,INT_MAX,2);
if(temp.val > ans.val && temp.val > 8000){
9. disc = 2;
ans.val = temp.val;
ans.move = temp.move;
}
}
if(n!=1){
temp = Max(start,1,INT_MIN,INT_MAX,3);
if(temp.val > ans.val && temp.val > 8000){
disc = 3;
ans.val = temp.val;
ans.move = temp.move;
}
}
}
}
////////////////////////////////////MAKING THE FINAL
MOVE////////////////////////////////////////////////////////////////////////////////
column = ans.move + 1;
cout<<ans.move<<endl;
fout.open("output.txt");
cout<<disc<<" "<<column<<" "<<ans.val<<endl;
fout<<disc<<" "<<column;
}