#初学者必看#手把手教你扫雷教程#B站鹏哥史上最细

前言

会写的不一定真的懂了,本篇文章结合了B站鹏哥的写作手法,循序渐进推进知识点,一步步教你写代码,非常适合初学者学习,建议反复观看。

同时作者我也是一个C语言B站初学者,欢迎一起学习交流,批评指正。

家人们,来都来了,动动你们发财的小手,给我点点关注,点点赞呗,你们的支持就是我创作的动力,我会持续发布高质量的文章供大家一起学习。

课前准备


先准备创建自定义的头文件,用于声明函数;两个源文件,一个写具体函数实现,一个写程序过程。我用的是VS2022编译器,你用其他的编译器也可以,但不保证有其他问题,欢迎Q我。

go 现在开始吧!!


让我们先写一个流程图,告诉你的电脑要做什么?

作为游戏的设计者,你要让你的电脑明白将要做什么,也就是游戏是怎么运行的,下面附上流程图。

第一部分:菜单的实现

a46d2fd143514496905ab14ad35d141a.png

 第二部分:游戏的实现

1172eda61596455aa6e85f094f228c3c.png

学会看和绘画流程图是学习和培养编程思维的最好方法。当我们有了流程图就可以开始着手写代码了,实现代码的运行,让我们谈谈具体的细节吧。

菜单实现的具体细节


第一部分:

创建main()函数,打印你的菜单,并使你的菜单有效。

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include<stdio.h>
void meun()
{
    printf("********************************\n");
    printf("**********    扫雷    **********\n");
    printf("******1.游戏开始 0.游戏结束******\n");
    printf("********************************\n");
}

void   game()
{
  //第二部分实现
}
int main()
{
    int arr;
    //打印菜单
    meun();
    do {
        printf("请输入—>\n");
        scanf("%d", &arr);
        switch (arr)
        {
        case 1:
            game();
            break;
        case 0:
            printf("你的游戏已经退出\n");
            break;
        default:
            printf("你的输入有错,请重新输入->\n");
            break;
        }
    } while (arr);

}

有些人可能不采用1或0的菜单键,而是采用像yes/no的字符串键,这样就不能用switch case 的分支了,这时要才用if, else if分支,并且在使用它时不能用“==”来判断,而是用trcmp(arr,"yes")==0来实现。

还记得我们之前的准备吗,这里引用的头文件“game.h”是自己定义的哦,它用于函数的声明。

看看效果:

e382dccad38e49eca3359d8297394493.png


 第二部分:游戏的实现具体细节

创建隐棋盘数组与显棋盘数组,并初始化,先上代码->

接下来所有需要创建的第二部分函数都在void game()函数中。

   void main()
{
    //布置雷的数组
    char mine[ROWS][COLS] = {0};
    //排查雷的数组
    char show[ROWS][COLS] = {0};
    //数组初始化
    InitBoard(mine,ROWS,COLS,'0');
    InitBoard(show,ROWS,COLS,'*');
}
    

头文件中声明

#include<stdio.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//数组初始化声明
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

函数具体实现(/数组初始化)

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

我们想创建一个9*9的棋盘,但是是却创建了一个11*11的数组,这是为什么呢?

22838f4046f8461a99dd5ae8ff28079a.png

 上图解释,如图,首先,我们需要操作的地方是大红正方形区域,打印的也是大红正方形区域,这里会布雷,排雷,并显示雷,然而大红正方形区域外的地域是干嘛的呢?看到左上角的小红正方形区域了吗,如果要排查1号位周围的雷的个数,就要将号位周围的雷的个数加起来,并显示在1号位上,像1号位一样靠近大红正方形区域红线的点位如果在没有外围格子的情况下计算雷的数量是很复杂的,有了外围格子,靠近大红正方形区域的特殊区域在排查雷的时候就可以像大红正方形区域内所有点位一样的排查手法,就简单些。

打印显性棋盘

创建函数

 //打印显性棋盘
    Dispiayboard(show, ROW, COL);

打印显性棋盘声明

//打印显性棋盘声明
void  Dispiayboard(char mine[ROWS][COLS], int row, int col);

函数具体实现

//打印显性棋盘
void  Dispiayboard(char board[ROWS][COLS], int row, int col)
{
    int i, j;
    for (i = 0; i <= col; i++)
    {
        printf("%d ", i);
    }
    printf("\n");
    printf("---------------------\n");
    for (i = 1; i <= row; i++)
    {
        printf("%d", i);
        printf("|");
        for (j = 1; j <= col; j++)
        {
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
    printf("---------------------\n");
}

打印的是9*9的区域即大红正方形区域,if就很好的解决了,它的条件忽略了大红正方形区域外的地域。打印的是显性棋盘。

看看效果:

572973885f5a4e14bf44f53341311576.png


埋雷

创建函数

 //埋雷
    set_mine(mine, ROW, COL);
    //调试时看看雷的布置结果,后面要删
    Dispiayboard(mine, ROW, COL);

这里调用了一个打印函数,用于查看埋雷的情况

埋雷声明

//埋雷声明
void set_mine(char mine[ROWS][COLS], int row, int col);

函数具体实现

void set_mine(char mine[ROWS][COLS], int row, int col)
{
    int x, y;
    int count = 11;
    srand((unsigned int)time(NULL));
    while (count)
    {
        x = rand() % row + 1;
        y = rand() % col + 1;
        if ('0' == mine[x][y])
        {
            mine[x][y] = '1';

        }
        count--;
    }
}

这里是用1来代替雷,count 是布置雷的个数,rand是生成随机1-1024数字的库函数,这里将它% row +1或% col +1,是将它的随机值控制在1-9之间,同时为了保证它在每次启动程序的时候随机值都不一样,所布置的雷的区域不一样,他会配合srand函数一起使用,如上述使用方法。因为是库函数要引用头文件,这里的头文件是#include<time.h>和#include <cstdlib>

看看效果:

71ccbdff85a040f0b4c7d9df68b209e0.png


排雷

先把调试用到的打印函数屏蔽,不然就是看答案了。

创建函数

 //排雷
    find_mine(mine, show, ROW, COL);

这里是有四个值的传参,是对显影棋盘的操作。

排雷声明

//排雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

函数具体实现

int  Get_mine_count(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 + 1] +
        mine[x + 1][y] - 8 * '0';
}
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x, y;
    while (1)
    {
        printf("请输入坐标->\n");
        scanf("%d%d", &x, &y);
        if (x >= 1 && x <= 9 && y <= 9 && y >= 0)
        {
            if (mine[x][y] == '1')
            {
                printf("你被炸死了\n");
                Dispiayboard(mine, ROW, COL);
                break;
            }
            else
            {
                int count = Get_mine_count(mine, x, y);
                show[x][y] = count + '0';
                Dispiayboard(show, ROW, COL);
            }
        }
        else {
            printf("请输入正确的坐标->\n");
        }
    }

}

Get_mine_count函数的原理是对排雷点位周围雷的计算,因为雷的值设定的是1,累加起来就好了。(这里就体现了11*11数组的好处)

在find_mine函数中,两个if有两个作用,一个是判断你输入的值是否正确,二是判断这个点位是否为1,也就是是否为雷。然后不管输赢都最后打印隐棋盘,公布答案 Dispiayboard的作用。

看看效果:


求家人们给个三连吧,我会持续发布一些适合初学者看的文章,让大家少走弯路,避免我踩过的坑,求求了 

猜你喜欢

转载自blog.csdn.net/2301_77479336/article/details/130009757