涉及循环、数组、指针、队列,适合初学者
不多废话,上代码!
//此段代码在Visual Studio Code中C语言环境中正常运行,无error、无warning
//输入坐标时只要按照 “数字,数字” (英文逗号)格式输入即可正常执行
//程序可以悔棋(一次只能悔去上一步棋),可以复盘
//输入坐标不在棋盘位置内或是棋盘该点已有棋子时会提示重新输入
//只需在verdict函数中修改if语句中notre的值便可实现任意指棋
#include
#include
#define MAXSIZE 400 //棋盘棋子容量
#define true 1
#define false 0
int a[20][20]={0},sum=0; //a记录棋子位置,sum记录落子数,队列用来复盘
typedef struct
{
int hang; //棋子的行
int lei; //棋子的列
char e; //棋子属性
}Element;
typedef struct LinkQueueNode
{
Element data;
struct LinkQueueNode *next;
}LinkQueueNode;
typedef struct
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
int Init(LinkQueue *Q) //初始化队列
{
Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if(Q->front!=NULL){
Q->rear=Q->front;
Q->front->next=NULL;
return(true);
}
return(false);
}
int Enter(LinkQueue *Q,int p,int q,char cc) //棋子入队
{
LinkQueueNode *NewNode;
NewNode=(LinkQueueNode*)malloc(sizeof(LinkQueueNode));
if(NewNode!=NULL){
NewNode->data.hang=p-1;
NewNode->data.lei=q-1;
NewNode->data.e=cc;
NewNode->next=NULL;
Q->rear->next=NewNode;
Q->rear=NewNode;
return(true);
}
return(false);
}
int Delete(LinkQueue *Q,int *x,int *y,char *c) //棋子出队
{
LinkQueueNode *p;
if(Q->front==Q->rear)
return(false);
p=Q->front->next;
Q->front->next=p->next;
if(Q->rear==p)
Q->rear=Q->front;
*x=p->data.hang;
*y=p->data.lei;
*c=p->data.e;
free(p);
return(true);
}
void PrintBoard(int i,int j) //打印当前棋盘
{
for(int m=0;mfront!=Q->rear){
Delete(Q,&x,&y,&c);
printf("%c:%d,%d\n",c,x+1,y+1);
}
exit(0);
}
else exit(0);
}
int main()
{
LinkQueue Q;
Init(&Q);
int p=0,q=0;
int m,n;
char c1='@',c2='#';
PrintBoard(20,20);
printf("Enter 0,0 for regret(In the previous step)\n");
while(1){
printf("White cordinates:");
scanf("%d,%d",&p,&q);
if(p==0&&q==0){ //悔棋(悔掉上一步黑棋)
Enter(&Q,p,q,c2);
a[m-1][n-1]=0;
sum--;
}
else if(a[p-1][q-1]==0&&p<=20&&p>=1&&q<=20&&q>=1){ //白棋落子
a[p-1][q-1]=1;
Enter(&Q,p,q,c1);
m=p,n=q;
sum++;}
else continue;
system("cls"); //清屏
PrintBoard(20,20);
if(verdict(p-1,q-1,1)==1){ //一方胜利后即选择是否复盘
printf("White win!");
replay(&Q);
exit(0);}
while(1){
printf("Black coordinates:");
scanf("%d,%d",&p,&q);
if(p==0&&q==0){ //悔棋(悔掉上一步白棋)
a[m-1][n-1]=0;
Enter(&Q,p,q,c1);
sum--;
break;}
if(a[p-1][q-1]==0&&p<=20&&p>=1&&q<=20&&q>=1){ //黑棋落子
a[p-1][q-1]=2;
Enter(&Q,p,q,c2);
m=p,n=q;
sum++;
break;}
}
system("cls");
PrintBoard(20,20);
if(verdict(p-1,q-1,2)==2){ //一方胜利后即选择是否复盘
printf("Black win!");
replay(&Q);
exit(0);}
if(sum==400){ //棋盘若满,平局
printf("it ends in a draw!");
exit(0);}
}
return 0;
}