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