C语言扫雷:递归展开逻辑详解与代码实现

陆景行
陆景行
发布时间:2026-10-15| 6人浏览过
原创

深入解析 C 语言扫雷程序中“棋盘展开”这一核心算法。通过双棋盘设计区分信息隐藏,利用递归逻辑实现安全区域的自动连通展示,并附带完整的头文件、测试主程序及游戏逻辑源码。

项目结构与棋盘策略

在构建扫雷游戏时,首先需要解决两个核心需求:一是隐藏雷的位置,防止玩家作弊;二是展示已翻开的区域及其周围的雷数。为了实现这一点,代码通常采用两个二维数组来模拟:board 用于记录真实的雷分布(底层逻辑),show 用于展示给玩家的界面(显示层)。

为了避免玩家在输入坐标时触碰数组非法边缘导致的越界访问,棋盘的物理尺寸通常会比视觉尺寸大两圈。例如,视觉上是 9x9 的格子,实际开辟的是 11x11 的空间(即 ROWS = ROW + 2),中间 9x9 的区域才是有效游戏区。

第1步:定义宏与头文件

入口: game.h
参数说明: 定义行/列大小以及雷的数量。
动作: 声明游戏相关函数的原型。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS (ROW+2)
#define COLS (COL+2)
#define Easy_count 10 // 预设地雷数量

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); 

初始化与布雷逻辑

游戏开始前,必须将内部棋盘初始化为字符 '0'(表示无雷),外部展示棋盘初始化为 '*'(表示未翻开)。随后在内部棋盘中随机撒下指定数量的雷(用字符 '1' 表示)。

第2步:布置地雷

目的: 确保地雷分布在有效区域内且不重叠。
操作: 使用 rand() 生成 1~9 的随机数作为横纵坐标,若该位置未被占用则标记为 '1'。

void SetMine(char board[ROWS][COLS], int row, int col)
{
    int count = Easy_count;
    while(count)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if(board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }
    }
}

玩家交互与胜负判定

玩家输入坐标后,系统需要判断是否踩雷或排雷成功。踩雷直接结束游戏;排雷成功后调用展开函数。胜利条件是:未被翻开的格子数等于地雷总数。

void Player(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0, y = 0;
    int win = 0;
    while(win < row*col - Easy_count)
    {
        printf(">>>请输入要排查的坐标:>>>");
        scanf("%d %d", &x, &y);
        if(x >=1 && x <=row && y >=1 && y <=col)
        {
            if(show[x][y] == '*')
            {
                if(mine[x][y] == '1')
                {
                    printf("很遗憾,你被炸死了\n");
                    DisplayBoard(mine, row, col);
                    break;
                }
                else
                {
                    // 如果没踩雷,进入展开逻辑
                    OpenBoard(mine, show, row, col, x, y);
                    DisplayBoard(show, row, col);
                    win = GetWin(show, row, col);
                }
            }
            else
            {
                printf("该坐标已经被排查过了\n");
            }
        }
        else
        {
            printf("输入非法,请重新输入\n");
        }
    }
}

核心算法:递归自动展开

扫雷最精妙的部分在于“自动展开”。当玩家点击一个位置,如果它周围没有雷,那么它周围的所有相邻空格也应该同时翻开。这种连锁反应最适合用**递归**来实现。

第3步:统计周围雷数

入口: 获取坐标 (x, y)。
逻辑: 遍历该点周围 8 个邻居,统计其中 '1' 的个数。
技巧: 由于数组存储的是字符 '0' 和 '1',可以通过求和再减去 '0' 的 ASCII 值来计算整数数量。

int GetSum(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');
}

第4步:递归展开逻辑

目的: 展开当前格子及周围连通的无雷区域。
操作: 调用 OpenBoard。
图片辅助说明:

展开规则详解:

  • 命中地雷: 不处理(此分支由玩家交互层拦截)。
  • 周围有雷: 将该位置在 show 板中更新为具体的数字(周围雷的数量),递归终止,不再向四周扩散。
  • 周围无雷(数字为0): 将其显示为空格 ' '。然后对该点周围的 8 个邻居分别调用 OpenBoard 进行递归。
void OpenBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y)
{
    int sum = GetSum(mine, x, y);
    if(sum == 0) 
    {   // 周围无雷
        show[x][y] = ' ';
        // 遍历周围8个点进行递归
        for(int i=x-1; i<=x+1; i++)
        {
            for(int j=y-1; j<=y+1; j++)
            {
                // 边界检查与未翻开检查
                if(i >=1 && i<=row && j >=1 && j<=col && show[i][j]=='*')
                {
                    OpenBoard(mine, show, row, col, i, j);
                }
            }
        }
    }
    else
    {   // 周围有雷
        show[x][y] = sum+'0'; // 转换为字符显示
    }
}

注意: 上述代码简化了针对已翻开位置的重复调用判断(即防止无限递归或重复计算)。在实际工程中,通常在进入递归前增加对 show[i][j] 是否为 '*' 的判断,以确保每只翻开一次。

总结

C语言扫雷的实现关键在于双内存管理与递归展开逻辑。通过巧妙利用 ASCII 码差值计算雷数,能够高效统计周围风险;而递归机制则完美解决了“一触连发”的连锁反应问题。掌握该案例,有助于深刻理解递归栈的工作方式及数组越界的防御性编程技巧。

以上就是C语言通过递归实现扫雷展开的详细内容,更多关于C语言扫雷递归算法的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。