写一个进入游戏的选项界面
玩过游戏的大家都知道,一般在20年代前的游戏刚进入时都会有一个选项界面。比如开始游戏,游戏设置,关闭游戏等。那咱也照仿着它们也试着写一个选项界面。
当然,最开始我们要先创建好文件和文件夹,共三个文件,一个游戏主体.c文件,一个放函数的.c文件,和一个.h头文件,其中函数,游戏主体.c文件要包含函数头文件,如图:
为了不让主题文件显得太复杂,我们将选项界面封装在一个函数中。把此函数放在“函数.cpp”中。然后在头文件中声明。
title函数如下:
void title()
{
printf("|----------------------------------|\n");
printf("|************1.开始游戏************|\n");
printf("|----------------------------------|\n");
printf("|************2.游戏设置************|\n");
printf("|----------------------------------|\n");
printf("|************0.关闭游戏************|\n");
printf("|----------------------------------|\n");
}
此时我们要想,选项我们已经有了,我们如何选择呢?
游戏选项的选择
玩家看到界面之后肯定会选择1,2,0之中的一个数字,所以我们要将这几个选项的功能分开。此时我们就用到switch函数。此功能写在游戏主体.c文件中。
int main()
{
int x=1,n=10,m=4;//x为玩家输入初始化为1,防止随机数生成为0,而n为游戏扫雷格子的大小,m为游戏中雷的数量,在游戏设置时可以更改。
do
{
title();//x为玩家输入,而n为游戏扫雷格子的大小,在游戏设置时可以更改。
scanf("%d", &x);//玩家输入一个选项
switch (x)
{
case 1:
youxi();
break;
case 2:
shezhi(&n,&m);
break;
case 0:
printf("游戏已退出\n");
break;
default:
printf("不能如此输入,请重新输入\n");
break;
}
} while (x);
}
这就是这个游戏的主体逻辑,此时的youxi函数和shezhi函数都只是一个空壳。我们接下来要一一实现以下的功能。
游戏设置的shezhi函数的实现
void shezhi(int* n,int* m)
{
int x=1;
do {
printf("|----------------------------------|\n");
printf("|***********1.修改方格数***********|\n");
printf("|----------------------------------|\n");
printf("|***********2.修改炸弹数***********|\n");
printf("|----------------------------------|\n");
printf("|***********0. 返回菜单 ***********|\n");
printf("|----------------------------------|\n");
scanf("%d", &x);
switch (x)
{
case 1:
printf("请输入您想将方格数修改成为的数\n");
int nn;
scanf("%d", &nn);
if ((*m) < nn * nn)
{
*n = nn;
printf("方格数修改成功\n");
}
else
{
printf("方格修改失败,总空格数不能小于或等于于炸弹数\n");
continue;
}
break;
case 2:
printf("请输入您想将炸弹数修改成为的数\n");
int mm;
scanf("%d", &mm);
if (mm < (*n) * (*n))
{
*m = mm;
printf("炸弹数修改成功\n");
}
else
{
printf("炸弹修改失败,炸弹数不能大于或等于总空格数\n");
continue;
}
break;
case 0:
break;
default:
printf("不能如此输入,请重新输入\n");
break;
}
} while (x);
}
完成shezhi函数之后,我们要开始制作youxi函数。
游戏内容youxi函数的实现
游戏函数就有些麻烦了,如何实现表面不显示雷,但后台有雷,并且实现标记位置功能呢?此时我们就想到要建立两个二维数组,然后一个二维数组显示表面,当我们走出一步时,查找另一个二维数组所选位置是否为雷。并且埋雷时我们要求每局的雷埋的都不相同,所以我们用rand函数来生成雷。
void youxi(int n,int m)
{
int p = m;
char biao[21][21] = {0};
char nei[21][21] = {0};
memset(biao, '*', sizeof(biao));//将内外的数组分别用memset函数进行初始化
memset(nei, '0', sizeof(nei));
while (1)
{
mailei(nei, n, m);
xianshi(nei, n, m);
xianshi(biao, n, m);
int flag = saolei(biao, nei, n, m);
if (flag == -1)//判断是否死亡
{
printf("游戏失败\n");
break;
}
biaoji(biao,nei,n,m,&p);
if (p == 0)
{
printf("游戏胜利\n");
break;
}
}
}
当然,youxi里各个函数都需要实现,由于篇幅原因,我将不一一赘述。我将函数代码放在下面,仅供参考。我的扫雷功能实现的还不是很完善,希望各位大佬多多包含。
各个函数的实现
#define _CRT_SECURE_NO_WARNINGS
#include"函数.h"
void title()
{
printf("|----------------------------------|\n");
printf("|************1.开始游戏************|\n");
printf("|----------------------------------|\n");
printf("|************2.游戏设置************|\n");
printf("|----------------------------------|\n");
printf("|************0.关闭游戏************|\n");
printf("|----------------------------------|\n");
}
void mailei(char arr[21][21], int n, int m)
{
for (int i = 0; i < m; i++)//因为我们后面要判断一个位置边上8个位置有无炸弹,所以为了方便我们直接将
{ //数组埋雷从1开始,这样就可以看作边缘位置上周围没有炸弹,省去很多判断。
arr[1 + (rand() % n)][1 + (rand() % n)] = '1';
}
}
void xianshi(char arr[21][21], int n, int m)
{
for (int i = 1; i <= n; i++)
{
if (i == 1)
printf("----------");
else
printf("----");
}
printf("\n");
for (int i = 0; i <= n; i++)打印列数序号标
{
if (i == 0)
printf("| %2d |", i);
else
printf(" %d |",i);
}
printf("\n");
for (int j = 1; j <= n; j++)
{
printf("----");
}
printf("------");
printf("\n");
for (int i = 1; i <= n; i++)
{
printf("| %2d ", i);//打印行数序号标
for (int j = 1; j <= n; j++)
{
if (j == 1)
printf("|");
printf(" %c |",arr[i][j]);
}
printf("\n");
for (int j = 1; j <= n; j++)
{
printf("----");
}
printf("------");
printf("\n");
}
}
int panduan0(char arr1[21][21], char arr2[21][21], int x, int y,int n)
{
if (x <= 0 || x >= n || y <= 0 || y >= n)
{
arr2[x][y] == '2';
return -1;
}
int count = 0;//记录周围9个格子内共有多少个炸弹
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
if (arr2[x + i][y + j] == '1')
count++;
}
}
return count;
}
int saolei(char arr1[21][21],char arr2[21][21], int n, int m)
{
printf("请输入您要扫的位置,格式为行空格列\n");
int x,y;
scanf("%d%d", &x,&y);
if (x > n || y > n||x<1||y<1)
printf("行数或列数超出限制,请重新输入\n");
else if(arr2[x][y]=='1')
{
return -1;
}
else if (arr2[x][y] == '2')
{
printf("此处以被标记,您已无法标记\n");
}
else
{
int count=panduan0(arr1, arr2, x, y, n);
arr1[x][y] = '0' + count;
arr2[x][y] = '2';
}
}
void biaoji(char arr1[][21], char arr2[][21], int n, int m,int*p)
{
int x = 1;
while (x)
{
printf("你需要标记吗?不需要请按0,需要请按其他任何数字\n");
scanf("%d", &x);
if (x != 0)
{
printf("请输入您要标记的位置\n");
int a,b;
scanf("%d%d", &a,&b);
if (a > n || b > n || a < 1 || b < 1)
printf("行数或列数超出限制,请重新输入\n");
else
{
arr1[a][b] = '#';
if (arr2[a][b] == '1')
{
*p--;
}
}
}
}
printf("请输入您要标记的数\n");
}
void youxi(int n,int m)
{
int p = m;
char biao[21][21] = {0};
char nei[21][21] = {0};
memset(biao, '*', sizeof(biao));//将内外的数组分别用memset函数进行初始化
memset(nei, '0', sizeof(nei));
while (1)
{
mailei(nei, n, m);
xianshi(nei, n, m);
xianshi(biao, n, m);
int flag = saolei(biao, nei, n, m);
if (flag == -1)//判断是否死亡
{
printf("游戏失败\n");
break;
}
biaoji(biao,nei,n,m,&p);
if (p == 0)
{
printf("游戏胜利\n");
break;
}
}
}
void shezhi(int* n,int* m)
{
int x=1;
do {
printf("|----------------------------------|\n");
printf("|***********1.修改方格数***********|\n");
printf("|----------------------------------|\n");
printf("|***********2.修改炸弹数***********|\n");
printf("|----------------------------------|\n");
printf("|***********0. 返回菜单 ***********|\n");
printf("|----------------------------------|\n");
scanf("%d", &x);
switch (x)
{
case 1:
printf("请输入您想将方格数修改成为的数\n");
int nn;
scanf("%d", &nn);
if ((*m) < nn * nn)
{
*n = nn;
printf("方格数修改成功\n");
}
else
{
printf("方格修改失败,总空格数不能小于或等于于炸弹数\n");
continue;
}
break;
case 2:
printf("请输入您想将炸弹数修改成为的数\n");
int mm;
scanf("%d", &mm);
if (mm < (*n) * (*n))
{
*m = mm;
printf("炸弹数修改成功\n");
}
else
{
printf("炸弹修改失败,炸弹数不能大于或等于总空格数\n");
continue;
}
break;
case 0:
break;
default:
printf("不能如此输入,请重新输入\n");
break;
}
} while (x);
}