老套路,二维数组存储棋盘,宏定义各种棋子,每次棋子的移动实质为二维数组的赋值。
重点是判断棋子是否可移动到目标位置,移动有两种可能,一是单纯移动,二是吃子移动。主要飞将的特殊规则。废话不多说,贴源码(主要下面是两个源文件哦,嘿嘿。)
main.c
#include
#include
#include
//自定义源文件(棋谱结构)
#include"manual.c"
//棋盘行列
#define ROWS 10
#define COLS 9
//空地
#define white 0
//红方棋子
#define isred (map[i][j]>0&&map[i][j]<10)
#define ju 1
#define ma 2
#define xiang 3
#define shi 4
#define shuai 5
#define pao 6
#define bing 7
//黑方棋子
#define isblack (map[i][j]>10)
#define Ju 11
#define Ma 12
#define Xiang 13
#define Shi 14
#define Jiang 15
#define Pao 16
#define Zu 17
//控制输出颜色
#define NONECOLOR SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7)
#define REDCOLOR SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED)
#define GREENCOLOR SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN)
//当前玩家
#define red 1
#define black 0
//地图
int map[ROWS][COLS]={white};
//棋步
char step[20];
//初始化地图
void InitializeMap()
{
int i,j;
for(i=0;iROWS||(*y1)<0||(*y1)>COLS||(*x2)<0||(*x2)>ROWS||(*y2<0)||(*y2)>COLS)
{
return 0;
}
else if((*x1)==(*x2)&&(*y1)==(*y2))
{
return 0;
}
return 1;
}
//判断是否已经结束游戏(-1:黑胜 0:还没结束 1:红胜)
int isOver()
{
int i,j;
//没有將时红胜,没有帥时黑胜
int haveShuai=0,haveJiang=0;
for(i=0;i0&&map[x2][y2]<10&&player==red||map[x2][y2]>10&&player==black)
{
return 0;
}
int piece=map[x1][y1];
int i,j;
int start,end;
int eye_x=-1,eye_y=-1;
int count=0;
switch(piece)
{
//車、车
case ju:
case Ju:
if(x1==x2)
{
start=y1;
end=y2;
i=x1;
if(y1>y2)
{
start=y2;
end=y1;
}
for(j=start+1;jx2)
{
start=x2;
end=x1;
}
for(i=start+1;i4))
{
return 0;
}
else if(abs(x1-x2)==2&&abs(y1-y2)==2)
{
eye_x=(x1+x2)/2;
eye_y=(y1+y2)/2;
if(map[eye_x][eye_y]!=white)
{
return 0;
}
}
else
{
return 0;
}
break;
case shi:
case Shi:
//出九宫
if(player==red&&(x2<7||y2<3||y2>5)||player==black&&(x2>2||y2<3||y2>5))
{
return 0;
}
//不是走的斜一格
else if(abs(x1-x2)!=1||abs(y1-y2)!=1)
{
return 0;
}
break;
case shuai:
case Jiang:
//飞将
if((player==red&&x2<3||player==black&&x2>6)&&y1==y2)
{
start=x1;
end=x2;
j=y1;
if(x1>x2)
{
start=x2;
end=x1;
}
for(i=start+1;i5||player==red&&x2<7||player==black&&x2>2||abs(x1-x2)+abs(y1-y2)!=1)
{
return 0;
}
break;
case pao:
case Pao:
if(x1==x2)
{
start=y1;
end=y2;
i=x1;
if(y1>y2)
{
start=y2;
end=y1;
}
for(j=start+1;j1)
{
return 0;
}
else if(count==1)
{
if(map[x2][y2]>10&&player==red||map[x2][y2]>0&&map[x2][y2]<10&&player==black)
{
return 1;
}
else
{
return 0;
}
}
}
else if(y1==y2)
{
start=x1;
end=x2;
j=y1;
if(x1>x2)
{
start=x2;
end=x1;
}
for(i=start+1;i1)
{
return 0;
}
else if(count==1)
{
if(map[x2][y2]>10&&player==red||map[x2][y2]>0&&map[x2][y2]<10&&player==black)
{
return 1;
}
else
{
return 0;
}
}
}
else
{
return 0;
}
break;
case bing:
case Zu:
//不是横或纵走一格
if((abs(x1-x2)+abs(y1-y2))!=1)
{
return 0;
}
//没过河时便左右移动
if(player==red&&x1>=5&&(abs(y1-y2)==1)||player==black&&(x1<=4)&&(abs(y1-y2)==1))
{
return 0;
}
//往后退
else if(player==red&&(x1-x2==-1)||player==black&&(x2-x1==-1))
{
return 0;
}
break;
}
return 1;
}
//获得棋子名字
char *getPieceName(int piece)
{
switch(piece)
{
case Ju:
return "车";
case ju:
return "車";
case Ma:
return "马";
case ma:
return "馬";
case Xiang:
return "象";
case xiang:
return "相";
case Shi:
return "士";
case shi:
return "仕";
case Jiang:
return "將";
case shuai:
return "帥";
case Pao:
return "砲";
case pao:
return "炮";
case Zu:
return "卒";
case bing:
return "兵";
}
return "";
}
//获得棋步
void getStep(int x1,int y1,int x2,int y2,int player)
{
//清空之前棋步
step[0]='\0';
char border_red[][3]={"九","八","七","六","五","四","三","二","一"};
char border_black[][3]={"1","2","3","4","5","6","7","8","9"};
int i,j;
int piece=map[x1][y1];
int last=0,next=0;
j=y1;
for(i=0;i0)
{
strcat(step,"进");
}
else
{
strcat(step,"退");
}
strcat(step,border_black[abs(distance)-1]);
break;
case Ma:
case Xiang:
case Shi:
if(distance>0)
{
strcat(step,"进");
}
else
{
strcat(step,"退");
}
strcat(step,border_black[y2]);
break;
case ju:
case shuai:
case pao:
case bing:
if(distance>0)
{
strcat(step,"退");
}
else
{
strcat(step,"进");
}
strcat(step,border_red[9-abs(distance)]);
break;
case ma:
case xiang:
case shi:
if(distance>0)
{
strcat(step,"退");
}
else
{
strcat(step,"进");
}
strcat(step,border_red[y2]);
break;
}
}
int main()
{
InitializeMap();
//棋谱
manual m;
//初始化棋谱
initializeManual(&m);
//游戏是否已经结束
int isEnd=0;
//坐标
int x1,y1,x2,y2;
//输入是否合法
int inputRight;
//移动是否成功
int moveSuccess;
//当前玩家
int player=red;
while(!isEnd)
{
system("cls"); //清屏
displayMap(); //打印现在棋局
displayPlayer(player); //当前玩家回合
inputRight=getInput(&x1,&y1,&x2,&y2); //接收玩家输入
if(x1==-1&&x2==-1&&y1==-1&&y2==-1) //请求打印棋谱
{
displayManual(m); //打印棋谱
}
if(inputRight) //输入成功
{
//是否选择己方棋子
if(map[x1][y1]>0&&map[x1][y1]<10&&player==red||map[x1][y1]>10&&player==black)
{
//是否可以移动
moveSuccess=canMove(x1,y1,x2,y2,player);
if(moveSuccess) //可以移动
{ //按照输入移动棋子
getStep(x1,y1,x2,y2,player);
insertStep(step,&m); //添加棋步到棋谱中
printf("当前棋步为-->>%s\n",step);//打印当前棋步
system("pause");
movePiece(x1,y1,x2,y2);
exchangePlayer(&player); //移动成功,轮到对方回合
isEnd=isOver(); //判断棋局是否已经结束
}
}
}
}
system("cls");
displayMap(); //打印现在棋局
displayWinner(isEnd);
saveManual(m,"manual.txt");
return 0;
}
manual.c
#ifndef manual_c
#define manual_c
#define MAXCOUNT 200
//棋谱结构
typedef struct manual
{
int count;
char step[MAXCOUNT][20];
}manual;
//初始化棋谱
void initializeManual(manual *m)
{
m->count=0;
}
//打印棋谱
void displayManual(manual m)
{
printf("\n");
if(m.count==0)
{
printf("当前棋谱为空!\n");
}
int i;
for(i=0;i>",i/2+1);
}
printf("%s ",m.step[i]);
if(i%2==1)
{
printf("\n");
}
}
printf("\n");
system("pause");
}
//添加棋步
void insertStep(char step[],manual *m)
{
if(m->count>=MAXCOUNT)
{
return;
}
int i=m->count;
strcpy(m->step[i],step);
i++;
m->count=i;
}
//删除棋步
void deleteStep(manual *m)
{
int i=m->count;
i--;
m->count=i;
}
//保存棋谱
void saveManual(manual m,char filepath[])
{
int i;
FILE *fp=fopen(filepath,"w");
for(i=0;istep[i])==EOF)
{
break;
}
i++;
}
m->count=i;
fclose(fp);
}
#endif