涉及循环、数组、指针、队列,适合初学者
不多废话,上代码!
//此段代码在Visual Studio Code中C语言环境中正常运行,无error、无warning
//输入坐标时只要按照 “数字,数字” (英文逗号)格式输入即可正常执行
//程序可以悔棋(一次只能悔去上一步棋),可以复盘
//输入坐标不在棋盘位置内或是棋盘该点已有棋子时会提示重新输入
//只需在verdict函数中修改if语句中notre的值便可实现任意指棋
#include<stdio.h>
#include<stdlib.h>
#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;m<i;m++){
for(int n=0;n<j;n++){
if(a[m][n]==0){
printf(". ");
}
else if(a[m][n]==1){
printf("@ ");
}
else{
printf("# ");
}
}
printf("\n");
}
}
int verdict(int row,int col,int x) //判断是否构成五子
{
int m=col-1,n=col+1;
int notre=1;
//横向判断
for(int i=col-1;a[row][i]==x;i--)
notre++;
for(int i=col+1;a[row][i]==x;i++)
notre++;
if(notre==5){
return x;
}
else notre=1;
//竖向判断
for(int i=row-1;a[i][col]==x;i--)
notre++;
for(int i=row+1;a[i][col]==x;i++)
notre++;
if(notre==5){
return x;
}
else notre=-1;
//斜向判断(左斜)
for(int i=row,j=col;a[i][j]==x;i--,j--){
notre++;
}
for(int i=row,j=col;a[i][j]==x;i++,j++){
notre++;
}
if(notre==5){
return x;
}
else notre=-1;
//斜向判断(右斜)
for(int i=row,j=col;a[i][j]==x;i--,j++){
notre++;
}
for(int i=row,j=col;a[i][j]==x;i++,j--){
notre++;
}
if(notre==5){
return x;
}
}
void replay(LinkQueue *Q) //选择是否复盘
{
int i,x,y;
char c;
printf("\nWhether to rematch the chess game?");
printf("\nInput 1 is / Input 2 end : ");
scanf("%d",&i);
if(i==1){
while(Q->front!=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;
}
版权声明:本文为m0_57538148原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。