/******************************** * 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; }