⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chess_simulation.cpp

📁 这个一道ACM竞赛中的复杂模拟程序。按照国际象棋的规则
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			if(y==0) 
				black0rookmoved=true;			// the black 0 rook has moved
			if(y==7)
				black7rookmoved=true;			// the black 7 rook has moved
				
		}

}

// move a chess from the document 
void MakeMove(TBoard b, char *mv,TSide side)
{
	int x,y,x2,y2;
	GetPosition(mv,x2,y2);// get the position (x2,y2) from the document
	if(b[x2][y2].side==side)
	{
		result=ILLEGAL;
		return;
	}


	x=-1;
	GetSourcePosition(b,x2,y2,x,y,ChessType(mv),side); //find the source position (x,y)
	if(x==-1)
	{
		result=ILLEGAL;
		return;		
	}
	
	if(x==-2)
	{
		result=PUZZLE;
		return;	
	}

	
	if(b[x][y].pt==ROOK)
	{// the rook has moved, set the caslte mark
		MarkRookMove(side,x,y);	
	}
	if(b[x][y].pt==KING)
	{// the king has moved, set the caslte mark
		if(side==WHITE)
			whitekingmoved=true;
		else
			blackkingmoved=true;
	}
	
	ChessMove(b,x,y,x2,y2);		// move the chess

}

// get the oppesite player
TSide Opponent(TSide side)
{
	if(side==BLACK)
		return WHITE;
	return BLACK;
}

// whether (x,y) chess will be captured 
bool GridBeAttack(TBoard b, int x, int y, TSide bywho)
{
	int i,j;

	
	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
		{
			if(b[i][j].side==bywho && CanMove(b,i,j,x,y,2))
				return true;
		}
	}

	return false;

} 

// decide whether can castle 
bool CanCastle(TBoard b, TSide side, int flag)
{
	int row,i;

	if(side==WHITE)
	{// decide the white 
		if(whitekingmoved)
			return false;	// king moved,can not castle 
		if(flag==3 && white7rookmoved)
			return false;	// rook moved,can not castle
		if(flag==5 && white0rookmoved)
			return false;	// rook moved,can not castle
	}
	else
	{ // decide the black
	if(blackkingmoved)
		return false;		// 
	if(flag==3 && black7rookmoved)
		return false;	// rook moved,can not castle
	if(flag==5 && black0rookmoved)
		return false;	// rook moved,can not castle	
	
	}
	if (side==WHITE)
		row=0;
	else
		row=7;

	if(flag==5)
	{ 
		for(i=1;i<4;i++)
		{
			if(b[row][i].side!=NONE)
				return false ; // there are other chess between king and rook,can not castle	
		}
		for(i=0;i<5;i++)
		{
			if(GridBeAttack(b,row,i,Opponent(side)))
				return false; // whether the target position be attacked 		
		}
	}
	else 
	{// the other side rook 
		for (i=5;i<7;i++)
		{
			if(b[row][i].side!=NONE)
				return false; 
		}
	for(i=4;i<8;i++)
		if(GridBeAttack(b,row,i,Opponent(side)))
			return false; 

	}
		return true;
}

// find the king position 
void GetKingPosition(TBoard b, TSide side,int &x,int &y)
{
	int i,j;


	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
		{ // find the position
			if(b[i][j].pt==KING && b[i][j].side==side)
			{// find the king
				x=i; y=j;
				return ;
			}
		}
	}

}

// decide whether to be check 
bool BeCheck(TBoard b, TSide side)
{
	int x,y,i,j;
	TSide opp;
	GetKingPosition(b,side,x,y);	// find the king position
	opp=Opponent(side);
	for(i=0;i<8;i++)
	{
		for (j=0;j<8;j++)
		{// decide whether the (i,j) chess to attack the king 
			if(b[i][j].side==opp && CanMove(b,i,j,x,y,2))
				return true;
		}
	}
	
	return false ;	
	
}

// copy the chessboard
void CopyBoard(TBoard b2,TBoard b)
{
	int i,j;
		for(i=0;i<8;i++)
		{
			for(j=0;j<8;j++)
			{
				b2[i][j].pt=b[i][j].pt;
				b2[i][j].side=b[i][j].side;
			}
		}
}


