[C语言]超详细讲解扫雷游戏(递归+标记),附思维导图

本文通过详细的思维导图和代码分析,介绍使用C语言实现扫雷游戏的过程。涉及棋盘初始化、雷的布局、周边雷数统计,以及游戏逻辑的实现。通过递归函数解决非雷区域周围雷数的计算,帮助读者理解扫雷游戏的编程实现。
摘要由CSDN通过智能技术生成

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. 第一个二维数组,布置雷,把生成出来的雷存放到这个数组里,用字符‘1’表示雷,字符’0’表示非雷
  2. 第二个二维数组,用来排查雷,记录当前区域周围雷的个数

问题解决后就可以对数组进行初始化了:
mine棋盘用于存放雷的信息,全部为‘0’
show棋盘用于显示当前所选区域周围雷的个数,全部初始化为’1’
初始化后开始布置雷,这里我们9x9的棋盘,默认雷的个数为10个,随机产生x,y雷的坐标(范围是1~9),放入show棋盘。
我们可以打印出mine,和show棋盘看一下,当然玩家在玩的时候mine棋盘是不能显示的。

Mine棋盘:
在这里插入图片描述
Show棋盘:
在这里插入图片描述
最后玩家进行雷的排查,具体函数实现见game.c

3. game.c内容分析

  1. InitBoard()函数,这里棋盘ROWS和COLS都为11,rows和cols都为11,set为自定义初始化字符
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
  1. DisplayBoard()函数,注意的棋盘并不是打印11x11的棋盘,玩家只需要看到9x9的,因此我们从第二行第二列开始打印,具体先打印列号,其次打印行号和初始化符号。

  2. SetMine()函数,我们引用头文件#include <time.h>
    产生随机数srand((unsigned int)time(NULL));, 雷的x,y坐标为int x=rand()%row+1 and int y=rand()%col+1
    布置雷前判断一下此区域是否为字符’0’,是则设为’1’

  3. getMineCount()函数,判断此坐标附近把个坐标的位置是否为雷,值得注意的是二维数组内都是用char类型来存储,那么如果是雷怎么转换成数字类型来进行相加呢? 我们知道 0+‘0’ = ‘0’,因为字符’0’被替换成了48,那么四周的八个区域字符进行相加得到的值减去8*'0’就可以得到有几个雷了。

  4. no_mine_spread()函数,如果此区域是’0’,我们就分别去此区域周围的八个区域也进行一次相应的判断,看是否为雷区,如果不是雷,递归下去,直到周围是雷为止,并把当前周围雷的数量show[x][y] = mine进行记录。

  5. game_win()函数,此函数为判断玩家是否胜利,遍历二维数组,判断标记符号或者剩余未踩的区域的数量,如果count和雷的数量相等,恭喜玩家,游戏结束,否则游戏结束

  6. mark_Mine()函数,玩家如果想标记此区域可能是雷,将此区域标记为符号’!’

  7. FIndMine()函数

    1. 输入即将排查雷的坐标
    2. 检查坐标是不是雷,如果是雷,gameover,否则调用getMineCount()函数,来判断周围雷的个数,存储到show数组
    3. 询问是否要进行疑似雷的标记

代码实现

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
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值