国际象棋C++.docx

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

国际象棋C++.docx

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

国际象棋C++.docx

国际象棋C++

#include

#include

#include

usingnamespacestd;

enumTResult

{//结局状态

WHITEWIN=1,//白方赢

BLACKWIN,//黑方赢

STALEMATE,//僵局

DRAW,//和局

DEAD,//过多的输入

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

ILLEGAL//非法

};

constcharRESULT[8][20]=

{//结局状态输出表示

"",

"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;//最后结局

/*

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

*

*whitecastled:

白方是否已经王车易位

*blackcastled:

黑方是否已经王车易位

*white0rookMoved:

白方号位的车是否已经移动

*white7rookMoved:

白方号位的车是否已经移动

*black0rookMoved:

黑方号位的车是否已经移动

*black7rookMoved:

黑方号位的车是否已经移动

*whitekingMoved:

白方王是否已经移动

*blackkingMoved:

黑方王是否已经移动

*

*/

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

for(j=0;j

{

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

dx=-1;

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;

else

dx=1;

if(y2

dy=-1;

else

dy=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;

}

}

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

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

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

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