// decide whether it is statemate
bool NoMoveAvailable(TBoard b,TSide side)
{
	int x,y,x2,y2;
	TBoard b2;

	for (x=0;x<8;x++)
	{
		for(y=0;y<8;y++)
		{	
			if(b[x][y].side==side)
			{	
				for (x2=0;x2<8;x2++)
				{
					for(y2=0;y2<8;y2++)
					{// decide whether the king can move from (x,y) to (x2,y2)
						if((x2!=x || y2!=y) && b[x][y].side!=b[x2][y2].side && CanMove(b,x,y,x2,y2,1))
						{
							if (b[x][y].pt==KING)
							{ 
								CopyBoard(b2,b);
								ChessMove(b2,x,y,x2,y2);
								if(!BeCheck(b2,side))
								{// decide whether the king be attacked
									return false;
								}
							}
							else 
							{
								return false;
							}
						}
					}
				}
			}
		}
	}
								return true;
}
						
// run the castle 
// param: flag=3 means King-side castle
//		  flag=5 means Queen-side castle
void Castle(TBoard b, TSide side, int flag)
{
	int row;


	if(side==WHITE)
	{ // the white
		if(whitecastled)
		{// white has run the castle 
			result=ILLEGAL;
			return;
		}						
		else 
		{
		whitecastled=true;// set the castle mark
		}
	}
	else 
	{ // the black
		if(blackcastled)
		{
			result=ILLEGAL;
			return; 
		}
		else 
		{
			blackcastled=true;		
		}
	}
	if(CanCastle(b,side,flag))
	{ // whether can run castle
		if(side==WHITE)
		{
			row=0;		
		}
		else
		{
			row=7;
		}
		if(flag==3)
		{// run the castle 
			ChessMove(b,row,4,row,6);
			ChessMove(b,row,7,row,5);
		}
		else
		{
			ChessMove(b,row,4,row,2);
			ChessMove(b,row,0,row,3);
		
		}
	}
	else 
	{
			result=ILLEGAL;
	}
}
	
	
// decide the end
bool CheckMate(TBoard b,TSide side)
{
	int x,y,x2,y2;
	TBoard b2;


	if(!BeCheck(b,side))
		return false;
	for(x=0;x<8;x++)
	{
		for(y=0;y<8;y++)
		{
			if(b[x][y].side==side)
			{
				for(x2=0;x2<8;x2++)
				{
					for(y2=0;y2<8;y2++)
					{
						if((x!=x2 || y!=y2) && b[x2][y2].side!=side)
						{// can king move from (x,y) to (x2,y2)
							if(CanMove(b,x,y,x2,y2,1))
							{
								CopyBoard(b2,b);
								ChessMove(b2,x,y,x2,y2);
								if(!BeCheck(b2,side))
									return false;   // do not be checked							
							}
							if(b[x][y].pt==PAWN && CanMove(b,x,y,x2,y2,2))
							{
								CopyBoard(b2,b);
								ChessMove(b2,x,y,x2,y2);
								if(!BeCheck(b2,side))
									return false;
							}
						}
					}
				}
			}
		}
	}
			return true;
}


// simulate the process 
void run(TBoard b)
{
	int i;
	TSide side;

	side=WHITE;
	for(i=0;i<n;i++)
	{
		if(result==WHITEWIN || result==BLACKWIN || result==STALEMATE)
		{// over, skip the following data 
			result=DEAD;
			SkipInput(i);
			return ;
		}

		scanf("%s",mv);
		if(mv[0]!='O')
			MakeMove(b,mv,side);	// not castle
		else 
			Castle(b,side,strlen(mv));	//castle

		
		if(BeCheck(b,side))
			result=ILLEGAL; // move to a position to be checked, illegal move
		if(result==PUZZLE || result==ILLEGAL)
		{// illegal or puzzle scheme, skip the following data
			SkipInput(i+1);
			return;			
		}
		

		if(CheckMate(b,Opponent(side)))
		{ // check over, find the winner
			if(side==WHITE)
			{
				result=WHITEWIN;
			}
			else 
			{
				result=BLACKWIN;		
			}
		
		}
			side=Opponent(side);
	}
	if(result==DRAW && NoMoveAvailable(b,side))
		result = STALEMATE; 

}




int main()  
{
	TBoard b;


	freopen("chess.in","r",stdin);
	freopen("chess.out","w",stdout);
	while (scanf("%d",&n),n>0)
	{
		init(b);
		result=DRAW;	// asume draw first
		whitecastled=false;  blackcastled=false;
		white0rookmoved=false;white7rookmoved=false;
		black0rookmoved=false;black7rookmoved=false;
		whitekingmoved=false;blackkingmoved=false;      // init the castle mark
		run(b);
		printf("%s\n",RESULT[result]);
		/*if (result==STALEMATE)	
			PrintBoard(b,n,mv)	;*/
		
	}
		return 0;
}













⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -