/********************************* Blokus Baicai Seeker Release ** by coolypf ** 2009-05-22 09:24 *********************************/#include <iostream>#include <string>#include <stdlib.h>using namespace std;#define Blank -1int 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;}