1、 NONE = 0, WHITE,/黑方 BLACK /白方typedef struct /棋盘每个位置的表示 TSide side;/所属玩家 TPieceType pt;/棋子类型TPiece;const int BOARDSIZE = 8;/棋盘大小typedef TPiece TBoardBOARDSIZEBOARDSIZE;/棋盘int n;/棋谱步数TResult result;/最后结局/* *用来进行王车易位的布尔变量* * whitecastled:白方是否已经王车易位* blackcastled:黑方是否已经王车易位* white0rookMoved: 白方号位的车是否已经
2、移动* white7rookMoved:* black0rookMoved: 黑方号位的车是否已经移动* black7rookMoved:* whitekingMoved: 白方王是否已经移动* blackkingMoved: 黑方王是否已经移动*/bool whitecastled,blackcastled,white0rookMoved,white7rookMoved,black0rookMoved,black7rookMoved,whitekingMoved,blackkingMoved; TPieceType ChessType(const string& move) switch(m
3、ove0) case K:/王 return KING;Q/后 return QUEEN;R/车 return ROOK;B/象 return BISHOP;N/马 return KNIGHT; return PAWN;/兵TSide Opponent(TSide side) /获取对手类型 if (side=WHITE) return BLACK; return WHITE;void clear(TBoard b,int x,int y) /清空棋盘b的(x,y)位置 bxy.side = NONE; bxy.pt = SPACE;void init(TBoard b) /初始化棋盘 int
4、 i,j; /清空整个棋盘 for(i=0;iBOARDSIZE;+i) for(j=0;j+j) clear(b,i,j); /摆放各个棋子 /棋盘前两行是白方 b0i.side = WHITE; b1i.side = WHITE; b1i.pt = PAWN;/上面第二行是白方的兵 /棋盘最后两行是黑方 b6i.side = BLACK; b7i.side = BLACK; b6i.pt = PAWN;/倒数第二行是黑方的兵 b00.pt = b07.pt = b70.pt = b77.pt = ROOK;/初始化车的位置 b01.pt = b06.pt = b71.pt = b76.pt
5、 = KNIGHT;/初始化马的位置 b02.pt = b05.pt = b72.pt = b75.pt = BISHOP;/初始化象的位置 b03.pt = b73.pt = QUEEN;/初始化后的位置 b04.pt = b74.pt = KING;/初始化王的位置 /初始化王车易位使用的布尔变量 whitecastled = false; blackcastled = false; white0rookMoved = false; white7rookMoved = false; black0rookMoved = false; black7rookMoved = false; whit
6、ekingMoved = false; blackkingMoved = false; void SkipInput(int k) /棋局已经结束,忽略剩余的输入 int i; char mv20; for(i=k;n; scanf_s(%s,mv);void GetPosition(const string& move,int &x,int &y) /从输入的移动步骤中获取棋子的目标位置 int k = 0; if(move0a)/首字母是大写字母 k = 1; x = movek+1-1;/行 y = movek-/列bool OutOfBoard(int x,int y) /棋子是否超出
7、棋盘界限 if (x0|yBOARDSIZE|yBOARDSIZE) return false;bool CanMovePawn(TBoard b,int x,int y,int x2,int y2,int flag) /判断能否把兵从(x,y)移动到(x2,y2),当flag=1时,表示(x,y)直接移动到(x2,y2),flag为其他表示从(x,y)吃子到(x2,y2) if (flag=1) /直接移动,即兵直线前进一格 if (y!=y2|bx2y2.side!=NONE) /y坐标不能改变,无法前进 if (bxy.side=WHITE) /下棋的是白方 if (x=1) /白方的兵
8、是第一次移动 return x2=2 | (x2=3&b2y.side=NONE);/第一次移动兵可以移动格或格 else return x2=x+1;/不是第一次移动,就只能向前移动格 /下棋的是黑方 if (x=6) /黑方的兵是第一次移动 return x2=5 | (x2=4&b5y.side=NONE); return x2=x-1; /吃子判断,吃子时,x向前格,y坐标改变格 /要吃子的是白方 return (x2=x+1&abs(y2-y)=1); else /要吃子的是黑方 return (x2=x-1&bool CanMoveKing(TBoard b,int x,int y
9、,int x2,int y2) /判断能否把王从(x,y)移动到(x2,y2) return (abs(x-x2)=1&abs(y-y2)=1);bool CanMoveRook(TBoard b,int x,int y,int x2,int y2) /判断能否把车从(x,y)移动到(x2,y2) int dx,dy,i,xx,yy; /判断移动是否是直线 if (x!=x2 & y!=y2) /直线方向增量 if (x2x) dx = -1; dx = 1; if (y2 dy = -1; dy = 1; /x方向上移动 for (i=1;abs(y-y2); yy = y+i*dy; if
10、 (bxyy.side! /中间有棋子阻挡 /y方向上移动abs(x-x2); xx = x+i*dx; if (bxxy.side!bool CanMoveBishop(TBoard b,int x,int y,int x2,int y2) /判断能否把象从(x,y)移动到(x2,y2) /是否斜向移动 if (abs(x-x2)!=abs(y-y2) if (bxxyy.side!bool CanMoveQueen(TBoard b,int x,int y,int x2,int y2) return CanMoveRook(b,x,y,x2,y2) | CanMoveBishop(b,x,
11、y,x2,y2);/王后等于车+象bool CanMoveKnight(int x,int y,int x2,int y2) /判断马能否从(x,y)移动到(x2,y2) int xx,yy; xx = abs(x-x2); yy = abs(y-y2); return (xx+yy=3 & (xx=1 | yy=1);/马行日,x或者y这两者之一移动格,另一方向移动格bool CanMove(TBoard b,int x,int y,int x2,int y2,int flag) /判断一个棋子能否从(x,y)移动到(x2,y2),当flag=1时,直接移动,flag=2时,表示把(x2,y
12、2)处的棋子给吃掉 /判断是否越界 if (OutOfBoard(x,y)|OutOfBoard(x2,y2) /判断原位置是否有棋子 if (bxy.side=NONE) /根据原来位置上棋子的不同类型判断是否合法 switch (bxy.pt) case PAWN: return CanMovePawn(b,x,y,x2,y2,flag); case KING: return CanMoveKing(b,x,y,x2,y2); case QUEEN: return CanMoveQueen(b,x,y,x2,y2); case ROOK: return CanMoveRook(b,x,y,
13、x2,y2); case BISHOP: return CanMoveBishop(b,x,y,x2,y2); case KNIGHT: return CanMoveKnight(x,y,x2,y2);void GetSourcePosition(TBoard b,int x2,int y2,int &y,TPieceType ct,TSide side) /*从给出的位置(x2,y2),类型ct和玩家side,求出移动的棋子的原来位置(x,y),, * 当x=-2时,表示有重复移动方案(Puzzle),x=-1时表示没有移动可能(illegal) */ int i,j,flag = 1; i
14、f(bx2y2.side!=NONE)/目标位置是对手的棋子,则此步为吃子方案 flag = 2; for (i=0; for (j=0; if (bij.side=side&bij.pt=ct) /原位置合法并且是同一个子 if (CanMove(b,i,j,x2,y2,flag) if (x=-1) /能够移动并且不重复,找到原来棋子的位置 x = i; y = j; /能够移动并且有方案,说明有重复 x = -2; return;void MarkRookMove(TSide side,int x,int y) if (x=0) if (y=0) white0rookMoved = tr
15、ue;/白方号车已经移动 if (y=7) white7rookMoved = true; if (x=7) black0rookMoved = true;/黑方号车已经移动 black7rookMoved = true;void ChessMove(TBoard b,int x,int y,int x2,int y2) /棋子从(x,y)移动到(x2,y2) bx2y2.side = bxy.side; bx2y2.pt = bxy.pt; clear(b,x,y);/清空原位置void MakeMove(TBoard b,const string& move,TSide side) /根据
16、输入的步骤mv,玩家side移动棋子 int x,y,x2,y2; GetPosition(move,x2,y2);/目标位置 if(bx2y2.side=side) /目标位置处已经有我方的棋子了,此步非法 result = ILLEGAL; x = -1; GetSourcePosition(b,x2,y2,x,y,ChessType(move),side);/尝试寻找原位置 /非法状态 else if (x=-2) /重复状态 result = PUZZLE; /移动的棋子是车时,设置王车易位布尔变量 if (bxy.pt=ROOK) MarkRookMove(side,x,y); /移
17、动的棋子是王时,设置王车易位布尔变量 if (bxy.pt=KING) if (side=WHITE)/白方王移动了 whitekingMoved = true; else/黑方王移动了 blackkingMoved = true; ChessMove(b,x,y,x2,y2);/移动棋子bool GridBeAttack(TBoard b,int x,int y,TSide byWho) /判断位置(x,y)的棋子能否被吃掉 if (bij.side=byWho & CanMove(b,i,j,x,y,2) /会被对手吃掉的bool CanCastle(TBoard b,TSide side
18、,int flag) /判断是否能够进行王车易位 int row,i; /白方王车易位 if (whitekingMoved=true) /王已经动了,不能王车易位 if (flag=3&white7rookMoved=true) /目标车已经动了,不能王车易位 if (flag=5&white0rookMoved=true) /黑方王车易位 if (blackkingMoved=true) /王已经动了 if (flag=3 & black7rookMoved=true) if (flag=5 & black0rookMoved=true) row = 0; row = 7; if (fla
19、g=5)4; if (browi.side! /王车之间是否有棋子,若有则不能易位5; if (GridBeAttack(b,row,i,Opponent(side)=true) /在目标位置上会被对手吃掉,不能王车易位 for (i=5;BOARDSIZE-1; for (i=4; if (GridBeAttack(b,row,i,Opponent(side)/检查符合要求,可以王车易位void Castle(TBoard b,TSide side,int flag) /进行王车易位,flag=3,表示靠近王的车King-side castle,flag=5时,表示Queen-side ca
20、stle int row; if (whitecastled=true) /白方是否已经易位,已经易过位,不能再易了 return ; whitecastled = true;/设置易位变量 if (blackcastled=true) /黑方是否已经易位,已经易过位,不能再易了 blackcastled = true; if (CanCastle(b,side,flag)=true) /判断是否能够易位 if (flag=3) /进行王车易位 ChessMove(b,row,4,row,6); ChessMove(b,row,7,row,5); ChessMove(b,row,4,row,2); ChessMove(b,row,0,row,3); /无法王车易位,此步非法void GetKingPosition(TBoard b,TSide side,int & /寻找国王的位置 if (bij.pt=KING & bij.side = side) /找到指定方的王
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1