扫雷游戏分析设计
功能说明
使用控制台实现经典扫雷
游戏是否继续通过菜单实现
扫雷的棋盘格是9*9的格子
电脑随机给出10个雷
可以排除雷
1)如果位置是雷,则游戏结束,并显示雷所在的位置
2)如果位置不是雷,就显示周围有几个雷
3)把电脑给出的雷之外的所有位置都找出来后,排雷成功,游戏结束
游戏的界面
游戏的代码设计与分析
数据结构分析
在扫雷的过程中,布置的雷和排查出的雷都需要储存,结合扫雷的棋盘是99,我们可以想到用两个二维数组来存储数据,先将设置雷的数组全部初始化为存放字符’0‘,而对于显示于屏幕上的数组全部初始化为存放字符’‘。对于电脑给出的随机数所对应的数组元素,我们将其值设置为’1‘,将此位置看作雷所在的位置。
排查数组时,我们若果想要排查(1,1),则直接在键盘上输入1空格1,程序则会排查此位置是否是所对应雷数组的雷的位置,若果是,则游戏直接退出,不是则显示此位置周围有多少个雷,并打印于屏幕上。
当输入的坐标不是棋盘上所标注出来的位置坐标,则提示输入非法,并重新输入。
当排查的位置是雷所在的位置,游戏退出,重新弹出菜单,玩家选择游戏是否继续。
当把所有雷除外的位置都排查了一遍,则显示游戏成功,也是显示菜单重新选择游戏继续与否。
各项功能实现的代码块
打印菜单
void menu()
{
printf("******************************\n");
printf("********* 1-->play *********\n");
printf("********* 0-->exit *********\n");
printf("******************************\n");
}
此代码块实现定义菜单函数,给玩家选择提示,1为游戏,2为退出。
定义并初始化两个棋盘,一个用于设置雷的位置,一个用于打印于屏幕上排查雷
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine,ROWS,COLS,'0');
InitBoard(show,ROWS,COLS,'*');
本次扫雷游戏设置棋盘格是9*9,如果日后想加大难度或者更改棋盘格的大小,可以直接改变ROW、COL的值,因此我们这里使用定义标识符define,用它来定义变量行ROW和列COL,并且由此来确定二维数组大小。
void InitBoard(char board[ROWS][COLS],int rows,int cols,char set)
{
int i,j;
for(i=o;i<rows;i++)
for(j=0;j<cols;j++)
board[i][j] = set;
}
对于两个数组的初始化,这里通过调用函数InitBoard实现,需要给函数传递的参数有:将要被初始化的数组,数组的行,数组的列,以及给数组初始化的内容是什么。之所以传递初始化数组的内容是因为我们上述定义的两个数组,mine数组要初始化为全是字符’0‘的数组,而show数组要初始化为全是字符’*‘的数组,所以将要初始化的内容传递过去。
显示排查棋盘
void Display(char board ,int row ,int col)
{
int i,j;
for(i=0;i<=row;i++)
printf("%d",i);
printf("\n");
for(i=1;i<=row;i++)
{
printf("%d ",i);
for(j=1;j<=col;j++)
printf("%c ",board[i][j];
print("\n");
}
此打印函数,我们不仅显示出数组元素内容,而且显示出行和列,方便玩家直接输入想要查看发的位置坐标。
棋盘上设置雷的函数
#define EASY_COUNT 10
#include<stdio.h>
#include<time.h>
#incluide<stdlib.h>
srand((unsigned int)time(NULL));
void(char mine[ROWS][COLS],int row,int col)
{
int x,y;
int count=EASY_COUNT;
while(count)
{
x=rand%row+1;
y=rand%col+1;
if(mine[x][y]=='0'
{ mine[x][y]='1';
count--;
}
}
此函数调用了rand函数生成一个伪随机数,它不需要参数,获取一个0到最大随机数的任意一个数。我们此棋盘有行列限制,所以用获得的随机数对行或者列求模可以得到0到row-1或者col-1之间的一个随机数,对此随机数加一就是对应的随机行或列了。然后只要将此随机得到的行列确定的数组元素的值改变为’1‘,这便是雷的位置了。
排查雷函数
int MineCount(char mine[ROWS][COLS],int x,int y)
{
return mine [x-1][y-1]+mine[x-1][y]+mine[x-1][y+1]+mine[x][y-1]
+mine[x][y+1]+mine[x+1][y-1]+mine[x+1][y]+mine[x+1][y+1]-8*'0';
}
FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
inta , b;
int c=row*col-EAST_COPUNT;
while(c)
{
printf("请输入要排查的位置坐标:");
scanf("%d %d",&a,&b);
if(a>0&&a<=row&&b>0&&b<=col)
{
if(mine[a][b]=='1')
{
printf("踩雷了,游戏失败!”);
break;
}
else
{
int cout = MineCount(mine[ROWS][COLS],int a,int b)
show[a][b]=count+'0';
Display(show,ROW,COL);
}
}
else
{
printf("输入有误,请重新输入!\n");
}
if(c==0)
printf("恭喜你,通关成功!");
}
此段函数实现代码的排查,对于玩家输入的坐标,先判断坐标是否是棋盘上所标识出来的,是的话则进行排查,不是的话重新输入。对于是棋盘上的坐标,则将此坐标对应到mine棋盘上,看看坐标对应的棋盘元素是不是’1‘,若是’1’,说明玩家踩雷了,游戏结束,若不是’1‘,则显示周围雷的个数。mine数组中存放的都是字符,且不是’0’就是’1’,我们知道’1’-‘0’=1 ,即1+‘0’=1且’0’-‘0’=0。所以我们这里采取的是**用周围八个字符减去八个’0’,有多少个’1’,得到的count就是多少,再用得到的count加上’0’,就能获得周围雷的个数的字符形式了,将它打印到相应位置就可以了。**注意,我们这里定义了一个变量c,并用它来控制循环的进行,我们给c赋的初值是棋盘的行和列的乘积减去雷的个数,也就是最大的能排查的次数。退出循环有两种机会,一是踩到雷了,游戏结束退出,二是所有的排查机会都用完了,也就是找到了所有的非雷的位置,说明玩家成功通关,因此我们这里控制变量c每排查一次减小一,直到排查机会用完游戏结束或者玩家踩雷游戏终止。
以上就是实现经典扫雷的基本功能的C语言代码块,如果你有兴趣可以将它们拼接起来上手试试吧!
当然,如果你发现了什么问题,欢迎指正批评,大家可以一起讨论!
拜拜咯。。。