Solution -「THUPC 2019」Duckchess

cirnovsky /

§ Description

Link.

大模拟是不可能给你概括题意的。

§ Solution

(据说鸭棋题解用这个标题很吉利)(这里是被点名批评的 长度 19k 的打法)(先说好代码里 Chinglish 满地,尽量不要吐槽吧……)


首先我们不需要仔细阅读每一种棋的判定方法及其走法,写的时候照抄即可。

理一下大体逻辑。首先开一个全局的棋盘 vector<vector<string> > evemap;,一个 over 表示棋局是否结束。

然后是棋手的结构体:

struct chess
{
	string color;
	string getcolor(int x,int y);
	string getchess(int x,int y);
	bool outside(int x,int y);
	bool exist(int x,int y);
	bool thereok(int x,int y);
	bool occaptain(int sx,int sy,int tx,int ty);
	bool ocguard(int sx,int sy,int tx,int ty);
	bool ocelephant(int sx,int sy,int tx,int ty);
	bool ochorse(int sx,int sy,int tx,int ty);
	bool occar(int sx,int sy,int tx,int ty);
	bool ocduck(int sx,int sy,int tx,int ty);
	bool ocsoldier(int sx,int sy,int tx,int ty);
	string checkgoi();
	bool checkove();
	void moving(int sx,int sy,int tx,int ty);
	string final(string s);
	vector<string> movecaptain(int sx,int sy,int tx,int ty);
	vector<string> moveguard(int sx,int sy,int tx,int ty);
	vector<string> moveelephant(int sx,int sy,int tx,int ty);
	vector<string> movehorse(int sx,int sy,int tx,int ty);
	vector<string> movecar(int sx,int sy,int tx,int ty);
	vector<string> moveduck(int sx,int sy,int tx,int ty);
	vector<string> movesoldier(int sx,int sy,int tx,int ty);
	vector<string> execute(int sx,int sy,int tx,int ty); 
}redplay,blueplay;

string color 表示棋手的颜色。

这里先来解释一下各个函数的含义:

  • oc-chessmove-chess 形式:

    • bool oc-chess(sx,sy,tx,ty):这个表示 chess 棋从 (sx,sy)(s_{x},s_{y}) 走到 (tx,ty)(t_{x},t_{y}) 是否合法。
    • vector<string> move-chess(sx,sy,tx,ty):这个标识 chess 棋从 (sx,sy)(s_{x},s_{y}) 走到 (tx,ty)(t_{x},t_{y}) 最终返回的东西。
  • 其他的一些杂函数:

    • string getcolor(x,y):棋盘位置 (x,y)(x,y) 的棋的颜色,如果没有则返回 empty
    • string getchess(x,y):棋盘位置 (x,y)(x,y) 的棋的棋子类型,如果没有则返回 empty
    • bool outside(int x,int y)(x,y)(x,y) 是否出界。
    • bool exist(int x,int y)(x,y)(x,y) 是否存在任意一方的棋子。
    • bool thereok(int x,int y)(x,y)(x,y) 是否不存在同色棋子且没有出界。
    • string checkgoi():检查是否有将军。(通过遍历棋盘实现)
    • bool checkove():是否有任意一方的将军被吃。
    • void moving(int sx,int sy,int tx,int ty):把 (sx,sy)(s_{x},s_{y}) 的棋子移到 (tx,ty)(t_{x},t_{y})
    • string final(string s):我棋盘存储棋子的形式是 color-chess,这个函数的作用就是转为题目的形式 color chess
    • void execute(sx,sy,tx,ty):处理一次询问。

结构差不多就这里,接下来说一下具体实现。

  • 首先用个 void mapinitial() 初始化棋盘。
  • 然后都询问,处理询问,调用 execute()
  • 输出。

好的我承认这个实现方法特别烂。

