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

📄 chess_simulation.cpp

📁 这个一道ACM竞赛中的复杂模拟程序。按照国际象棋的规则
💻 CPP
📖 第 1 页 / 共 2 页
字号:
# include "stdio.h"
# include "stdlib.h"
# include "string.h"
/*
这个一道ACM竞赛中的复杂模拟程序。按照国际象棋的规则,程序从check_in中读入双方落子的步骤
通过程序模拟该盘棋过程,并最后判断输赢。将结果仿真check_out中。
*/
# define ERROR -1

enum TResult // define the final state
{
	WHITEWIN=1,//white win
	BLACKWIN,  //black win
	STALEMATE, // Statlemate
	DRAW,	   // DRAW
    DEAD,      // MORE INPUT
	PUZZLE,    // CAN NOT DECIDE WHICH CHESS TO MOVE
	ILLEGAL    // ILLEGAL STEP
};

const char RESULT[8][20]={ // THE FINAL STATE OUTPUT
"",
"White Win",
"Black Win",
"Stalemate",
"Draw",
"Dead Moves",
"Puzzle Move",
"Illegal Move"
};

enum TPieceType //the types of chess
{
	SPACE=0,	
	PAWN,		
	KING,
	QUEEN,
	ROOK,
	BISHOP,
	KNIGHT
};

enum TSide		//the two players
{
	NONE=0,
	WHITE,
	BLACK
};

typedef struct  // every chess
{
	TSide side;
	TPieceType pt;
} TPiece;

typedef TPiece TBoard[8][8];

char mv[20];
int n;
TResult result;// the final state
bool
whitecastled,blackcastled,white0rookmoved,white7rookmoved,black0rookmoved,black7rookmoved,whitekingmoved,blackkingmoved;
// all for the castle 
// whitecastled, to judge whether the white castle ; blackcastle, to judge whether the black castle 
// white0rookmoved, to judge the white 0 rook moved ; white7rookmoved, to judge the white 7 rook moved 
// black0rookmoved, to judge the black 0 rook moved ; black7rookmoved, to judge the black 7 rook moved 
// whitekingmoved, to judge the white king moved ; blackkingmoved, to judge the black king moved 
TPieceType ChessType(char *mv)
{
	switch(mv[0])
	{
	case 'K': return KING;
	case 'Q': return QUEEN;
	case 'R': return ROOK;
	case 'B': return BISHOP;
	case 'N': return KNIGHT;
	}
	return PAWN;


}

// clear the chess board 
void clear(TBoard b, int x,int y)
{
	b[x][y].side=NONE;
	b[x][y].pt=SPACE;


}

// init the chess board 
void init(TBoard b)
{
	int i,j;
	for (i=0;i<8;i++)
	{
		for (j=0;j<8;j++)
		{
			clear(b,i,j);

		}
	}		// clear the chess board 

for (i=0; i<8;i++)
{	// init the color and the position 
	b[0][i].side=WHITE; b[1][i].side=WHITE;
	b[1][i].pt=PAWN;
	b[7][i].side=BLACK;b[6][i].side=BLACK;
	b[6][i].pt=PAWN;

}

	b[0][0].pt=b[0][7].pt=b[7][0].pt=b[7][7].pt=ROOK; //init the ROOK
	b[0][1].pt=b[0][6].pt=b[7][1].pt=b[7][6].pt=KNIGHT; //init the KNIGHT
	b[0][2].pt=b[0][5].pt=b[7][2].pt=b[7][5].pt=BISHOP; //init the BISHOP
	b[0][3].pt=b[7][3].pt=QUEEN;						//init the QUEEN
    b[0][4].pt=b[7][4].pt=KING;							//init the KING
}

// when the result is decided, to skip the next data 
void SkipInput(int k)
{
	int i;
	char mv[20];
	for(i=k;i<n;i++)
		scanf("%s",mv);

}


