




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
#include #include #include using namespace std;enum TResult /结局状态 WHITEWIN = 1,/白方赢 BLACKWIN,/黑方赢 STALEMATE,/僵局 DRAW,/和局 DEAD,/过多的输入 PUZZLE,/无法决定移动棋子 ILLEGAL /非法;const char RESULT820= /结局状态输出表示 , White Win, Black Win, Stalemate, Draw, Dead Moves, Puzzle Move, Illegal Move ;enum TPieceType /棋子类型 SPACE = 0, PAWN,/兵 KING,/王 QUEEN,/后 ROOK,/车 BISHOP,/象 KNIGHT /马;enum TSide 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: 白方号位的车是否已经移动* white7rookMoved: 白方号位的车是否已经移动* black0rookMoved: 黑方号位的车是否已经移动* black7rookMoved: 黑方号位的车是否已经移动* whitekingMoved: 白方王是否已经移动* blackkingMoved: 黑方王是否已经移动*/bool whitecastled,blackcastled,white0rookMoved,white7rookMoved,black0rookMoved,black7rookMoved,whitekingMoved,blackkingMoved; TPieceType ChessType(const string& move) switch(move0) case K:/王 return KING; case Q:/后 return QUEEN; case R:/车 return ROOK; case B:/象 return BISHOP; case 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 i,j; /清空整个棋盘 for(i=0;iBOARDSIZE;+i) for(j=0;jBOARDSIZE;+j) clear(b,i,j); /摆放各个棋子 for(i=0;iBOARDSIZE;+i) /棋盘前两行是白方 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 = 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; whitekingMoved = false; blackkingMoved = false; void SkipInput(int k) /棋局已经结束,忽略剩余的输入 int i; char mv20; for(i=k;in;+i) 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-a;/列bool OutOfBoard(int x,int y) /棋子是否超出棋盘界限 if (x0|yBOARDSIZE|yBOARDSIZE) return true; 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坐标不能改变,无法前进 return false; if (bxy.side=WHITE) /下棋的是白方 if (x=1) /白方的兵是第一次移动 return x2=2 | (x2=3&b2y.side=NONE);/第一次移动兵可以移动格或格 else return x2=x+1;/不是第一次移动,就只能向前移动格 else /下棋的是黑方 if (x=6) /黑方的兵是第一次移动 return x2=5 | (x2=4&b5y.side=NONE);/第一次移动兵可以移动格或格 else return x2=x-1;/不是第一次移动,就只能向前移动格 else /吃子判断,吃子时,x向前格,y坐标改变格 if (bxy.side=WHITE) /要吃子的是白方 return (x2=x+1&abs(y2-y)=1); else /要吃子的是黑方 return (x2=x-1&abs(y2-y)=1); return false; bool CanMoveKing(TBoard b,int x,int y,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) return false; /直线方向增量 if (x2x) dx = -1; else dx = 1; if (y2y) dy = -1; else dy = 1; /x方向上移动 for (i=1;iabs(y-y2);+i) yy = y+i*dy; if (bxyy.side!=NONE) /中间有棋子阻挡 return false; /y方向上移动 for (i=1;iabs(x-x2);+i) xx = x+i*dx; if (bxxy.side!=NONE) /中间有棋子阻挡 return false; return true; bool CanMoveBishop(TBoard b,int x,int y,int x2,int y2) /判断能否把象从(x,y)移动到(x2,y2) int dx,dy,i,xx,yy; /是否斜向移动 if (abs(x-x2)!=abs(y-y2) return false; /直线方向增量 if (x2x) dx = -1; else dx = 1; if (y2y) dy = -1; else dy = 1; for (i=1;iabs(x-x2);+i) xx = x+i*dx; yy = y+i*dy; if (bxxyy.side!=NONE) /中间有棋子阻挡 return false; return true; bool CanMoveQueen(TBoard b,int x,int y,int x2,int y2) /判断能否把王从(x,y)移动到(x2,y2) return CanMoveRook(b,x,y,x2,y2) | CanMoveBishop(b,x,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,y2)处的棋子给吃掉 /判断是否越界 if (OutOfBoard(x,y)|OutOfBoard(x2,y2) return false; /判断原位置是否有棋子 if (bxy.side=NONE) return false; /根据原来位置上棋子的不同类型判断是否合法 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,x2,y2); case BISHOP:/象 return CanMoveBishop(b,x,y,x2,y2); case KNIGHT:/马 return CanMoveKnight(x,y,x2,y2); return false; void GetSourcePosition(TBoard b,int x2,int y2,int &x,int &y,TPieceType ct,TSide side) /*从给出的位置(x2,y2),类型ct和玩家side,求出移动的棋子的原来位置(x,y),, * 当x=-2时,表示有重复移动方案(Puzzle),x=-1时表示没有移动可能(illegal) */ int i,j,flag = 1; if(bx2y2.side!=NONE)/目标位置是对手的棋子,则此步为吃子方案 flag = 2; for (i=0;iBOARDSIZE;+i) for (j=0;jBOARDSIZE;+j) if (bij.side=side&bij.pt=ct) /原位置合法并且是同一个子 if (CanMove(b,i,j,x2,y2,flag) if (x=-1) /能够移动并且不重复,找到原来棋子的位置 x = i; y = j; else /能够移动并且有方案,说明有重复 x = -2; return; void MarkRookMove(TSide side,int x,int y) if (side=WHITE) if (x=0) if (y=0) white0rookMoved = true;/白方号车已经移动 if (y=7) white7rookMoved = true;/白方号车已经移动 return; if (x=7) if (y=0) black0rookMoved = true;/黑方号车已经移动 if (y=7) 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) /根据输入的步骤mv,玩家side移动棋子 int x,y,x2,y2; GetPosition(move,x2,y2);/目标位置 if(bx2y2.side=side) /目标位置处已经有我方的棋子了,此步非法 result = ILLEGAL; return; x = -1; GetSourcePosition(b,x2,y2,x,y,ChessType(move),side);/尝试寻找原位置 if (x=-1) /非法状态 result = ILLEGAL; return; else if (x=-2) /重复状态 result = PUZZLE; return; /移动的棋子是车时,设置王车易位布尔变量 if (bxy.pt=ROOK) MarkRookMove(side,x,y); /移动的棋子是王时,设置王车易位布尔变量 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)的棋子能否被吃掉 int i,j; for (i=0;iBOARDSIZE;+i) for (j=0;jBOARDSIZE;+j) if (bij.side=byWho & CanMove(b,i,j,x,y,2) /会被对手吃掉的 return true; return false; bool CanCastle(TBoard b,TSide side,int flag) /判断是否能够进行王车易位 int row,i; if (side=WHITE) /白方王车易位 if (whitekingMoved=true) /王已经动了,不能王车易位 return false; if (flag=3&white7rookMoved=true) /目标车已经动了,不能王车易位 return false; if (flag=5&white0rookMoved=true) /目标车已经动了,不能王车易位 return false; else /黑方王车易位 if (blackkingMoved=true) /王已经动了 return false; if (flag=3 & black7rookMoved=true) /目标车已经动了,不能王车易位 return false; if (flag=5 & black0rookMoved=true) /目标车已经动了,不能王车易位 return false; if (side=WHITE) row = 0; else row = 7; if (flag=5) for (i=1;i4;+i) if (browi.side!=NONE) /王车之间是否有棋子,若有则不能易位 return false; for (i=0;i5;+i) if (GridBeAttack(b,row,i,Opponent(side)=true) /在目标位置上会被对手吃掉,不能王车易位 return false; else for (i=5;iBOARDSIZE-1;+i) if (browi.side!=NONE) /王车之间是否有棋子,若有则不能易位 return false; for (i=4;iBOARDSIZE;+i) if (GridBeAttack(b,row,i,Opponent(side) /在目标位置上会被对手吃掉,不能王车易位 return false; return true;/检查符合要求,可以王车易位void Castle(TBoard b,TSide side,int flag) /进行王车易位,flag=3,表示靠近王的车King-side castle,flag=5时,表示Queen-side castle int row; if (side=WHITE) if (whitecastled=true) /白方是否已经易位,已经易过位,不能再易了 result = ILLEGAL; return ; else whitecastled = true;/设置易位变量 else if (blackcastled=true) /黑方是否已经易位,已经易过位,不能再易了 result = ILLEGAL; return; else blackcastled = true; if (CanCastle(b,side,flag)=true) /判断是否能够易位 if (side=WHITE) row = 0; else row = 7; if (flag=3) /进行王车易位 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; void GetKingPosition(TBoard b,TSide side,int &x,int &y) /寻找国王的位置 int i,j; for (i=0;iBOARDSIZE;+i) for (j=0;jBOARDSIZE;+j) if (bij.pt=KING & bij.side = side) /找到指定方的王 x = i; y = j; return; bool BeCheck(TBoard b,TSide side) /判断是否被“将军 int x,y,i,j; TSide oppSide; GetKingPosition(b,side,x,y);/寻找玩家side的王 oppSide = Opponent(side);/对手 for (i=0;iBOARDSIZE;+i) for (j=0;jBOARDSIZE;+j) if (bij.side=oppSide & CanMove(b,i,j,x,y,2)=true) /判断对手是否能否将军,flag=2表示此步是吃子, return true; return false; void CopyBoard(TBoard desBoard,TBoard srcBoard) /复制棋盘 int i,j; for (i=0;iBOARDSIZE;+i) for (j=0;jBOARDSIZE;+j) desBoardij.pt = srcBoardij.pt; desBoardij.side = srcBoardij.side; bool NoMoveAvailable(TBoard b,TSide side) /判断是否是僵局 int x,y,x2,y2; TBoard b2; for (x=0;xBOARDSIZE;+x) for (y=0;yBOARDSIZE;+y) if (bxy.side=side) for (x2=0;x2BOARDSIZE;+x2) for (y2=0;y2BOARDSIZE;+y2) /判断side方的王能否从(x,y)走到(x2,y2) if (x2!=x | y2!=y) & bxy.side!=bx2y2.side & CanMove(b,x,y,x2,y2,1) if (bxy.pt=KING) CopyBoard(b2,b); ChessMove(b2,x,y,x2,y2); if (!BeCheck(b2,side) /判断位置是否被”将军“,没有就不是僵局 return false; else return false; return true; bool CheckMate(TBoard b,TSide side) /判断是否已经结束(即是否某一方被将死) int x,y,x2,y2; TBoard b2; if (!BeCheck(b,side) /没有被将死 return false; for (x=0;xBOARDSIZE;+x) for (y=0;yBOARDSIZE;+y) if (bxy.side=side) for (x2=0;x2BOARDSIZE;+x2) for (y2=0;y2BOARDSIZE;+y2) if (x!=x2 | y!=y2) & bx2y2.side!=side) /王能否从(x,y)移动到(x2,y2) if (CanMo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度购物中心商铺招商租赁管理合同范本
- 2025年度企事业单位应急周转借款合同范本
- 2025版外汇风险对冲基金投资合同
- 2025版跨境电商融资抵押租赁合同
- 2025版内衣行业电子商务平台合作订货合同模板
- 2025版围栏施工项目质量检验与认证服务合同
- 2025年航空航天零件打磨维修合同
- 贵州省福泉市2025年上半年公开招聘村务工作者试题含答案分析
- 2025版农产品电商物流配送服务合同书
- 2025版企业内部培训与职业技能提升合同
- 小学英语人教版四年级下册 巩固强化练(含答案)
- 防暴器材使用管理办法
- 2025-2026学年粤教粤科版(2024)小学科学二年级上册(全册)教学设计(附目录)
- 钢梁步履式顶推技术规范
- 新建寿县生态陵园(殡仪馆和公墓)规划选址论证、可研报告编制以及初步设
- 岗前安全培训课件
- 2025年山东高考历史试卷真题讲评及备考策略指导(课件)
- 学前儿童融合教育
- 2025年新疆中考道德与法治试卷真题(含标准答案)
- 科技公司薪资管理制度
- 糖尿病患者围手术期麻醉管理
评论
0/150
提交评论