/********************************
* Blokus Baicai Seeker Release *
* by coolypf *
* 2009-05-22 09:24 *
********************************/
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
#define Blank -1
int Me,iStart=19;
const int soBlock=1,
soBlank=3,
soFix=30,
soAngle=75;
const char Piece[21][5][5]=
{
{
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,1,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,1,1,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,1,1,1},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,1,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{0,1,1,0,0},
{0,0,1,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0}
},
{
{1,0,0,0,0},
{1,1,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,0,0,0,0},
{1,1,0,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,0,0,0},
{1,0,0,0,0},
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,1,0,0,0},
{1,1,1,0,0},
{0,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,0,0,0,0},
{1,1,1,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{1,1,1,0,0},
{1,0,0,0,0},
{1,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,1,1,0,0},
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,1,1,0,0},
{1,1,0,0,0},
{0,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,1,1,0,0},
{0,1,0,0,0},
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
},
{
{0,1,1,1,0},
{1,1,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}
}
};
const char soSingle[21]=
{
1,3,6,8,9,5,8,
9,9,7,9,7,9,9,
9,9,9,7,9,9,9
};
char b[20][20],p[21][8][5][5];
int step=0,startx,starty;
bool unused[4][21];
bool IsAngle(char [][20],int,int,int);
bool CanPut(char [][20],int,int,int,int,int);
bool CanPutStart(int,int,int,int);
void Init();
void Backup(char [][20],const char [][20]);
int SimpleEvaluate(char [][20],int,int,int,int,int);
int MyEvaluate(char [][20]);
void AI();
void turn(char [][5],const char [][5],int);
void PutStart();
void Put(int,char [][20],int,int,int,int);
int cBlanks(char [][20],bool [][20],int,int,int);
int main()
{
Init();
int n,x,y,p,i,d;
string cmd;
while(1)
{
cin>>cmd;
if(cmd=="[end]") break;
else if(cmd=="[start]")
{
cin>>startx>>starty;
cin>>cmd;
cin>>n;
if(startx==0)
{
if(starty==0)
{
Me=0;
}
else
{
Me=1;
}
}
else
{
if(starty==0)
{
Me=3;
}
else
{
Me=2;
}
}
while(n--)
{
cin>>x>>y>>p>>i>>d;
Put(p,b,x,y,i,d);
unused[p][i]=false;
}
PutStart();
}
else
{
cin>>n;
while(n--)
{
cin>>x>>y>>p>>i>>d;
Put(p,b,x,y,i,d);
unused[p][i]=false;
}
AI();
}
}
return 0;
}
void Init()
{
int i,j,d;
for(i=0;i<20;++i) for(j=0;j<20;++j) b[i][j]=Blank;
for(i=0;i<21;++i) for(d=0;d<8;++d)
turn(p[i][d],Piece[i],d);
for(i=0;i<21;++i) for(j=0;j<4;++j) unused[j][i]=true;
}
void turn(char t[5][5],const char s[5][5],int d)
{
int i,j;
switch(d)
{
case 0:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[i][j];
break;
case 1:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[4-j][i];
break;
case 2:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[4-i][4-j];
break;
case 3:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[j][4-i];
break;
case 4:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[i][4-j];
break;
case 5:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[4-j][4-i];
break;
case 6:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[4-i][j];
break;
case 7:
for(i=0;i<5;++i) for(j=0;j<5;++j) t[i][j]=s[j][i];
break;
}
}
void PutStart()
{
int u,v,d;
for(u=startx-4;u<=startx;++u) for(v=starty-4;v<=starty;++v) for(d=0;d<8;++d)
{
if(CanPutStart(u,v,iStart,d))
{
Put(Me,b,u,v,iStart,d);
unused[Me][iStart]=false;
cout<<u<<' '<<v<<' '<<iStart<<' '<<d<<endl<<flush;
step++;
return;
}
}
}
bool CanPutStart(int x,int y,int i,int d)
{
int u,v;
bool filled=false;
for(u=0;u<5;++u) for(v=0;v<5;++v)
{
if(p[i][d][u][v]==1 &&
(
((x + u) < 0) ||
((y + v) < 0) ||
((x + u) > 19) ||
((y + v) > 19)
)) return false;
if(!filled && p[i][d][u][v]==1 &&
((x + u) == startx) &&
((y + v) == starty)) filled=true;
}
return filled;
}
void Put(int color,char board[20][20],int x,int y,int i,int d)
{
int u,v;
for(u=0;u<5;++u) for(v=0;v<5;++v)
if (p[i][d][u][v] == 1)
board[x + u][y + v] = color;
}
bool IsAngle(char bb[][20],int color,int x,int y)
{
if(bb[x][y]==Blank)
{
if(x>0 && y>0 && bb[x-1][y-1]==color ||
x>0 && y<19 && bb[x-1][y+1]==color ||
x<19 && y>0 && bb[x+1][y-1]==color ||
x<19 && y<19 && bb[x+1][y+1]==color)
{
if(x>0 && bb[x-1][y]==color ||
x<19 && bb[x+1][y]==color ||
y>0 && bb[x][y-1]==color ||
y<19 && bb[x][y+1]==color) return false;
else return true;
}
else return false;
}
else return false;
}
bool CanPut(char bb[20][20],int c,int x,int y,int i,int d)
{
int u,v;
bool corner=false;
for(u=0;u<5;++u) for(v=0;v<5;++v)
{
if(
(p[i][d][u][v] == 1) &&
(
((x + u) < 0) ||
((y + v) < 0) ||
((x + u) > 19) ||
((y + v) > 19) ||
(bb[x + u][y + v] != Blank) ||
(
((y + v + 1) <= 19) &&
(bb[x + u][y + v + 1] == c)
) ||
(
((x + u + 1) <= 19) &&
(bb[x + u + 1][y + v] == c)
) ||
(
((y + v - 1) >= 0) &&
(bb[x + u][y + v - 1] == c)
) ||
(
((x + u - 1) >= 0) &&
(bb[x + u - 1][y + v] == c)
)
)
) return false;
if(
(corner == false) &&
(p[i][d][u][v] == 1) &&
(
(
((x + u - 1) >= 0) &&
((y + v + 1) <= 19) &&
(bb[x + u - 1][y + v + 1] == c)
) ||
(
((x + u + 1) <= 19) &&
((y + v + 1) <= 19) &&
(bb[x + u + 1][y + v + 1] == c)
) ||
(
((x + u + 1) <= 19) &&
((y + v - 1) >= 0) &&
(bb[x + u + 1][y + v - 1] == c)
) ||
(
((x + u - 1) >= 0) &&
((y + v - 1) >= 0) &&
(bb[x + u - 1][y + v - 1] == c)
)
)
) corner=true;
}
return corner;
}
void Backup(char bak[20][20],const char bo[20][20])
{
int i,j;
for(i=0;i<20;++i) for(j=0;j<20;++j) bak[i][j]=bo[i][j];
}
struct PutLog
{
int x,y,i,d,s;
} plog[100000];
int cmpr(const void *p,const void *q)
{
return ((PutLog *)q)->s-((PutLog *)p)->s;
}
void AI()
{
int xm,ym,im=-1,dm,x,y,i,p,d,smax=-100000,s,sp,spmax;
int xp,yp,ip,dp,xpm,ypm,ipm[4]={-1,-1,-1,-1},ipma,dpm;
int puts=0,t;
unused[Me][im]=false;
char bb[20][20];
for(i=0;i<21;++i) if(unused[Me][i]) for(x=-4;x<20;++x) for(y=-4;y<20;++y) for(d=0;d<8;++d) if(CanPut(b,Me,x,y,i,d))
{
Backup(bb,b);
Put(Me,bb,x,y,i,d);
plog[puts].s=MyEvaluate(bb)+soSingle[i]*soSingle[i]*soSingle[i]*soBlock;
plog[puts].x=x;plog[puts].y=y;plog[puts].i=i;plog[puts].d=d;
puts++;
}
qsort(plog,puts,sizeof(PutLog),cmpr);
if(step>2) for(t=0;t<5 && t<puts;++t)
{
s=plog[t].s*2;
Backup(bb,b);
Put(Me,bb,plog[t].x,plog[t].y,plog[t].i,plog[t].d);
for(p=(Me+1)%4;p!=Me;p=(p+1)%4)
{
spmax=-100000;
for(ip=0;ip<21;++ip) if(unused[p][ip]) for(xp=-4;xp<20;++xp)
for(yp=-4;yp<20;++yp) for(dp=0;dp<8;++dp) if(CanPut(bb,p,xp,yp,ip,dp))
{
sp=SimpleEvaluate(bb,p,xp,yp,ip,dp);
if(sp>spmax)
{
spmax=sp;
xpm=xp;ypm=yp;ipm[p]=ip;dpm=dp;
}
}
if(ipm[p]!=-1)
{
Put(p,bb,xpm,ypm,ipm[p],dpm);
unused[p][ipm[p]]=false;
}
}
s+=MyEvaluate(bb)*3;
if(step>7)
{
p=Me;
{
ipma=-1;
spmax=-100000;
for(ip=0;ip<21;++ip) if(unused[p][ip]) for(xp=-4;xp<20;++xp)
for(yp=-4;yp<20;++yp) for(dp=0;dp<8;++dp) if(CanPut(bb,p,xp,yp,ip,dp))
{
sp=SimpleEvaluate(bb,p,xp,yp,ip,dp);
if(sp>spmax)
{
spmax=sp;
xpm=xp;ypm=yp;ipma=ip;dpm=dp;
}
}
if(ipma!=-1) Put(p,bb,xpm,ypm,ipma,dpm);
}
for(p=(Me+1)%4;p!=Me;p=(p+1)%4)
{
ipma=-1;
spmax=-100000;
for(ip=0;ip<21;++ip) if(unused[p][ip]) for(xp=-4;xp<20;++xp)
for(yp=-4;yp<20;++yp) for(dp=0;dp<8;++dp) if(CanPut(bb,p,xp,yp,ip,dp))
{
sp=SimpleEvaluate(bb,p,xp,yp,ip,dp);
if(sp>spmax)
{
spmax=sp;
xpm=xp;ypm=yp;ipma=ip;dpm=dp;
}
}
if(ipma!=-1) Put(p,bb,xpm,ypm,ipma,dpm);
}
for(p=0;p<4;++p) if(ipm[p]>=0) unused[p][ipm[p]]=true;
s+=MyEvaluate(bb)*3;
}
if(s>smax)
{
smax=s;
im=plog[t].i;dm=plog[t].d;xm=plog[t].x;ym=plog[t].y;
}
}
else
{
xm=plog[0].x;ym=plog[0].y;dm=plog[0].d;im=plog[0].i;
}
if(im!=-1)
{
Put(Me,b,xm,ym,im,dm);
cout<<xm<<' '<<ym<<' '<<im<<' '<<dm<<endl<<flush;
unused[Me][im]=false;
step++;
}
}
int cx,cy;
int SimpleEvaluate(char bo[20][20],int c,int x,int y,int i,int d)
{
char bb[20][20];
Backup(bb,bo);
Put(c,bb,x,y,i,d);
int s=soSingle[i]*soSingle[i]*soSingle[i]*soBlock,u,v;
int angles=0,fixes=0;
for(u=x;u<x+5;++u) for(v=y;v<y+5;++v) if(bb[u][v]==c)
{
if(u>0 && bb[u-1][v]!=c && bb[u-1][v]!=Blank) fixes++;
if(v>0 && bb[u][v-1]!=c && bb[u][v-1]!=Blank) fixes++;
if(u<19 && bb[u+1][v]!=c && bb[u+1][v]!=Blank) fixes++;
if(v<19 && bb[u][v+1]!=c && bb[u][v+1]!=Blank) fixes++;
}
s+=soFix*fixes;
int t;
for(u=x;u<x+5;++u) for(v=y;v<y+5;++v)
{
if(bb[u][v]==Blank) for(t=0;t<4;++t)
{
if(t==c)
{
if(IsAngle(bb,c,u,v)) angles+=5;
}
else if(IsAngle(bb,t,u,v)) angles--;
}
}
s+=soAngle*angles;
return s;
}
int MyEvaluate(char bb[20][20])
{
int s,x,y,u,v,t;
int fixes=0,blanks=0;
if(step>2) s=0;
else
{
double dis,dismin=10000;
for(x=0;x<20;++x) for(y=0;y<20;++y) if(bb[x][y]==Me)
{
dis=(9.5-x)*(9.5-x)+(9.5-y)*(9.5-y);
if(dis<dismin) dismin=dis;
}
s=-dismin*50;
}
for(u=0;u<20;++u) for(v=0;v<20;++v) if(bb[u][v]==Me)
{
if(u>0 && bb[u-1][v]!=Me && bb[u-1][v]!=Blank) fixes++;
if(v>0 && bb[u][v-1]!=Me && bb[u][v-1]!=Blank) fixes++;
if(u<19 && bb[u+1][v]!=Me && bb[u+1][v]!=Blank) fixes++;
if(v<19 && bb[u][v+1]!=Me && bb[u][v+1]!=Blank) fixes++;
}
s+=soFix*fixes;
{
bool marked[20][20]={0};
for(x=0;x<20;++x) for(y=0;y<20;++y)
{
if(bb[x][y]==Blank && !marked[x][y] && IsAngle(bb,Me,x,y))
{
cx=x;cy=y;
blanks+=(cBlanks(bb,marked,x,y,Me)*8);
}
}
}
for(t=0;t<4;++t) if(t!=Me)
{
bool marked[20][20]={0};
for(x=0;x<20;++x) for(y=0;y<20;++y) if(bb[x][y]==Blank)
{
if(!marked[x][y] && IsAngle(bb,t,x,y))
{
cx=x;cy=y;
blanks-=cBlanks(bb,marked,x,y,t);
}
}
}
s+=soBlank*blanks;
return s;
}
int cBlanks(char bb[20][20],bool marked[20][20],int x,int y,int color)
{
if(x<cx-4 || x>cx+4 || y<cy-4 || y>cy+4) return 0;
marked[x][y]=true;
if(x>0 && bb[x-1][y]==color
|| y>0 && bb[x][y-1]==color
|| x<19 && bb[x+1][y]==color
|| y<19 && bb[x][y+1]==color) return 0;
int c=1;
if(x>0 && !marked[x-1][y] && bb[x-1][y]==Blank) c+=cBlanks(bb,marked,x-1,y,color);
if(y>0 && !marked[x][y-1] && bb[x][y-1]==Blank) c+=cBlanks(bb,marked,x,y-1,color);
if(x<19 && !marked[x+1][y] && bb[x+1][y]==Blank) c+=cBlanks(bb,marked,x+1,y,color);
if(y<19 && !marked[x][y+1] && bb[x][y+1]==Blank) c+=cBlanks(bb,marked,x,y+1,color);
return c;
}
角鬥士(Blokus)博弈程序
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.