// print the board 
void PrintBoard(TBoard b,int no,char *mv)
{
	const char CHESSSHORTNAME[10]="_PKQRBN";
	int i,j;
	
	printf("NO.%d %s\n",no,mv);

	for (i=7;i>=0;i--)
	{	
		for (j=0;j<8;j++)
		{
			if(b[i][j].side==NONE)
				printf("  ");		//the space output 
			else {	
			if(b[i][j].side==WHITE)
			{	printf("W");
			}
			else  
			{
				printf("B");
			}
			
			printf("%c",CHESSSHORTNAME[b[i][j].pt]); 

			}		
			printf("  ");
		}
			printf("\n");
	}
	printf("===================================\n");
}

// find whether a chess to cross the borader 
bool OutofBoard(int x,int y)
{
	if (x<0||y<0) 
		return true;
	if (x>=8||y>=8)
		return true;
	return false;

}

// decide whether pawn can move pawn from (x y) to (x2 y2)
// when the flag is one, pawn move from (x y) to (x2 y2)
// when flag is others, pawn captures from (x y) to (x2 y2)
bool CanMovePawn(TBoard b,int x,int y, int x2,int y2,int flag)
{
	if (flag==1)
	{ // flag is one, to move straight 
		if (y!=y2||b[x2][y2].side!=NONE)
			return false; // y can not be changed
		if (b[x][y].side==WHITE)
		{ // the player is white 
			if (x==1) 
			{ // the white to move first 
				return (x2==2||(x2==3 && b[2][y].side==NONE));
				//return ((x2==2&& b[2][y].side=NONE)||(x2==3 && b[2][y].side=NONE&&b[3][y].side=NONE));

												// the first move can be either one or two step 
			}
			else {
				return x2==x+1; // not the first move, only one step
				//return (x2==x+1 && b[x+1][y].side=NONE)	
			}
		}
		else {
			if (x==6)	// the first move by the black 
				return (x2==5||(x2==4 && b[5][y].side==NONE)); 
				//return ((x2==5&& b[6][y].side=NONE)||(x2==4 && b[5][y].side=NONE&&b[4][y].side=NONE));
			else 
				return x2==x-1;					// the one step 
				//return (x2==x-1 && b[x-1][y].side=NONE)
		
		}

	}
	else { //the capture 
			if(b[x][y].side==WHITE) 
			{// the white 
				return (x2==x+1 && abs(y2-y)==1);  // y change one and x move forware one
			}
			else {// black
				return (x2==x-1 && abs(y2-y)==1);  // y change one and x move forware one
			}

	}

	return false ;
}

// decide whether king can move pawn from (x y) to (x2 y2)
bool CanMoveKing(TBoard b, int x, int y, int x2, int y2)
{
	return (abs(x-x2)<=1&& abs(y-y2)<=1);
	
	//return (abs(x-x2)<=1&& abs(y-y2)<=1 && b[x2][y2].side!=b[x][y].side);


}

// decide whether rook can move pawn from (x y) to (x2 y2)
bool CanMoveRook(TBoard b, int x, int y, int x2, int y2)
{
	int dx,dy,i,xx,yy;
	if (x!=x2 && y!=y2)
		return false ;// move straight 
	/*
	if (b[x][y].side==b[x2][y2].side)
		return false; // the same side can not move 
	*/
	if (x2<x) 
		dx=-1;
	else 
		dx=1;
	if (y2<y) 
		dy=-1;
	else 
		dy=1;
	if (x==x2)
	{  // move in x direction	
		for (i=1;i<abs(y-y2);i++)
		{
			yy=y+i*dy;
			if (b[x][yy].side!=NONE)
			return false;     // find whether there are other chess in the way 		
		
		}
	
		return true;
	
	}
		
	for (i=1;i<abs(x-x2);i++)
	{    // move in x direction
		xx=x+i*dx;
		if (b[xx][y].side!=NONE)
			return false; //  find whether there are other chess in the way 
	}
		return true ;

}


