国际象棋C++.docx

上传人:b****3 文档编号:24763968 上传时间:2023-06-01 格式:DOCX 页数:25 大小:46.65KB
下载 相关 举报
国际象棋C++.docx_第1页
第1页 / 共25页
国际象棋C++.docx_第2页
第2页 / 共25页
国际象棋C++.docx_第3页
第3页 / 共25页
国际象棋C++.docx_第4页
第4页 / 共25页
国际象棋C++.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

国际象棋C++.docx

《国际象棋C++.docx》由会员分享,可在线阅读,更多相关《国际象棋C++.docx(25页珍藏版)》请在冰豆网上搜索。

国际象棋C++.docx

国际象棋C++

#include

#include#includeusingnamespacestd;

enumTResult

{//结局状态WHITEWIN=1,//白方赢

BLACKWIN,//黑方赢

STALEMATE,/僵局

DRAW,//和局

DEAD,//过多的输入

PUZZLE,//无法决定移动棋子

ILLEGAL//非法

};

constcharRESULT[8][20]=

{//结局状态输出表示

HH

"WhiteWin","BlackWin","Stalemate","Draw","DeadMoves","PuzzleMove","IllegalMove"};

enumTPieceType

{//棋子类型

SPACE=0,PAWN,//兵KING,//王QUEEN,//后ROOK,//车BISHOP/象KNIGHT//马};

enumTSide

{

NONE=0,

WHITE,//黑方BLACK//白方};

typedefstruct

{//棋盘每个位置的表示

TSideside;//所属玩家TPieceTypept;//棋子类型}TPiece;

constintBOARDSIZE=8;//棋盘大小typedefTPieceTBoard[BOARDSIZE][BOARDSIZE];棋盘

intn;//棋谱步数

TResultresult;//最后结局

/*

*用来进行王车易位的布尔变量

*/boolwhitecastled,blackcastled,white0rookMoved,white7rookMoved,black0rookMoved,black7rookMoved,whitekingMoved,blackkingMoved;

TPieceTypeChessType(conststring&move){

switch(move[0])

{

case'K':

//王

returnKING;

case'Q':

//后

returnQUEEN;

case'R':

//车

returnROOK;

case'B':

//象

returnBISHOP;

case'N':

//马

returnKNIGHT;

}

returnPAWN;//兵

}

TSideOpponent(TSideside)

{//获取对手类型

if(side==WHITE)returnBLACK;

returnWHITE;

}

voidclear(TBoardb,intx,inty)

{//清空棋盘b的(x,y)位置b[x][y].side=NONE;//所属玩家b[x][y].pt=SPACE;//棋子类型

}

voidinit(TBoardb)

{//初始化棋盘

inti,j;

//清空整个棋盘

for(i=0;i

clear(b,i,j);

}

//摆放各个棋子for(i=0;i

//棋盘前两行是白方

b[0][i].side=WHITE;

b[1][i].side=WHITE;

b[1][i].pt=PAWN;//上面第二行是白方的兵//棋盘最后两行是黑方

b[6][i].side=BLACK;

b[7][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;//b[0][1].pt=b[0][6].pt=b[7][1].pt=b[7][6].pt=KNIGHT;//b[0][2].pt=b[0][5].pt=b[7][2].pt=b[7][5].pt=BISHOP;//b[0][3].pt=b[7][3].pt=QUEEN;//初始化后的位置b[0][4].pt=b[7][4].pt=KING;//初始化王的位置//初始化王车易位使用的布尔变量whitecastled=false;

blackcastled=false;

white0rookMoved=false;white7rookMoved=false;

black0rookMoved=false;black7rookMoved=false;

whitekingMoved=false;

blackkingMoved=false;

}

voidSkipInput(intk)

{//棋局已经结束,忽略剩余的输入inti;

charmv[20];for(i=k;i

{scanf_s("%s",mv);

}

}

voidGetPosition(conststring&move,int&x,int&y)

{//从输入的移动步骤中获取棋子的目标位置

intk=0;

if(move[0]<'a')//首字母是大写字母

k=1;

x=move[k+1]-'1';//行

y=move[k]-'a';//列

}

boolOutOfBoard(intx,inty)

{//棋子是否超出棋盘界限

if(x<0||y<0)

{

returntrue;

}

if(x>BOARDSIZE||y>BOARDSIZE)

{

returntrue;

}

returnfalse;

}

boolCanMovePawn(TBoardb,intx,inty,intx2,inty2,intflag)

{//判断能否把兵从(x,y)移动到(x2,y2),当flag=1时,表示(x,y)直接移动到(x2,y2),flag为其他表示从(x,y)吃子到(x2,y2)

if(flag==1){//直接移动,即兵直线前进一格

if(y!

=y2||b[x2][y2].side!

=NONE)

{//y坐标不能改变,无法前进

returnfalse;

}

if(b[x][y].side==WHITE)

{//下棋的是白方

if(x==1)

{//白方的兵是第一次移动

returnx2==2||(x2==3&&b[2][y].side==NONE);//第一次移动兵可以移动格

或格

}else

{

returnx2==x+1;//不是第一次移动,就只能向前移动格

}

}

else

{//下棋的是黑方

if(x==6)

{//黑方的兵是第一次移动

returnx2==5||(x2==4&&b[5][y].side==NONE);//第一次移动兵可以移动格

或格

}

else

{

returnx2==x-1;//不是第一次移动,就只能向前移动格}

}

else

{//吃子判断,吃子时,x向前格,y坐标改变格

if(b[x][y].side==WHITE)

{//要吃子的是白方

return(x2==x+1&&abs(y2-y)==1);

}

else

{//要吃子的是黑方

return(x2==x-1&&abs(y2-y)==1);

}

}returnfalse;

boolCanMoveKing(TBoardb,intx,inty,intx2,inty2)

{//判断能否把王从(x,y)移动到(x2,y2)return(abs(x-x2)<=1&&abs(y-y2)<=1);

}

boolCanMoveRook(TBoardb,intx,inty,intx2,inty2)

{//判断能否把车从(x,y)移动到(x2,y2)intdx,dy,i,xx,yy;

//判断移动是否是直线

if(x!

=x2&&y!

=y2)

{

returnfalse;

}

//直线方向增量

if(x2

else

dx=1;

if(y2

dy=-1;

else

dy=1;

//x方向上移动

for(i=1;i

yy=y+i*dy;

if(b[x][yy].side!

=NONE)

{//中间有棋子阻挡

returnfalse;

}//y

}

方向上移动

for(i=1;i

{

xx=x+i*dx;

if(b[xx][y].side!

=NONE)

{//中间有棋子阻挡returnfalse;

}

}returntrue;

}

boolCanMoveBishop(TBoardb,intx,inty,intx2,inty2)

{//判断能否把象从(x,y)移动到(x2,y2)intdx,dy,i,xx,yy;

//是否斜向移动

if(abs(x-x2)!

=abs(y-y2))

{

returnfalse;

}

//直线方向增量

if(x2

dx=-1;

elsedx=1;

if(y2

dy=-1;

elsedy=1;

for(i=1;i

{

xx=x+i*dx;

yy=y+i*dy;

if(b[xx][yy].side!

=NONE){//中间有棋子阻挡returnfalse;

}

}

returntrue;

}

boolCanMoveQueen(TBoardb,intx,inty,intx2,inty2)

{//判断能否把王从(x,y)移动到(x2,y2)

returnCanMoveRook(b,x,y,x2,y2)||CanMoveBishop(b,x,y,x2,y2);//王后等于车+象

}

boolCanMoveKnight(intx,inty,intx2,inty2)

{//判断马能否从(x,y)移动到(x2,y2)

intxx,yy;

xx=abs(x-x2);

yy=abs(y-y2);

return(xx+yy==3&&(xx==1||yy==1));//马行日,x或者y这两者之一移动格,另一方向移动格

}

boolCanMove(TBoardb,intx,inty,intx2,inty2,intflag)

{//判断一个棋子能否从(x,y)移动到(x2,y2),当flag=1时,直接移动,flag=2时,表示把(x2,y2)处的棋子给吃掉

//判断是否越界

if(OutOfBoard(x,y)||OutOfBoard(x2,y2))

{

returnfalse;

}

//判断原位置是否有棋子

if(b[x][y].side==NONE)

{

returnfalse;

}

//根据原来位置上棋子的不同类型判断是否合法

switch(b[x][y].pt)

{casePAWN:

//兵returnCanMovePawn(b,x,y,x2,y2,flag);

caseKING:

//王

returnCanMoveKing(b,x,y,x2,y2);

caseQUEEN:

//后

returnCanMoveQueen(b,x,y,x2,y2);

caseROOK:

/库

returnCanMoveRook(b,x,y,x2,y2);

caseBISHOP:

/像

returnCanMoveBishop(b,x,y,x2,y2);

caseKNIGHT:

//马

returnCanMoveKnight(x,y,x2,y2);

}

returnfalse;

}

voidGetSourcePosition(TBoardb,intx2,inty2,int&x,int&y,TPieceTypect,TSideside)

{/*从给出的位置(x2,y2),类型ct和玩家side,求出移动的棋子的原来位置(x,y),,

*当x=-2时,表示有重复移动方案(Puzzle),x=-1时表示没有移动可能(illegal)

*/

inti,j,flag=1;

if(b[x2][y2].side!

=NONE)//目标位置是对手的棋子,则此步为吃子方案flag=2;

for(i=0;i

{

for(j=0;j

{

if(b[i][j].side==side&&b[i][j].pt==ct)

{//原位置合法并且是同一个子if(CanMove(b,i,j,x2,y2,flag))

{

if(x==-1)

{//能够移动并且不重复,找到原来棋子的位置x=i;

y=j;

}

else

{//能够移动并且有方案,说明有重复x=-2;

return;

}

}

}

voidMarkRookMove(TSideside,intx,inty){

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;//黑方号车已经移动}

voidChessMove(TBoardb,intx,inty,intx2,inty2)

{//棋子从(x,y)移动到(x2,y2)

b[x2][y2].side=b[x][y].side;

b[x2][y2].pt=b[x][y].pt;

clear(b,x,y);//清空原位置

}

voidMakeMove(TBoardb,conststring&move,TSideside){//根据输入的步骤mv,玩家side移动棋子

intx,y,x2,y2;

GetPosition(move,x2,y2);//目标位置

if(b[x2][y2].side==side)

{//目标位置处已经有我方的棋子了,此步非法

result=ILLEGAL;return;

}

x=-1;

GetSourcePosition(b,x2,y2,x,y,ChessType(move),side);//尝试寻找原位置if(x==-1)

{//非法状态

result=ILLEGAL;return;

}

elseif(x==-2)

{//重复状态

result=PUZZLE;return;

}//移动的棋子是车时,设置王车易位布尔变量if(b[x][y].pt==ROOK)

{

MarkRookMove(side,x,y);

}

//移动的棋子是王时,设置王车易位布尔变量

if(b[x][y].pt==KING)

{

if(side==WHITE)//白方王移动了whitekingMoved=true;

else//黑方王移动了blackkingMoved=true;

}ChessMove(b,x,y,x2,y2);//移动棋子

}

boolGridBeAttack(TBoardb,intx,inty,TSidebyWho)

{//判断位置(x,y)的棋子能否被吃掉

inti,j;

for(i=0;i

{

for(j=0;j

{

if(b[i][j].side==byWho&&CanMove(b,i,j,x,y,2)){//会被对手吃掉的returntrue;

}

}

}

returnfalse;

}

boolCanCastle(TBoardb,TSideside,intflag)

{//判断是否能够进行王车易位

introw,i;

if(side==WHITE)

{//白方王车易位

if(whitekingMoved==true)

{//王已经动了,不能王车易位returnfalse;

}

if(flag==3&&white7rookMoved==true)

{//目标车已经动了,不能王车易位returnfalse;

}

if(flag==5&&white0rookMoved==true)

{//目标车已经动了,不能王车易位returnfalse;

}

}

else

{//黑方王车易位

if(blackkingMoved==true)

{//王已经动了returnfalse;

}

if(flag==3&&black7rookMoved==true)

{//目标车已经动了,不能王车易位returnfalse;

}

if(flag==5&&black0rookMoved==true)

{//目标车已经动了,不能王车易位returnfalse;

}

}

if(side==WHITE)

row=0;

else

row=7;

if(flag==5)

for(i=1;i<4;++i)

{

if(b[row][i].side!

=NONE)

{//王车之间是否有棋子,若有则不能易位

returnfalse;

}

for(i=0;i<5;++i)

{

if(GridBeAttack(b,row,i,Opponent(side))==true)

{//在目标位置上会被对手吃掉,不能王车易位returnfalse;

}

}}else

{

for(i=5;i

{

if(b[row][i].side!

=NONE)

{//王车之间是否有棋子,若有则不能易位

returnfalse;

}

}

for(i=4;i

{

if(GridBeAttack(b,row,i,Opponent(side)))

{//在目标位置上会被对手吃掉,不能王车易位returnfalse;

}

}

}returntrue;//检查符合要求,可以王车易位

}

voidCastle(TBoardb,TSideside,intflag)

{//进行王车易位,flag=3,表示靠近王的车King-sidecastle,flag=5时,表示Queen-sidecastle

introw;

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;

}

}

voidGetKingPosition(TBoardb,TSideside,int&x,int&y)

{//寻找国王的位置

inti,j;

for(i=0;i

for(j=0;j

{

if(b[i][j].pt==KING&&b[i][j].side==side)

{//找到指定方的王

x=i;y=j;return;

}

}

}

boolBeCheck(TBoardb,TSideside)

{//判断是否被“将军"

intx,y,i,j;

TSideoppSide;

GetKingPosition(b,side,x,y);//寻找玩家side的王oppSide=Opponent(side);//对手for(i=0;i

{

for(j=0;j

{

if(b[i][j].side==oppSide&&CanMove(b,i,j,x,y,2)==true)

{//判断对手是否能否将军,flag=2表示此步是吃子,returntrue;

}

}

}

returnfalse;

}

voidCopyBoard(TBoarddesBoard,TBoardsrcBoard)

{//复制棋盘

inti,j;

for(i=0;i

{

for(j=0;j

{

desBoard[i][j].pt=srcBoard[i][j].pt;desBoard[i][j].side=srcBoard[i][j].side;

}

}

boolNoMoveAvailable(TBoardb,TSideside)

{//判断是否是僵局

intx,y,x2,y2;

TBoardb2;

for(x=0;x

{

for(y=0;y

if(b[x][y].side==side)

{

for(x2=0;x2<

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 历史学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1