用C写五子棋
用这种办法写出的五子棋程序比较简单。
核心代码在于判断判断四个方向上的五个棋子是不是一致,如果是一致的则跳出Game()并宣布某方获得胜利,如果不一致则继续下棋。
但是我并没有设立人人对战,只设立了人机对战。
人机对战,我采用的仍是大多数时候选用的获得随机数的方法:rand函数,通过srand(time(NULL))给rand()一个种子从而获得随机数。通过随机数,我们就可以让电脑进行“下棋”。
话不多说,上代码。
还是说明一下rand函数:
rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的。
rand函数需要有srand()函数用来设置rand()产生随机数时的随机数种子。
参数seed是整数,通常可以利用time(0)或getpid(0)的返回值作为seed。
下面是头文件和宏定义部分:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define hang 14 //定义行是14
#define lie 14 //定义列是14
char map[hang][lie]; //定义了一个二维数组来存放棋子
这里没什么特别好说的┗|`O′|┛ 嗷
下面是初始化部分:
void init(void)
{
int i,j;
for(i=4;i<hang-4;i++)
{
for(j=4;j<lie-4;j++)
{
map[i][j]='*'; //这里可以使用空格,我习惯用星号作为底板了
}
}
}
那么看到这里,肯定会有人问为什么这里要这么初始化,空出了好多空间,其实这里边存在着一个数组越界的问题。
因为我们需要判断四个方向上棋子是否一致,那么如果我们需要判断的棋子的位置在棋盘的四个角,那么就会发生数组越界,数组的空间如果定义的正正好好,那么很容易出现出map[-1] map[-2] map[-3] 等等这样的负值情况,因为这是个小程序,所以一般情况下不会崩溃,但是要知道数组越界存在让程序崩溃的可能。如果数组越界的情况下,程序仍旧能正常运行的话,那么只能这么解释:
坐火车,你买的是一张站票/(ㄒoㄒ)/~~
但是你运气很好,你发现有一个座位正好是空着的o( ̄▽ ̄)ブ
于是你抱着试一试的心理坐在了那个位置上,想着坐一会儿就行,可是没想到你运气特别好一直做到了终点站还顺利下车了
也就是说你数组越界的那一部分的地址并没有其他程序在使用,所以是正常运行起来了,这一般是小程序,大程序的话很容易发生崩溃或出现BUG。
好了,言归正传,我们继续。
下面是打印棋盘:
void drawmap(void)
{
int i,j;
printf("0 "); //纵坐标的序号(列)
for(i=4;i<hang-4;i++)
{
printf("%d ",i);
}
printf("\n");
printf("\n");
printf("\n");
printf("\n");
for(i=4;i<hang-4;i++)
{
printf("%d ",i); //横坐标的序号(行)
for(j=4;j<lie-4;j++)
{
printf("%c ",map[i][j]); //契合上面的初始化
}
printf("\n");
}
}
下面是判断部分,即假设棋子所在的位置,那么这个位置各个方向的四个棋子和它本身是不是一致的,如果是一致的return 1,如果不一致return 0。一共是十七个可能出现的位置,那么就针对这十七个点就行逐一判断,我们确保它们都是五个都是一样的棋子(字符)。
int judge(int x,int y)
{
if(map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2]&&map[x][y]==map[x+3][y+3]&&map[x][y]==map[x+4][y+4])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2]&&map[x][y]==map[x+3][y+3])
{
return 1;
}
if(map[x][y]==map[x-1][x-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x-3][y-3]&&map[x][y]==map[x+1][y+1])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x-3][y-3]&&map[x][y]==map[x-4][y-4])
{
return 1;
}
if(map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2]&&map[x][y]==map[x+3][y-3]&&map[x][y]==map[x+4][y-4])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2]&&map[x][y]==map[x+3][y-3])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2])
{
return 1;
}
if(map[x][y]==map[x+1][y-1]&&map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x-3][y+3])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x-3][y+3]&&map[x][y]==map[x-4][y+4])
{
return 1;
}
if(map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2]&&map[x][y]==map[x][y+3]&&map[x][y]==map[x][y+4])
{
return 1;
}
if(map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2]&&map[x][y]==map[x][y+3])
{
return 1;
}
if(map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2])
{
return 1;
}
if(map[x][y]==map[x][y-3]&&map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1])
{
return 1;
}
if(map[x][y]==map[x][y-4]&&map[x][y]==map[x][y-3]&&map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1])
{
return 1;
}
if(map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y]&&map[x][y]==map[x+3][y]&&map[x][y]==map[x+4][y])
{
return 1;
}
if(map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y]&&map[x][y]==map[x+3][y])
{
return 1;
}
if(map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y])
{
return 1;
}
if(map[x][y]==map[x-3][y]&&map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y])
{
return 1;
}
if(map[x][y]==map[x-4][y]&&map[x][y]==map[x-3][y]&&map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y])
{
return 1;
}
return 0;
}
接下来就是Game函数,游戏部分Game()
void Game(void)
{
int x,y;
int x0,y0,n=0; //n是为了计我们下的棋和电脑下的棋的棋数量的和
init();
while(1)
{
system("cls");
drawmap();
printf("你的回合,请输入坐标:(行,列)\n");
scanf("%d%d",&x,&y);
if(x<4||x>9||y<4||y>9||map[x][y]!='*') //判断输入的坐标是否合法
{
printf("坐标不合法,请重试\n");
system("pause");
continue;
}
else
{
map[x][y]='X';
n++; //我们下了一步
}
while(1)
{
srand(time(NULL)); //电脑下棋阶段
x0=rand()%6+4;
y0=rand()%6+4;
if(map[x0][y0]!='*') //如果不是*就重新获得随机数以此让电脑换一步棋
{
continue;
}
else
{
map[x0][y0]='O';
n++; //电脑下了一步
break;
}
}
if(judge(x,y)==1)
{
system("cls");
drawmap();
printf("你获胜啦!\n");
system("pause");
break;
}
if(judge(x0,y0)==1)
{
system("cls");
drawmap();
printf("电脑获胜!\n");
system("pause");
break;
}
if(n==36) //我们的棋盘是6*6的,所以是当n计数是36个的时候判断平局
{
printf("平局!\n");
}
}
}
在这里说一下哈(不要打我/(ㄒoㄒ)/~~),电脑实在是太笨了,因为只是单纯靠时间当种子获得随机数,电脑几乎不可能五子一线我们赢的成功率几乎就是100% 所以我也没有设计出太大的棋盘,因为没有太大的意义。人人对战的话我也感觉没太大意思,所以我就只用了6*6的棋盘,如果有兴趣可以设计出更大的棋盘。
下面是菜单函数:
void menu(void)
{
printf("==============================\n");
printf("===========五子棋=============\n");
printf("==============================\n");
printf("=========1.开始游戏===========\n");
printf("==============================\n");
printf("=========2.退出游戏===========\n");
printf("==============================\n");
printf("==============================\n");
}
这里没什么特别的,继续(* ̄(oo) ̄)
main函数:
int main()
{
char choice,c;
int start,end; //统计时间
system("color 3");
while(1)
{
menu();
printf("请输入你的选择:\n");
scanf(" %c",&choice);
switch(choice)
{
case '1':
{
start=clock();
Game();
break;
}
case '2':
{
printf("正在退出...\n");
Sleep(1000);
return 0;
}
default:printf("输入无效,请尝试重新输入\n");
continue;
break;
}
end=clock();
printf("你的用时是%d秒...\n",(end-start)/1000);
system("pause&&cls");
printf("是否继续游戏?(Y/N)\n");
scanf(" %c",&c);
if(c=='n'||c=='N')
{
break;
}
}
return 0;
}
那么到这里所有的部分函数就结束了,下面附上源代码:
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
#define hang 14
#define lie 14
char map[hang][lie];
void init(void)
{
int i,j;
for(i=4;i<hang-4;i++)
{
for(j=4;j<lie-4;j++)
{
map[i][j]='*';
}
}
}
void drawmap(void)
{
int i,j;
printf("0 ");
for(i=4;i<hang-4;i++)
{
printf("%d ",i);
}
printf("\n");
printf("\n");
printf("\n");
printf("\n");
for(i=4;i<hang-4;i++)
{
printf("%d ",i);
for(j=4;j<lie-4;j++)
{
printf("%c ",map[i][j]);
}
printf("\n");
}
}
int judge(int x,int y)
{
if(map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2]&&map[x][y]==map[x+3][y+3]&&map[x][y]==map[x+4][y+4])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2]&&map[x][y]==map[x+3][y+3])
{
return 1;
}
if(map[x][y]==map[x-1][x-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x+1][y+1]&&map[x][y]==map[x+2][y+2])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x-3][y-3]&&map[x][y]==map[x+1][y+1])
{
return 1;
}
if(map[x][y]==map[x-1][y-1]&&map[x][y]==map[x-2][y-2]&&map[x][y]==map[x-3][y-3]&&map[x][y]==map[x-4][y-4])
{
return 1;
}
if(map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2]&&map[x][y]==map[x+3][y-3]&&map[x][y]==map[x+4][y-4])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2]&&map[x][y]==map[x+3][y-3])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x+1][y-1]&&map[x][y]==map[x+2][y-2])
{
return 1;
}
if(map[x][y]==map[x+1][y-1]&&map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x-3][y+3])
{
return 1;
}
if(map[x][y]==map[x-1][y+1]&&map[x][y]==map[x-2][y+2]&&map[x][y]==map[x-3][y+3]&&map[x][y]==map[x-4][y+4])
{
return 1;
}
if(map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2]&&map[x][y]==map[x][y+3]&&map[x][y]==map[x][y+4])
{
return 1;
}
if(map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2]&&map[x][y]==map[x][y+3])
{
return 1;
}
if(map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1]&&map[x][y]==map[x][y+2])
{
return 1;
}
if(map[x][y]==map[x][y-3]&&map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1]&&map[x][y]==map[x][y+1])
{
return 1;
}
if(map[x][y]==map[x][y-4]&&map[x][y]==map[x][y-3]&&map[x][y]==map[x][y-2]&&map[x][y]==map[x][y-1])
{
return 1;
}
if(map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y]&&map[x][y]==map[x+3][y]&&map[x][y]==map[x+4][y])
{
return 1;
}
if(map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y]&&map[x][y]==map[x+3][y])
{
return 1;
}
if(map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y]&&map[x][y]==map[x+2][y])
{
return 1;
}
if(map[x][y]==map[x-3][y]&&map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y]&&map[x][y]==map[x+1][y])
{
return 1;
}
if(map[x][y]==map[x-4][y]&&map[x][y]==map[x-3][y]&&map[x][y]==map[x-2][y]&&map[x][y]==map[x-1][y])
{
return 1;
}
return 0;
}
void Game(void)
{
int x,y;
int x0,y0,n=0;
init();
while(1)
{
system("cls");
drawmap();
printf("你的回合,请输入坐标:(行,列)\n");
scanf("%d%d",&x,&y);
if(x<4||x>9||y<4||y>9||map[x][y]!='*')
{
printf("坐标不合法,请重试\n");
system("pause");
continue;
}
else
{
map[x][y]='X';
n++;
}
while(1)
{
srand(time(NULL));
x0=rand()%6+4;
y0=rand()%6+4;
if(map[x0][y0]!='*')
{
continue;
}
else
{
map[x0][y0]='O';
n++;
break;
}
}
if(judge(x,y)==1)
{
system("cls");
drawmap();
printf("你获胜啦!\n");
system("pause");
break;
}
if(judge(x0,y0)==1)
{
system("cls");
drawmap();
printf("电脑获胜!\n");
system("pause");
break;
}
if(n==36)
{
printf("平局!\n");
}
}
}
void menu(void)
{
printf("==============================\n");
printf("===========五子棋=============\n");
printf("==============================\n");
printf("=========1.开始游戏===========\n");
printf("==============================\n");
printf("=========2.退出游戏===========\n");
printf("==============================\n");
printf("==============================\n");
}
int main()
{
char choice,c;
int start,end;
system("color 3");
while(1)
{
menu();
printf("请输入你的选择:\n");
scanf(" %c",&choice);
switch(choice)
{
case '1':
{
start=clock();
Game();
break;
}
case '2':
{
printf("正在退出...\n");
Sleep(1000);
return 0;
}
default:printf("输入无效,请尝试重新输入\n");
continue;
break;
}
end=clock();
printf("你的用时是%d秒...\n",(end-start)/1000);
system("pause&&cls");
printf("是否继续游戏?(Y/N)\n");
scanf(" %c",&c);
if(c=='n'||c=='N')
{
break;
}
}
return 0;
}
到这里就结束了,勉强跑一跑吧o( ̄▽ ̄)ブ这实际上是一个测试版的程序,之前有一个多层循环判断五子棋的函数人机人人都是挺不错的,今天测试一下能勉强跑一跑ε=ε=ε=( ̄▽ ̄)
如有错误,大佬评论区留言喔。谢谢大家。