https://mp.csdn.net/mp_blog/creation/editor/135676438
1.扫雷游戏分析和设计。
●使用控制台实现经典扫雷游戏
●游戏可以通过菜单进行开始游戏还是退出游戏
●扫雷的棋盘是9*9的格子中进行
●默认随机布置十个雷
●可以排查雷
○如果所排查位置不是雷,就显示周围有几个雷
○如果位置是雷,就炸死游戏结束
○把十个雷的位置都找出来,则排雷成功,游戏结束
游戏界面:
游戏初始界面
游戏开始排雷界面
游戏排雷失败界面
2.游戏分析和设计
扫雷过程布置的雷和排查出的雷需要储存起来。所以我们需要数据结构来储存这些信息。因为是在9*9的格子中进行扫雷,所以我们联想到可以用二维数组来储存这些信息 。
那我们如何在这空格中确定是雷还是不是雷呢?
于是我们可以把不是雷的地方用0代替,把雷的地方用1代替。这样就可以更好的排查雷了。
如果我们要排查(2,5)这个坐标是不是雷(为0不是雷) ,于是我们就要把这个坐标周围八个位置(如图黄色的一圈)的雷的个数统计出来。
如果排查(8,6)这个位置的雷,此时我们会发现一个问题,如果(8,6)这个位置不是雷,统计周围雷的数量时(如上图所示)会发现下面一部分已经越界了,为了解决这个问题,我们可以将二维数组扩大一圈(创建成11*11),但是雷还是布置在中间9*9的格子里面,周围的一圈不用布置雷就行啦。
我们继续分析,当我们排查(3,6)的位置,这个坐标不是雷,统计周围雷的个数为1,并打印出来,作为排雷重要参考信息,但是打印在哪呢?如果还是打印在上面的数组中,(3,6)的位置就是1,那么这个1代表这个位置是雷还是代表周围雷的个数呢?这样就会产生混淆。
这里我们肯定有办法解决,比如:雷和非雷的信息不要使用数字,使用某些字符就行,这样就避免冲突了,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。这里我们采用另外一种方案,我们专门给一个棋盘(对应一个数组mine)存放布置好的雷的信息,再给另外一个棋盘(对应另外一个数组show)存放排查出的雷的信息。这样就互不干扰了,把雷布置到mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。
同时为了保持神秘,show数组开始时初始化为字符'*,为了保持两个数组的类型一致,可以使用同一套函数处理,mine数组最开始也初始化为字符‘0',布置雷改成'1'。如下如:
mine数组
show数组
mine数组用来存放布置好的雷的信息,而show数组则是用来存放排查出雷的个数的信息。
同时show数组在每排完一颗雷后,都需要打印一次,让玩家继续排雷。但是mine由于存放着雷的位置信息,就不能打印出来(打印出来就算作弊啦)
下面是我的代码实现:
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS ROW+2
#define number 10
//排查雷
void findmind(char arr[ROWS][COLS],char show[ROWS][COLS],int x,int y);
//寻找周围的雷
int getmind(char arr[ROWS][COLS],int x,int y);
//开始埋雷
void setmind(char arr[ROWS][COLS],int row,int col);
//初始化棋盘函数
void csh(char arr[ROWS][COLS],int row,int col,char s);
//打印棋盘
void display(char arr[ROWS][COLS],int row,int col);
void findmind(char arr[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
int x,y;
int win=0;
while(win<ROW*COL-number)
{
printf("请输入你要排查的坐标,并用空格隔开:");
scanf("%d%d",&x,&y);
if(x<=ROW&&x>=1&&y<=COL&&y>=1)
{
if(arr[x][y]=='0')
{//不是雷统计雷的个数
int z=getmind(arr,x,y);
show[x][y]=z+'0';
display(show,ROW,COL);
system("cls");
display(show,ROW,COL);
win++;
}
else
{
printf("你已经被雷炸死了!!!\n");
break;
}
}
else
{
printf("输入错误,请重新输入:");
}
}
if(win==ROW*COL-number)
{
printf("恭喜你,扫雷游戏通关!!!");
display(arr,ROW,COL);
}
}
int getmind(char arr[ROWS][COLS],int x,int y)
{
int z=arr[x-1][y-1]
+arr[x-1][y]
+arr[x-1][y+1]
+arr[x][y-1]
+arr[x][y+1]
+arr[x+1][y-1]
+arr[x+1][y]
+arr[x+1][y+1]-8*'0';
return z;
}
void setmind(char arr[ROWS][COLS],int row,int col)
{
int count=number;
while(count)
{
int x=rand()%row+1;
int y=rand()%col+1;
if(arr[x][y]=='0')
{
arr[x][y]='1';
count--;
}
}
}
void csh(char arr[ROWS][COLS],int row,int col,char s)
{
for(int i=0;i<=row;i++)
{
for(int j=0;j<=col;j++)
{
arr[i][j]=s;
}
}
}
void display(char arr[ROWS][COLS],int row,int col)
{
int i=0,j=0;
printf("-------扫雷游戏-------\n");
for(i=0;i<=row;i++)
{
printf("%d ",i);
}
printf("\n");
for(i=1;i<=row;i++)
{
printf("%d ",i);
for(j=1;j<=9;j++)
{
printf("%c ",arr[i][j]);
}
printf("\n");
}
}
void game()
{
char mine[ROWS][COLS]={0};
char show[ROWS][COLS]={0};
//初始化数组
csh(mine,ROWS,COLS,'0');
csh(show,ROWS,COLS,'*');
//打印棋盘
// display(mine,ROW,COL);
display(show,ROW,COL);
//设置十个雷
setmind(mine,ROW,COL);
//display(mine,ROW,COL);
//排查雷
findmind(mine,show,ROW,COL);
}
void menu()
{
printf("******1.开始游戏******\n");
printf("******0.退出游戏******\n");
}
void test()
{
srand((unsigned int)time(NULL));//随机数的生成器,方便后续随机生成10个雷
int input=0;
do
{
menu();
printf("请做出你的选择:");
scanf("%d",&input);
switch(input)
{
case 1: game ();break;
case 0:printf("退出游戏\n");break;
default:printf("你输入的值有误,请重新输入\n");
}
}
while(input);
}
int main()
{
test();
return 0;
}
如果有什么问题希望大家能够提出来,谢谢大家。