实现思路:游戏首先需要菜单(菜单函数),让用户选择(选择语句)玩与结束。当选择玩的时候,我们就能进入游戏(游戏函数)。进入游戏,首先需要创建n*n规格的二维数组(并且需要一个数组清空函数(清空棋格)),然后打印一个棋盘(打印当前棋盘函数),然后提示玩家下棋(玩家下棋函数),玩家下棋之后需要打印当前棋盘并判断(判断当前情况函数)是否有一方胜利。如果继续,则轮到电脑随机下棋(电脑下棋函数),电脑下完棋打印当前棋盘并判断是否有一方胜利。判断当前情况函数中有四种情况(玩家胜,电脑胜,平局或者继续),并且平局的情况需要检查当前棋盘是否填满(判断当前是否填满函数),此函数可作为类型函数,运用选择语句根据返回值执行下一步行动。
#include<stdio.h>
#include<stdlib.h>//与srand库函数配套
#include<time.h>//与time库函数配套
#define ROW 3
#define COL 3//为了实现多子棋的变换,使用全局变量实现多处改变
void menu()
{
printf("**********************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("**********************\n");
}
void qkong(char sz[ROW][COL],int row,int col)//形参为二维数组时,必须将行列规格标准出来,并且使用时只需要数组的名字。
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
sz[i][j]=' ';
}
}
}//将目标数组的全部元素变为空格,在棋盘上体现为清零
void dying(char sz[ROW][COL],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf(" %c ",sz[i][j]);//棋盘视觉实现
if(j<col-1)//控制结尾不多余打印
printf("|");
}
printf("\n");
if(i<row-1)//打印分割行,控制多余打印
{
for(j=0;j<col;j++)
{
printf("---");
if(j<col-1)//控制结尾不多余打印
printf("|");
}
}
printf("\n");//打印棋行
}
}
void wanjia(char sz[ROW][COL],int row,int col)
{
int x,y;
while(1)//将玩家输入信息规范
{
printf("玩家请下棋:");
scanf("%d %d",&x,&y);
if(x>=1&&x<=row&&y>=1&&y<=col)//将玩家输入信息规范
{
if(sz[x-1][y-1]==' ')
{
sz[x-1][y-1]='*';
break; //跳出死循环
}
}
else printf("该棋格无法下棋,请重新输入:");
}
}
void computer(char sz[ROW][COL],int row,int col)
{
int x,y;
printf("电脑下棋\n");
while(1)//规范信息
{
x=rand()%row;//产生数在闭区间0到row-1里面
y=rand()%col;
if(sz[x][y]==' ')
{
sz[x][y]='#';
break;
}
}
}
int iffull(char sz[ROW][COL],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
if(sz[i][j]==' ')
return 1;//预示棋盘未填满
}
}
return 0;
}
char panduan(char sz[ROW][COL],int row,int col)
{
int i,j,num;
for(i=0;i<row;i++)
{
if(sz[i][0]==sz[i][1]&&sz[i][1]==sz[i][2]&&sz[i][1]!=' ')
return sz[i][1];
}//检查每列
for(i=0;i<col;i++)
{
if(sz[0][i]==sz[1][i]&&sz[1][i]==sz[2][i]&&sz[1][i]!=' ')
return sz[1][i];
}//检查每行
if(sz[0][0]==sz[1][1]&&sz[1][1]==sz[2][2]&&sz[1][1]!=' ')
return sz[1][1];
if(sz[0][2]==sz[1][1]&&sz[1][1]==sz[2][0]&&sz[1][1]!=' ')
return sz[1][1];//检查两个对角线
num=iffull(sz,ROW,COL);
if(num==0)
return 'p';//填满,判断平局
return 'j';//继续游戏
}
void game()
{
printf("进入游戏\n");
char sz[ROW][COL],linshi;
qkong(sz,ROW,COL);//清空棋盘
dying(sz,ROW,COL);//打印棋盘,视觉实现
while(1)
{
wanjia(sz,ROW,COL);//玩家下棋
dying(sz,ROW,COL);//打印视觉实现
linshi=panduan(sz,ROW,COL);
if(linshi!='j') //判断是否继续
break;
computer(sz,ROW,COL);//电脑下棋
dying(sz,ROW,COL);//打印视觉实现
linshi=panduan(sz,ROW,COL);
if(linshi!='j') //判断是否继续
break;
}
if(linshi=='*')
printf("玩家胜\n");
if(linshi=='#')
printf("电脑胜\n");
if(linshi=='p')
printf("平局\n"); //判断情况
}
void test()
{
int input;
srand((unsigned int)time(NULL));
//time函数返回值是从初始时间到现在的时间数,简称时间戳,其中的参数(空指针NULL)使time在执行时不需要对内存申请空间
//srand函数是随机数发生器的初始化函数,参数一直变化可以使本题中rand函数随机出不同的值
do{
menu();
printf("请选择:");
scanf("%d",&input);
switch(input)//实现玩家选择
{
case 1:game();break;
case 0:printf("游戏结束\n");break;
default :printf("选择错误请重新输入\n");break;
}
}while(input);//因为循环至少需要执行一次,可以用dowhile语句,巧妙运用input实现循环开始与结束。
}
int main()
{
test();//编写一个函数将整个三子棋实现包括起来
return 0;
}