/*
function(vector<string>)(with prefix 'move') result:
	"invcom": invalid command
	"color-chess": the chess(opposite) which is eaten
	"beaten": have the Jiangjun been complete
	"over": have the game been over
vector[0][1][2][3]
*/
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int h=10,w=9;
int over;
//string evemap[20][20];
vector<vector<string> > evemap;
void printmap()
{
	for(int i=0;i<h;++i)
	{
		for(int j=0;j<w;++j)	printf("%14s",evemap[i][j].c_str()),printf("[%d %d]",i,j);
		printf("\n");
	}
}
struct chess
{
	string color;
	string getcolor(int x,int y)
	/*
		result:
			"empty": empty place
			"red": red chess
			"blue": blue chess
	*/
	{
		string res,s=evemap[x][y];
		if(s=="empty")	return "empty";
		else
		{
			for(int i=0;i<s.length();++i)
			{
				if(s[i]=='-')	break;
				res+=s[i];
			}
			return res;
		}
	}
	string getchess(int x,int y)
	/*
		result:
			each string has the same meaning as 'evemap'
	*/
	{
		string res,s=evemap[x][y];
		if(s=="empty")	return "empty";
		else
		{
			int st=0;
			for(int i=0;i<s.length();++i)
			{
				if(st)	res+=s[i];
				else if(s[i]=='-')	st=1;
			}
			return res;
		}
	}
	bool outside(int x,int y)
	{
		if(x<0||x>=h||y<0||y>=w)	return 1;
		else	return 0;
	}
	bool exist(int x,int y)
	{
		if(getchess(x,y)=="empty")	return 0;
		else	return 1;
	}
	bool thereok(int x,int y)
	/*
		result:
			1: this place is walkable
			0: this place is occupied or (x,y) is out of range
		means:
			1. isn't out of range
			2. (x,y) has no same color chess or is empty
	*/
	{
		if(outside(x,y))	return 0;
		else if(evemap[x][y]!="empty"&&getcolor(x,y)==color)	return 0;
		else	return 1;
	}
	bool occaptain(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				if(thereok(sx+i,sy)&&tx==(sx+i)&&ty==sy)	return 1;
				else if(thereok(sx,sy+i)&&tx==sx&&ty==(sy+i))	return 1;
			}
		}
		return 0;
	}
	bool ocguard(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				if(thereok(sx+i,sy+i)&&tx==(sx+i)&&ty==(sy+i))	return 1;
				if(thereok(sx+i,sy-i)&&tx==(sx+i)&&ty==(sy-i))	return 1;
			}
		}
		return 0;
	}
	bool ocelephant(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				for(int j=-1;j<=1;++j)
				{
					if(j)
					{
						if(thereok(sx+i,sy+j))
						{
							if(thereok(sx+(i<<1),sy+(j<<1))&&tx==(sx+(i<<1))&&ty==(sy+(j<<1)))	return 1;
						}
					}
				}
			}
		}
		return 0;
	}
	bool ochorse(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				for(int j=-1;j<=1;++j)
				{
					if(j)
					{
//						printf("[{%d %d} {%d %d} {%d %d %d}]\n",sx,sy+j,sx+i,sy+(j<<1),outside(sx,sy+j),exist(sx,sy+j),!outside(sx,sy+j)&&!exist(sx,sy+j));
						if(!outside(sx+i,sy)&&!exist(sx+i,sy))
						{
							if(thereok(sx+(i<<1),sy+j)&&tx==(sx+(i<<1))&&ty==(sy+j))	return 1;
						}
						if(!outside(sx,sy+j)&&!exist(sx,sy+j))
						{
							if(thereok(sx+i,sy+(j<<1))&&tx==(sx+i)&&ty==(sy+(j<<1)))	return 1;
						}
					}
				}
			}
		}
		return 0;
	}
	bool occar(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		if(sx==tx)
		{
			int delta;
			if(sy<ty)	delta=1;
			else	delta=-1;
			for(int j=sy;j^ty;j+=delta)
			{
				if((j^sy)&&exist(sx,j))	return 0;
			}
			return 1;
		}
		else if(sy==ty)
		{
			int delta;
			if(sx<tx)	delta=1;
			else	delta=-1;
			for(int i=sx;i^tx;i+=delta)
			{
//				printf("[{%d %d}]\n",i,sy);
				if((i^sx)&&exist(i,sy))	return 0;
			}
			return 1;
		}
		else	return 0;
	}
	bool ocduck(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				for(int j=-1;j<=1;++j)
				{
					if(j)
					{
						if(!outside(sx+(i<<1),sy+j)&&!exist(sx+(i<<1),sy+j)&&!outside(sx+i,sy)&&!exist(sx+i,sy))
						{
//							printf("[{%d %d} {%d %d} {%d %d} {%d %d} {%d %d} {%d %d}]\n",sx,sy,tx,ty,sx+i,sy,sx+(i<<1),sy+j,sx+((i<<1)+i),sy+(j<<1),thereok(sx+((i<<1)+i),sy+(j<<1)),tx==(sx+((i<<1)+i)&&ty==(sy+(j<<1))));
							if(thereok(sx+((i<<1)+i),sy+(j<<1))&&tx==(sx+((i<<1)+i))&&ty==(sy+(j<<1)))	return 1;
						}
						if(!outside(sx+i,sy+(j<<1))&&!exist(sx+i,sy+(j<<1))&&!outside(sx,sy+j)&&!exist(sx,sy+j))
						{
							if(thereok(sx+(i<<1),sy+((j<<1)+j))&&tx==(sx+(i<<1))&&ty==(sy+((j<<1)+j)))	return 1;
						}
					}
				}
			}
		}
		return 0;
	}
	bool ocsoldier(int sx,int sy,int tx,int ty)
	{
		if(!thereok(tx,ty))	return 0;
		for(int i=-1;i<=1;++i)
		{
			if(i)
			{
				if(thereok(sx+i,sy)&&tx==(sx+i)&&ty==sy)	return 1;
				if(thereok(sx,sy+i)&&tx==sx&&ty==(sy+i))	return 1;
				if(thereok(sx+i,sy+i)&&tx==(sx+i)&&ty==(sy+i))	return 1;
				if(thereok(sx+i,sy-i)&&tx==(sx+i)&&ty==(sy-i))	return 1;
			}
		}
		return 0;
	}
	string checkgoi()
	/*
		result:
			"not": Jiangjun didn't happened
			"red": the RED general has been Jiangjuned
			"blue": the BLUE general has been Jiangjuned
	*/
	{
		if(over)	return "not";
		for(int i=0;i<h;++i)
		{
			for(int j=0;j<w;++j)
			{
				string curcol=getcolor(i,j),curche=getchess(i,j),revcol;
				if(curcol=="red")	revcol="blue";
				else if(curcol=="blue")	revcol="red";
				else	revcol="empty";
				if(curche!="empty")
				{
					if(curche=="captain")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								if(!outside(i+k,j))
								{
									string nxtcol=getcolor(i+k,j),nxtche=getchess(i+k,j);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
								if(!outside(i,j+k))
								{
									string nxtcol=getcolor(i,j+k),nxtche=getchess(i,j+k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
							}
						}
					}
					else if(curche=="guard")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								if(!outside(i+k,j+k))
								{
									string nxtcol=getcolor(i+k,j+k),nxtche=getchess(i+k,j+k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
								if(!outside(i+k,j-k))
								{
									string nxtcol=getcolor(i+k,j-k),nxtche=getchess(i+k,j-k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
							}
						}
					}
					else if(curche=="elephant")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								for(int l=-1;l<=1;++l)
								{
									if(l)
									{
										if(!outside(i+(k<<1),j+(l<<1))&&!exist(i+k,j+l))
										{
											string nxtcol=getcolor(i+(k<<1),j+(l<<1)),nxtche=getchess(i+(k<<1),j+(l<<1));
											if(nxtcol==revcol&&nxtche=="captain")	return nxtcol; 
										}
									}
								}
							}
						}
					}
					else if(curche=="horse")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								for(int l=-1;l<=1;++l)
								{
									if(l)
									{
										if(!outside(i+(k<<1),j+l)&&!exist(i+k,j))
										{
											string nxtcol=getcolor(i+(k<<1),j+l),nxtche=getchess(i+(k<<1),j+l);
											if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
										}
										if(!outside(i+k,j+(l<<1))&&!exist(i,j+l))
										{
											string nxtcol=getcolor(i+k,j+(l<<1)),nxtche=getchess(i+k,j+(l<<1));
											if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
										}
									}
								}
							}
						}
					}
					else if(curche=="car")
					{
						for(int k=i;k<h;++k)
						{
							if(!outside(k,j))
							{
								string nxtcol=getcolor(k,j),nxtche=getchess(k,j);
								if(nxtche!="empty")
								{
									if(nxtche=="captain")	return nxtcol;
									break;
								}
							}
						}
						for(int l=j;l<w;++l)
						{
							if(!outside(i,l))
							{
								string nxtcol=getcolor(i,l),nxtche=getchess(i,l);
								if(nxtche!="empty")
								{
									if(nxtche=="captain")	return nxtcol;
									break;
								}
							}
						}
					}
					else if(curche=="duck")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								for(int l=-1;l<=1;++l)
								{
									if(l)
									{
										if(!outside(i+((k<<1)+k),j+(l<<1))&&!exist(i+(k<<1),j+l)&&!exist(i+k,j))
										{
											string nxtcol=getcolor(i+((k<<1)+k),j+(l<<1)),nxtche=getchess(i+((k<<1)+k),j+(l<<1));
											if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
										}
										if(!outside(i+(k<<1),j+((l<<1)+l))&&!exist(i+k,j+(l<<1))&&!exist(i,j+l))
										{
											string nxtcol=getcolor(i+(k<<1),j+((l<<1)+l)),nxtche=getchess(i+(k<<1),j+((l<<1)+l));
											if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
										}
									}
								}
							}
						}
					}
					else if(curche=="soldier")
					{
						for(int k=-1;k<=1;++k)
						{
							if(k)
							{
								if(!outside(i+k,j))
								{
									string nxtcol=getcolor(i+k,j),nxtche=getchess(i+k,j);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
								if(!outside(i,j+k))
								{
									string nxtcol=getcolor(i,j+k),nxtche=getchess(i,j+k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
								if(!outside(i+k,j+k))
								{
									string nxtcol=getcolor(i+k,j+k),nxtche=getchess(i+k,j+k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
								if(!outside(i+k,j-k))
								{
									string nxtcol=getcolor(i+k,j-k),nxtche=getchess(i+k,j-k);
									if(nxtcol==revcol&&nxtche=="captain")	return nxtcol;
								}
							}
						}
					}
				}
			}
		}
		return "not";
	}
	bool checkove()
	/*
		result:
			0: the game isn't over
			1: the game is still alive
	*/
	{
		bool red=0,blue=0;
		for(int i=0;i<h;++i)
		{
			for(int j=0;j<w;++j)
			{
				if(getchess(i,j)=="captain")
				{
//					printf("[%d %d]\n",i,j);
					if(getcolor(i,j)=="red")	red=1;
					else	blue=1;
				}
			}
		}
		return !red||!blue;
	}
	void moving(int sx,int sy,int tx,int ty)
	{
		evemap[tx][ty]=evemap[sx][sy];
		evemap[sx][sy]="empty";
	}
	string final(string s)
	{
		if(s=="empty")	return "empty";
		else
		{
			for(int i=0;i<s.length();++i)
			{
				if(s[i]=='-')
				{
					s[i]=' ';
					break;
				}
			}
			return s;
		}
	}
	vector<string> movecaptain(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
//		printf("%s %s\n",getcolor(sx,sy).c_str(),color.c_str());
		if(over||!occaptain(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> moveguard(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!ocguard(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> moveelephant(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!ocelephant(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> movehorse(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!ochorse(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> movecar(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!occar(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> moveduck(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!ocduck(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> movesoldier(int sx,int sy,int tx,int ty)
	{
		vector<string> res;
		if(over||!ocsoldier(sx,sy,tx,ty)||getcolor(sx,sy)!=color)
		{
			res.push_back("Invalid command");
			return res;
		}
		else
		{
			string cur,eat,goi,ove,col,lor;
			col=getcolor(sx,sy);
			lor=getcolor(tx,ty);
			cur=getchess(sx,sy);
			eat=getchess(tx,ty);
            if(lor=="empty")    lor="";
			if(eat=="empty")	eat="NA";
			moving(sx,sy,tx,ty);
			if(checkgoi()!="not")	goi="yes";
			else	goi="no";
			if(checkove())
			{
				over=1;
				ove="yes";
			}
			else	ove="no";
			cur=final(cur);
			res.push_back(col+" "+cur);
			if(lor!="") res.push_back(lor+" "+eat);
            else    res.push_back(eat);
			res.push_back(goi);
			res.push_back(ove);
			return res;
		}
	}
	vector<string> execute(int sx,int sy,int tx,int ty)
	{
		if(getchess(sx,sy)=="captain")	return movecaptain(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="guard")	return moveguard(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="elephant")	return moveelephant(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="horse")	return movehorse(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="car")	return movecar(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="duck")	return moveduck(sx,sy,tx,ty);
		else if(getchess(sx,sy)=="soldier")	return movesoldier(sx,sy,tx,ty);
		else	return vector<string>({"Invalid command"});
	}
}redplay,blueplay;
void mapinitial()
{
	evemap.resize(20);
	static vector<string> zero({"red-car","red-horse","red-elephant","red-guard","red-captain","red-guard","red-elephant","red-horse","red-car"});
	static vector<string> one({"empty","empty","empty","empty","empty","empty","empty","empty","empty"});
	static vector<string> two({"red-duck","empty","empty","empty","empty","empty","empty","empty","red-duck"});
	static vector<string> three({"red-soldier","empty","red-soldier","empty","red-soldier","empty","red-soldier","empty","red-soldier"});
	static vector<string> four({"empty","empty","empty","empty","empty","empty","empty","empty","empty"});
	static vector<string> five({"empty","empty","empty","empty","empty","empty","empty","empty","empty"});
	static vector<string> six({"blue-soldier","empty","blue-soldier","empty","blue-soldier","empty","blue-soldier","empty","blue-soldier"});
	static vector<string> seven({"blue-duck","empty","empty","empty","empty","empty","empty","empty","blue-duck"});
	static vector<string> eight({"empty","empty","empty","empty","empty","empty","empty","empty","empty"});
	static vector<string> nine({"blue-car","blue-horse","blue-elephant","blue-guard","blue-captain","blue-guard","blue-elephant","blue-horse","blue-car"});
	evemap[0]=zero;
	evemap[1]=one;
	evemap[2]=two;
	evemap[3]=three;
	evemap[4]=four;
	evemap[5]=five;
	evemap[6]=six;
	evemap[7]=seven;
	evemap[8]=eight;
	evemap[9]=nine;
	for(int i=0;i<evemap.size();++i)	evemap[i].resize(20);
}
int main()
{
// 	freopen("duck.in","r",stdin);
//	freopen("own.out","w",stdout);
	mapinitial();
	redplay.color="red";
	blueplay.color="blue";
	int q,now=1;
	scanf("%d",&q);
//	printmap();
	for(int i=1;i<=q;++i)
	{
		int sx,sy,tx,ty;
		scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
//		printf("{%d %d %d %d}\n",sx,sy,tx,ty);
		vector<string> ret;
		if(now&1)	ret=redplay.execute(sx,sy,tx,ty);
		else	ret=blueplay.execute(sx,sy,tx,ty);
		if(ret[0]=="Invalid command")	printf("Invalid command\n");
		else
		{
			printf("%s;%s;%s;%s\n",ret[0].c_str(),ret[1].c_str(),ret[2].c_str(),ret[3].c_str());
			if(ret[3]=="yes")	over=1;
			now++;
		}
// 		if(i>=q-1)
// 		printmap();
	}
	return 0;
}