国际象棋C++程序代码_第1页
国际象棋C++程序代码_第2页
国际象棋C++程序代码_第3页
国际象棋C++程序代码_第4页
国际象棋C++程序代码_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、#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 /棋子类型 spac

2、e = 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;/最后结局/* *用来进行王车易位的布尔变量* * whitec

3、astled:白方是否已经王车易位* blackcastled:黑方是否已经王车易位* white0rookmoved: 白方号位的车是否已经移动* white7rookmoved: 白方号位的车是否已经移动* black0rookmoved: 黑方号位的车是否已经移动* black7rookmoved: 黑方号位的车是否已经移动* whitekingmoved: 白方王是否已经移动* blackkingmoved: 黑方王是否已经移动*/bool whitecastled,blackcastled,white0rookmoved,white7rookmoved,black0rookmoved

4、,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

5、; 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

6、;/上面第二行是白方的兵 /棋盘最后两行是黑方 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;/初始化

7、王的位置 /初始化王车易位使用的布尔变量 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);

8、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)

9、/判断能否把兵从(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;/不是第一次移动,就只能向前移动格 el

10、se /下棋的是黑方 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,i

11、nt 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;i

12、abs(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-

13、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,x

14、2,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),当fla

15、g=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 can

16、movequeen(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,求出移动

17、的棋子的原来位置(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 =

18、 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 c

19、hessmove(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 = ill

20、egal; 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)/白方王移动了 whitek

21、ingmoved = 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

22、(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) /王已

23、经动了 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 (gridbeatta

24、ck(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,t

25、side 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 bl

26、ackcastled = 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,tsid

27、e 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 (

28、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.

29、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 & canmov

30、e(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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论