转载注上出处:https://blog.csdn.net/coder_what/article/details/83592729
大一无聊时写的五子棋
先放上代码,有空就来解释
//头文件
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
//宏定义
#define C 16//oordinate 用于便捷改变棋盘的长宽
//全局变量
char cheakboard[C][C];//棋盘的打印
int x,y,i,j;//用于循环的i,j和用于坐标定位的x,y
int n=1;
//函数声明
void model();//C*C的*模板
void printm();//打印*模板
void Pos(int,int);//光标位置的句柄
void work();//下棋过程,包括胜利后的判断,要嵌套有judge、whiteplay和blackplay函数
int judge(int,int);//判断是否连成五个子
void printn();//打印数字坐标模板
void whiteplay();//白方下子
void blackplay();//黑方下子
int* correct(int,int);//纠正下子覆盖问题,通过指针使其返回2个值
void printa();//将*模板和数字模板组合在一起
//主函数
int main()
{
int n=1;
system("Gobang");
while(1)
{
system("cls");
model();
printa();
Pos(20,20);
printf("This is the %dst game",n++);//判断局数
work();
}
return 0;
}
//自定义函数
void Pos(int x, int y)
{
COORD pos;
HANDLE h0utput;
pos.X=x;
pos.Y=y;
h0utput=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(h0utput, pos);
}
void model()
{
for(i=0;i<C;i++)
{
for(j=0;j<C;j++)
cheakboard[i][j]='*';
}
}
void printm( int n)
{
for(i=0;i<C;i++)
{
Pos(2,1+i);
for(j=0;j<C;j++)
printf("%3c",cheakboard[i][j]);
}
// printf("\n\n\t\tThis is the %dst game",n++);
}
void work()
{
char temp;
while(1)
{
whiteplay();
if(judge(x,y)==1)
{
system("cls");
printa();
printf("\n\nMr.White wins\n");
system("pause");
printf("Do you wanna restart the game:\n'y' or 'n':");
scanf("%c",&temp);
if(getch()=='n')
{
system("cls");
printf("\n\n\tgame over");
exit(0);
}
if(getch()=='y')
break;
}
blackplay();
if(judge(x,y)==1)
{
system("cls");
printa();
printf("\n\nMr.Black wins\n");
system("pause");
printf("Do you wanna restart the game:\n'y' or 'n':");
scanf("%c",&temp);
if(getch()=='n')
{
system("cls");
printf("\n\n\tgame over");
exit(0);
}
if(getch()=='y')
break;
}
}
}
int judge(int x,int y)
{
char temp=cheakboard[x][y];
int count=0;
i=0,j=0;
while(cheakboard[x][y-i]==temp) //基于x轴
{
i++;
}
while(cheakboard[x][y+j]==temp)//判断一次需要两个循环是因为先回到x轴最左边,然后从最左边数
{
j++;
count=i+j;
if(count==6)//此处为什么是6
return 1;
}
i=0,j=0,count=0;
while(cheakboard[x-i][y]==temp) //基于y轴
{
i++;
}
while(cheakboard[x+j][y]==temp)
{
j++;
count=i+j;
if(count==6)//此处为什么是6
return 1;
}
int a=0,b=0;
i=0,j=0,count=0;
while(cheakboard[x-a][y-i]==temp) //基于左上轴
{
i++;
a++;
}
while(cheakboard[x+b][y+j]==temp)
{
j++;
b++;
count=i+j;
if(count==6)//此处为什么是6
return 1;
}
i=0,j=0,a=0,b=0,count=0;
while(cheakboard[x-a][y+i]==temp) //基于右上轴
{
i++;
a++;
}
while(cheakboard[x+b][y-j]==temp)
{
j++;
b++;
count=i+j;
if(count==6)//此处为什么是6
return 1;
}
}
void printn()
{
printf(" @");
for(i=1;i<=C;i++)//行
printf("%3d",i);
for(i=1;i<=C;i++)//列
{
Pos(0,i);
printf("%d",i);
}
}
void whiteplay()
{
int* temp;
printf("\n\nplease input the row and column for White:");
scanf("%d%d",&x,&y);
x-=1;
y-=1;
correct(x,y);
temp=correct(x,y);
x=temp[0];
y=temp[1];
cheakboard[x][y]='0';
system("cls");
printa();
}
void blackplay()
{
int* temp;//临时变量
printf("\n\nplease input the row and column for Black:");
scanf("%d%d",&x,&y);
x-=1;
y-=1;
temp=correct(x,y);
x=temp[0];
y=temp[1];
cheakboard[x][y]='1';
system("cls");
printa();
}
int* correct(int x,int y)
{
int coor[2];//返回x,y的数组指针
while(1)
{
if(cheakboard[x][y]=='*')
{
coor[0]=x;
coor[1]=y;
return coor;//应该返回两个值
}
else
{
system("cls");
printa();
printf("\ninput error,please input again:");
scanf("%d%d",&x,&y);
x-=1;
y-=1;
}
}
}
void printa()
{
printn();
printm();
}
//感觉应该建立一个识别唯一性的函数 ,好波又感觉不用了
//还想添加的一些功能有:1.撤回 2.一共下了几次棋 3.把出子过程和最终的棋谱以文件的形式记录下来 4.颜色5.自己改参数
//本来建立了一个afterw()函数用来进行获胜之后的步骤,但是break在afterw中用不了
/*void afterw()
{
printf("Do you wanna restart the game:\n'y' or 'n':");
scanf("%c",&temp);
if(getch()=='n')
{
system("cls");
printf("\n\n\tgame over");
exit(0);
}
if(getch()=='y')
break;
}*/