一、主体函数的设计:
设计游戏菜单,通过选择进入或者退出游戏
int main()
{
int select = 0;
int quit = 0;
while (!quit)
{
Menu();
printf("请输入你的选择\n");
scanf("%d", &select);
switch (select)
{
case 1:
printf("欢迎进入游戏\n");
Game();
printf("是否再来一把?\n");
break;
case 2:
printf("欢迎下次再来\n");
quit = 1;
break;
default:
printf("输入有误,请从新输入\n");
break;
}
二、游戏菜单的编写
void Menu()
{
printf("######################\n");
printf("1.enter#########2.quit\n");
printf("######################\n");
}
三、对扫雷游戏函数Game()的整体设计思路:
3.1棋盘的显示:扫雷显示界面和统计界面需要分开统计,因此选择两个二维数组作为棋盘;棋盘大小设计为10x10,但是如图黑色格子所示,在一些边角落的棋子会导致后期统计雷的个数比较复杂,因此选择12x12的棋盘,但是只用其中10x10的格子,其余的雷区统计时将其设计为‘0’;
头文件中定义的一些变量解释;
#define ROW 12
#define LINE 12
#define NUM 20
`其中ROW代表行数,LINE代表列数,NUM代表雷的个数``
定义一个显示数组,并将其全部内容初始化为‘#’;
char showboard[ROW][LINE];
memset(showboard, '#', sizeof(showboard));//将所有棋盘的内容初始化为#;
设计棋盘显示函数ShowBoard();
static void ShowBoard(char showboard[][LINE],int row,int line)
{
printf(" ");
for (int i = 1; i < row - 1; i++)
{
printf("%2d |", i);
}
printf("\n--------------------------------------------\n");
for (int i = 1; i < line-1; i++)
{
printf(" %2d|", i);
for (int j = 1; j < line-1; j++)
{
printf(" %c |", showboard[i][j]);
}
printf("\n-------------------------------------------\n");
}
}
显示效果如图:
3.2设计棋盘中的‘’雷‘’:
定义一个统计数组来放在后台统计以及生成雷,数组的大小为12x12,设置雷区时使其分布在10x10内,外围的则初始化为‘0’,因此统计边角落的落子处周围的雷数就很方便了;
```c
char showmine[ROW][LINE];
memset(showmine, '0' , sizeof(showmine));//将雷区所有内容初始化为0;
srand((unsigned)time(NULL));//随机数种子,后期雷区的分布坐标;
Setmine(showmine, ROW, LINE);//设置雷区
``static void Setmine(char showmine[][LINE], int row, int line)
{
int count = NUM;
while (count)
{
int x = rand() % (row-2)+1;
int y = rand() % (line-2)+1;
if (showmine[x][y] == '0')
{
showmine[x][y] = '1'; // 使‘1’为雷;
count--;
}
}
}
3.3当输入扫雷坐标时,坐标处为雷则游戏结束,如果不为雷,则需要一个统计函数,统计周围的雷数显示出来
static char Getmine(char showmine[][LINE], int row, int line, int x, int y)
{
return showmine[x - 1][y - 1] + showmine[x - 1][y] + showmine[x - 1][y + 1]+\
showmine[x][y - 1] + showmine[x][y + 1] + showmine[x + 1][y - 1]+\
showmine[x + 1][y] + showmine[x + 1][y + 1] - 7* '0';
坐标周围有8个‘雷’数组,其中内容不是‘0’就是‘1’,那么将其相加起来再减去8个‘0’则为‘1’的个数,但是此时的1为数字1而不是符号‘1’,因此加上‘0’,那么对应的输出的符号就是‘1’–‘8’;
3.4当显示棋盘,和雷区分布统计都编写好后就可以进行游戏函数的整合编写了:
void Game()
{
char showboard[ROW][LINE];
memset(showboard, '#', sizeof(showboard));//将所有棋盘的内容初始化为#;
char showmine[ROW][LINE];
memset(showmine, '0' , sizeof(showmine));//将雷区所有内容初始化为0;
srand((unsigned)time(NULL));//随机数种子,后期雷区的分布坐标;
Setmine(showmine, ROW, LINE);//设置雷区
int count = (ROW-2)*(LINE-2)-NUM;//棋盘所有的格子-雷的个数就为空格数
do{
system("cls"); //显示一次棋盘,输入坐标后将上一次的清屏;
ShowBoard(showboard, ROW, LINE);//展示棋盘
int x = 0;
int y = 0;
printf("请输入你的坐标\n");
scanf("%d %d", &x, &y);
if (x < 0 || x >(ROW-2) || y < 0 || y >(LINE-2)) //越界了
{
printf("输入有误,重新输入\n");
continue;
}
else if (showboard[x][y] != '#') //被排除了
{
printf("输入有误,重新输入\n");
continue;
}
else if (showmine[x][y] != '1') //安全,没有踩到雷,将周围雷数显示出来
{
showboard[x][y] = Getmine(showmine, ROW, LINE, x, y); //将周围有几个雷显示在棋盘之上
}
else if (showmine[x][y] == '1') //踩到雷了
{
showboard[x][y] ='*';//棋盘之上显示‘*’代表雷
ShowBoard(showboard, ROW, LINE); //跳出循环之前,显示最终的棋盘情况
printf("雷区分布情况如下\n");
ShowBoard(showmine, ROW, LINE);//显示雷区的分布;
break;
}
count--;
} while (count);
if (count != 0)
{
printf("不好意思,你被炸死了\n");
}
else
printf("恭喜你,成功通关");