📄 chess_simulation.cpp
字号:
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 + -