// the decider whether bishop can move pawn from (x y) to (x2 y2)
bool CanMoveBishop(TBoard b,int x,int y,int x2,int y2)
{
	int dx,dy,i,xx,yy;
	if(abs(x-x2)!=abs(y-y2)) 
		return false; // whether move diagonally

		/*
	if (b[x][y].side==b[x2][y2].side)
		return false; // the same side can not move 
	*/

	if(x2<x) 
		dx=-1;
	else
		dx=1;
	if(y2<y)
		dy=-1;
	else
		dy=1;
	for(i=1;i<abs(x-x2);i++)
	{
		xx=x+i*dx;
		yy=y+i*dy;
		if(b[xx][yy].side!=NONE)
			return false ;          // find whether there are other chess in the way 
	
	}

		return true ;

}

// decide whether queen can move pawn from (x y) to (x2 y2)
bool CanMoveQueen(TBoard b,int x,int y,int x2,int y2)
{
	return CanMoveRook(b,x,y,x2,y2)||CanMoveBishop(b,x,y,x2,y2); // the same with the combine of rook and bishop

}

// decide whether queen can move pawn from (x y) to (x2 y2)
bool CanMoveKnight(int x,int y,int x2,int y2)
{
	int xx=abs(x-x2),yy=abs(y-y2);
			/*
	if (b[x][y].side==b[x2][y2].side)
		return false; // the same side can not move 
	*/

	return(xx+yy==3 && (xx==1||yy==1)); // the knight move  


}

// decide whether a chess  can move from (x,y) to (x2,y2)
// when the flag is one , move directly 
// when the flag is two, capture and move 
bool CanMove(TBoard b,int x, int y, int x2,int y2,int flag)
{
	if (OutofBoard(x,y) || OutofBoard(x2,y2) )
		return false ; // decide whether to cross the board
	if (b[x][y].side==NONE)
		return false ; // decide whether (x,y) have a chess
	
	
	switch (b[x][y].pt) 
	{ // to decide each kind
		case PAWN:return CanMovePawn(b,x,y,x2,y2,flag);	// the pawn
		case KING:return CanMoveKing(b,x,y,x2,y2);		// the king
		case QUEEN:return CanMoveQueen(b,x,y,x2,y2);	// the queen
		case ROOK: return CanMoveRook(b,x,y,x2,y2);		// the rook 
		case BISHOP: return CanMoveBishop(b,x,y,x2,y2);	// the bishop 
		case KNIGHT: return CanMoveKnight(x,y,x2,y2);	// the knight
	}

	return false ;
}


// move from (x,y) to (x2,y2)
void ChessMove(TBoard b, int x,int y, int x2, int y2)
{
	b[x2][y2].side=b[x][y].side;
	b[x2][y2].pt=b[x][y].pt;
	clear(b,x,y);

}

// to get the chess position from the document 
void GetPosition(char *mv, int &x2, int &y2)
{
	int k=0; 
	if(mv[0]<'a')
		k=1;
	x2=mv[k+1]-'1';
	y2=mv[k]-'a';
}

//to find the source position (x,y) from the given position (x2,y2) in the document 
// when x=-2, there is a puzzle scheme
// when x=-1, there is a illegal scheme
void GetSourcePosition(TBoard b, int x2, int y2, int &x, int &y, TPieceType ct,TSide side)
{
	int i,j,flag=1;
	if (b[x2][y2].side!=NONE)
		flag=2; //  give the capture scheme
	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
		{
			if(b[i][j].side==side && b[i][j].pt==ct)
			{//  the source position is legal and is the just chess moved
				if (CanMove(b,i,j,x2,y2,flag))
				{
					if(x==-1)
					{ // can move and no duplicate
						x=i;
						y=j;
					}
					else 
					{// can move and have ,scheme 
						x=-2;
						return ;
						
					}
				
				}
			
			}
			
		}

	}
}

// when the rook has moved, change the castle mark
void MarkRookMove(TSide side,int x, int y) 
{
	if(side==WHITE)
	{
		if(x==0)
		{
			if(y==0)  
				white0rookmoved=true;			// the white 0 rook has moved 
			if(y==7)
				white7rookmoved=true;			// the white 7 rook has moved		
	
		}
		return ;
	}

		if(x==7)
		{

⌨️ 快捷键说明

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