I have a dream today!
---Martin Luther King
无论是90后还是00后,相信大家都在xp系统上玩过扫雷游戏,我们初中电脑老师神采飞扬的炫耀过自己初级9x9棋盘扫雷成绩,只耗时2秒,问有没有来挑战的,现在想想给你80个雷,你要不猜一下试试吧~
思维导图
结构分析+图片案例
1. game.h内容分析
我们设计一个9x9的扫雷棋盘,需要考虑一个问题,当边界区需要排查周围8个区域是否会越界?答案是显然的,因此我们需要在9x9的周围加一个护城河防止数组在判断周围雷区的时候越界,即初始化一个11x11的棋盘。见下图:
2. test.c内容分析
首先根据用户的选择进行do…while判断,用户根据菜单进行判断,其他符号都满足while的循环条件,重新进行选择。
接着对棋盘进行初始化:
如果此区域是雷 ---- 用字符‘0’表示
如果此区域非雷 ---- 用字符‘1’表示
但有个问题是我们如果在排雷的过程中发现,此区域周围的八个区域中只有一个雷,那程序如何区分这个‘1’是雷?还是排查后统计出来总的雷的个数呢?
为了解决这个问题我们用两个二维数组进行判断:
- 第一个二维数组,布置雷,把生成出来的雷存放到这个数组里,用字符‘1’表示雷,字符’0’表示非雷
- 第二个二维数组,用来排查雷,记录当前区域周围雷的个数
问题解决后就可以对数组进行初始化了:
mine棋盘用于存放雷的信息,全部为‘0’
show棋盘用于显示当前所选区域周围雷的个数,全部初始化为’1’
初始化后开始布置雷,这里我们9x9的棋盘,默认雷的个数为10个,随机产生x,y雷的坐标(范围是1~9),放入show棋盘。
我们可以打印出mine,和show棋盘看一下,当然玩家在玩的时候mine棋盘是不能显示的。
Mine棋盘:
Show棋盘:
最后玩家进行雷的排查,具体函数实现见game.c
3. game.c内容分析
- InitBoard()函数,这里棋盘ROWS和COLS都为11,rows和cols都为11,set为自定义初始化字符
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
-
DisplayBoard()函数,注意的棋盘并不是打印11x11的棋盘,玩家只需要看到9x9的,因此我们从第二行第二列开始打印,具体先打印列号,其次打印行号和初始化符号。
-
SetMine()函数,我们引用头文件
#include <time.h>
产生随机数srand((unsigned int)time(NULL));
, 雷的x,y坐标为int x=rand()%row+1 and int y=rand()%col+1
布置雷前判断一下此区域是否为字符’0’,是则设为’1’ -
getMineCount()函数,判断此坐标附近把个坐标的位置是否为雷,值得注意的是二维数组内都是用char类型来存储,那么如果是雷怎么转换成数字类型来进行相加呢? 我们知道 0+‘0’ = ‘0’,因为字符’0’被替换成了48,那么四周的八个区域字符进行相加得到的值减去8*'0’就可以得到有几个雷了。
-
no_mine_spread()函数,如果此区域是’0’,我们就分别去此区域周围的八个区域也进行一次相应的判断,看是否为雷区,如果不是雷,递归下去,直到周围是雷为止,并把当前周围雷的数量show[x][y] = mine进行记录。
-
game_win()函数,此函数为判断玩家是否胜利,遍历二维数组,判断标记符号或者剩余未踩的区域的数量,如果count和雷的数量相等,恭喜玩家,游戏结束,否则游戏结束
-
mark_Mine()函数,玩家如果想标记此区域可能是雷,将此区域标记为符号’!’
-
FIndMine()函数
- 输入即将排查雷的坐标
- 检查坐标是不是雷,如果是雷,gameover,否则调用getMineCount()函数,来判断周围雷的个数,存储到show数组
- 询问是否要进行疑似雷的标记
代码实现
game.h
//
// game.h
// MineSweeper_Game
//
// Created by henry on 2021/5/5.
//
#ifndef game_h
#define game_h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MINE_NUM 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
void InitBoard(char board[ROWS][COLS], int row, int col, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char mine[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
#endif /* game_h */
test.c
//
// main.c
// MineSweeper_Game
//
// Created by henry on 2021/5/5.
//
#include "game.h"
void callMenu(){
printf("*****************************************\n");
printf("************ 1. Play ************\n");
printf("************ 0. Exit ************\n");
printf("*****************************************\n");
}
void enterGame(){
printf("MineSweeper\n");
char mine[ROWS][COLS] = {
0}; //存放布置好的雷的信息
char show[ROWS][COLS] = {
0}; //存放排查出的雷的信息
//初始化mine棋盘,全部放字符型的'0'
//初始化show棋盘,全部放字符型的'*'
InitBoard(mine, ROWS, COLS, '0');
InitBoard