角鬥士(Blokus)博弈程序

/********************************
* 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;
}
發佈了28 篇原創文章 · 獲贊 8 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章