从零开始实现扫雷游戏:C语言代码详解

基于C语言扫雷游戏的设计与实现 摘要 随着信息技术的快速发展,近年来,人们的生活已经离不开计算机。扫雷游戏是微软公司在1992年在windows系统上发布的一款益智类小游戏。直到今天这款小游戏依然存在。 关键词 随机数; ... 阅读详情

       

一、游戏设计与代码结构

1. 游戏核心机制

扫雷游戏的核心逻辑包含以下几个部分:

  • 棋盘初始化:创建两个二维数组,一个存储地雷位置(mine),另一个存储玩家可见区域(show)。

  • 地雷布置:在mine数组中随机生成指定数量的地雷。

  • 递归展开:当玩家点击无雷区域时,自动展开相邻的所有安全格子。

  • 时间管理:限制游戏时间,超时自动失败。

  • 输入处理:支持排雷(p)和标记(m)两种操作。

2. 代码文件分工

  • game.h:定义常量、函数声明。

  • game.c:实现游戏核心逻辑(初始化、打印、排雷、展开等)。

  • test.c:处理菜单交互、游戏启动和难度选择。


二、核心代码逐行解析

1. 棋盘初始化z 

InitBoard函数
void InitBoard(char board[MAX_ROWS][MAX_COLS], int rows, int cols, char set)
{
    for (int i = 0; i < rows; i++) 
    {
        for (int j = 0; j < cols; j++)
        {
            board[i][j] = set;
        }
    }
}

 

  • 参数说明:

    • board:待初始化的二维数组。

    • rows/cols:棋盘的行数和列数。

    • set:填充字符(mine用'0',show用'*')。

  • 注意事项:

    • 数组索引从0开始,但游戏逻辑中行列从1开始(避免边界检查复杂)。

DisplayBoard函数

void DisplayBoard(char board[MAX_ROWS][MAX_COLS], int row, int col) 
{
    printf("\n-----------扫雷游戏-----------\n");
    // 打印列号
    for (int i = 0; i <= col; i++) 
    {
        printf("%2d ", i);
    }
    printf("\n");
    for (int i = 1; i <= row; i++) 
    {
        printf("%2d ", i);
        for (int j = 1; j <= col; j++) 
        {
            printf("%2c ", board[i][j]);
        }
        printf("\n");
    }
}

 

 输出示例:

  0  1  2  3  4  5  6  7  8 
1 *  *  *  *  *  *  *  *  * 
2 *  *  *  *  *  *  *  *  * 
...

2. 地雷布置与计数

SetMine函数
void SetMine(char board[MAX_ROWS][MAX_COLS], int row, int col, int mine_count) 
{
    while (mine_count) 
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0') 
        {
            board[x][y] = '1';
            mine_count--;
        }
    }
}

 

  • 关键点:

    • 使用rand()生成随机坐标,需在main函数中调用srand((unsigned)time(NULL))初始化随机种子。

    • 地雷用字符'1'表示,安全区域为'0'。

GetMineCount函数

static int GetMineCount(char mine[MAX_ROWS][MAX_COLS], int x, int y) {

    int count = 0;
    for (int i = x - 1; i <= x + 1; i++) 
    {
        for (int j = y - 1; j <= y + 1; j++)
        {
            count += mine[i][j] - '0';
        }
    }
    return count;
}
  • 逻辑说明:

    • 遍历周围8个格子,累加地雷数量。

    • 字符'1'减去'0'得到数值1,'0'则得到0。

3. 递归展开与排雷逻辑

Expand函数(递归核心)
static void Expand(char mine[MAX_ROWS][MAX_COLS], char show[MAX_ROWS][MAX_COLS], int x, int y, int row, int col, int* win) 
{
    if (x < 1 || x > row || y < 1 || y > col || show[x][y] != '*')
    {
        return;
    }
    int count = GetMineCount(mine, x, y);
    show[x][y] = (count == 0) ? '0' : count + '0';
    (*win)++;
    if (count == 0)
    {
        for (int dx = -1; dx <= 1; dx++) 
        {
            for (int dy = -1; dy <= 1; dy++) 
            {
                if (dx != 0 || dy != 0)
                {
                    Expand(mine, show, x + dx, y + dy, row, col, win);
                }
            }
        }
    }
}
  • 递归终止条件:

    • 超出棋盘边界。

    • 当前格子已被探索(非'*')。

 FindMine函数(主逻辑)

void FindMine(char mine[MAX_ROWS][MAX_COLS], char show[MAX_ROWS][MAX_COLS], int row, int col, int mine_count, int time_limit)
{
    int win = 0;
    time_t start_time = time(NULL);     //游戏开始时间戳
    int remaining_time = time_limit;    //剩余时间初始化

    //主游戏循环:当未排完所有安全区域时继续
    while (win < row * col - mine_count) 
    {
        //时间计算与超时处理
        remaining_time = time_limit - (int)(time(NULL) - start_time);
        if (remaining_time <= 0)
        {
            printf("\n时间耗尽,游戏失败!\n");
            DisplayBoard(mine, row, col);//显示完整雷区
            return;
        }

        // 界面信息输出
        printf("\n剩余时间: %02d:%02d", remaining_time / 60, remaining_time % 60);//格式化为MM:SS
        printf("\n输入格式:操作(p排雷/m标记) 行 列 (如: p 3 4;m 3 4)\n");

        // 清空输入缓冲区并读取命令
        int c;
        while ((c = getchar()) != '\n' && c != EOF);  //清空输入缓冲区
        char cmd;
        int x, y;
        int read_result = scanf(" %c %d %d", &cmd, &x, &y);//读取输入
        if (read_result != 3) 
        {
            printf("输入格式错误!\n");
            while (getchar() != '\n');
            continue;
        }

        // 坐标合法性检查
        if (x < 1 || x > row || y < 1 || y > col)
        {
            printf("坐标非法!\n");
            continue;
        }

        // 处理标记/排雷逻辑
        if (cmd == 'm' || cmd == 'M') 
        {
            show[x][y] = (show[x][y] == '*') ? 'F' : '*';//切换标记状态:'*'<->'F'
            DisplayBoard(show, row, col);//更新显示
        }
        else if (cmd == 'p' || cmd == 'P')//排雷操作
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了!\n");
                DisplayBoard(mine, row, col);//显示雷区
                break;
            }
            //已标记位置保护
            if (show[x][y] == 'F') 
            {
                printf("请先取消标记!\n");
                continue;
            }
            //重复排雷检查
            if (show[x][y] != '*')
            {
                printf("该位置已排雷!\n");
                continue;
            }
            //安全区域处理
            int count = GetMineCount(mine, x, y);//获取周围雷数
            if (count == 0)                 //周围无雷时自动展开
            {
                //递归展开连续空白区域,并更新排雷计数
                Expand(mine, show, x, y, row, col, &win);
            }
            else //显示周围雷数
            {
                show[x][y] = count + '0';
                win++;
            }
            DisplayBoard(show, row, col);//更新显示
        }
        else    //无效命令处理
        {
            printf("无效命令!\n");
        }
    }

    //胜利条件判定
    if (win == row * col - mine_count)
    {
        printf("恭喜通关!剩余时间: %d秒\n", remaining_time);
    }
}
  • 胜利条件:已探索格子数等于总安全格子数(row * col - mine_count)。

三、主函数与游戏流程(test.c)

  1. 菜单显示:提供简单、中等、困难三种模式。

  2. 初始化游戏:创建两个二维数组,分别存储雷的位置和玩家视图。

  3. 进入排雷循环:结合时间限制和用户输入更新游戏状态。

int main() {
    int input = 0;
    srand((unsigned)time(NULL));
    do 
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1: 
            game(9, 9, EASY_MINES, EASY_TIME); //简单难度
            break;
        case 2: 
            game(16, 16, MEDIUM_MINES, MEDIUM_TIME); //中等难度
            break;
        case 3: 
            game(16, 30, HARD_MINES, HARD_TIME); //困难难度
            break;
        case 0: 
            printf("游戏结束!\n");
            break;
        default: 
            printf("输入错误,请重新选择!\n");
            break;
        }
    } while (input != 0);
    return 0;
}

四、游玩示例

 

五、改进方向与总结

  1. 性能优化:递归展开可能引发栈溢出,可改用队列实现迭代展开。

  2. 界面增强:引入颜色库(如 ncurses)提升视觉效果。

  3. 功能扩展:支持保存/加载游戏、自定义难度等。

       本扫雷游戏通过模块化设计实现核心功能,重点解决了递归展开、时间管理和输入处理等难点。代码结构清晰,适合初学者学习二维数组操作、递归逻辑及时间处理技巧。通过进一步优化,可扩展为功能更丰富的经典游戏复刻。 

扫雷游戏 C语言实现 扫雷游戏 C语言实现实现了如下功能: 鼠标控制 左键点开 右键标记 中键自动翻开(效果同windows扫雷) 首次点击不会中雷下面是几张效果图: 这是初始界面,3种难度级别,难度同经典版windows扫雷 Beginner 不同颜色的数字和标记功能 赢了! 游戏结束,可以点击Restart重新开始 Expert级别难度可以点击这里下载玩: MineSweeper Versi 阅读详情

相关推荐

C语言实现扫雷游戏---原理及其代码

3.打印两个棋盘,我们专⻔给⼀个棋盘(对应⼀个数组mine)存放布置好的雷的信息,并且玩家不知道那些地方有雷,再 给另外⼀个棋盘(对应另外⼀个数组show)存放排查出的雷的信息,当玩家在第一个棋盘输入坐标的时候,第二个棋盘进行排查雷:如果位置不是雷,就显⽰周围有⼏个雷 ◦ 如果位置是雷,就炸死玩家游戏结束 ◦ 把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束。因为我们需要在9*9的棋盘上布置雷的信息和排查雷,我们⾸先想到的就是创建⼀个9*9的数组来存放 信息。//2. show数组最开始是全'*'

2302_82059864的博客 1358

从零开始实现C语言扫雷游戏:代码详解与开发指南

一、引言一、引言扫雷游戏简介及其经典地位扫雷是一款经典的单人益智游戏,起源于20世纪60年代,并在1990年代通过微软Windows操作系统广泛流行。游戏中,玩家面临一个由格子组成的网格,其中隐藏着地雷。目标是通过逻辑推理揭开所有安全格子,而不触发任何地雷。每个格子显示数字,表示周围8个相邻格子中的地雷数量(例如,数字$3$表示有3个地雷在邻域)。玩家可以标记可疑地雷位置,辅助决策。扫雷的经典地位源于其简单却深奥的玩法:它结合了概率、逻辑和记忆,成为计算机游戏的里程碑。

2501_90869623的博客 1888

扫雷小游戏C语言代码实现

主页面: 游戏页面: 虽然页面比较low,但我已经尽力了 具体代码实现: #include<stdio.h> #include<windows.h> #include<conio.h> #include<stdlib.h> #include<time.h> int n;//记录已经探索的区域数 int x,y;//光标的横纵坐标 in...

格戮 1872

C语言实现扫雷——详解

扫雷大家应该都玩过,这是一个十分经典的游戏,今天我将给大家讲解如何用C语言多文件编程实现扫雷,我的这个扫雷有如下几个功能: 显示该点周围雷的个数 第一次下子,不炸死 坐标周围没雷,可以实现展开 游戏结束后展示玩家用时 话不多说,先附上效果图: 我们只要输入坐标就可以扫雷了,是不是很有趣? 其实要想实现这也不难,我们要用几个算法模块来模拟游戏规则,需要用函数来调用...

一砚梨花雨 7万+

C语言扫雷详解实现

今天就用之前所学的知识来写一个C语言简易版扫雷游戏,主要涉及了C语言中的一些基本知识,循环、分支、函数、数组等等,一步一步写出来

m0_66483195的博客 769

Mathtype公式下标深度调整技巧:解决固定行距下的显示不全问题

本文针对在Word等文档中设置固定行距时,Mathtype公式下标显示不全的问题,提供了专业解决方案。核心在于调整Mathtype软件内部的“下标深度”参数,通过修改单个公式或批量格式化全文,使公式完美适配固定行距,确保下标清晰完整,且不影响文档整体排版。

pepsi的博客 1502

C语言—实现扫雷游戏(注释详解)

文章目录前言一、游戏规则介绍二、基本思路流程介绍三、代码实现1.用户交互菜单(Menu函数)2. Game函数3.放雷函数(SetMines函数)4.扫雷展示面板(ShowBoard函数和ShowLine函数)5.统计周围雷的个数(CountMines函数)6.mine函数四、总代码 前言 一、游戏规则介绍 扫雷是一个十分经典的游戏,一张棋盘中有很多个不确定是雷还是安全区域的格子,当点击之后若没有雷则会在该区域显示周围八个格子雷的数目,若有雷则游戏结束。今天我就跟大家分享一下如何用c语言实现初阶版扫雷。 二

Vae的黑粉 1万+

专访高性能计算专家赵开勇:无人机/机器人开发实战,如何优化深度学习?

从能够自主飞行的无人机,到能和小朋友玩物体识别等游戏的机器人,极客们对智能设备追求没有止境。除了轻巧的体积、超长的续航,更重要的是要有一个智能的“大脑”,来实现人类能够想得到的人机交互,或者智能化的自主决策和行为动作,毫无疑问强大的深度学习能力不可或缺。那么,拒绝束缚人类想象力的嵌入式智能设备,其开发工作需要什么样的环境和工具?开发者进行相关开发的可行思路是什么?近日,优快云记者就此专访了智能设...

happytofly的博客 3510

[C语言] [游戏] 扫雷

使用C语言写一个扫雷游戏 !(练习二维数组)!(超详细的游戏设置思路和书写细节)!(看看7318字就很......)

博主学浅才疏,权当信笔涂鸦。嘿嘿,就算是记录我的学习历程吧,不过有时我会写得很细,但解题思路常常只有一种,别介意哈 ^ ^ (也许能学到一点点)。希望大家多来踩踩,顺便可以关注我,一起交流学习。 1万+

HBuilderX结合Android Studio实现Uniapp安卓Apk高效离线打包指南

本文提供了一份详细的Uniapp安卓Apk离线打包实战指南。通过整合HBuilderX与Android Studio,手把手教你搭建本地编译环境、配置原生工程、执行核心打包流程,并分享快速更新资源和排查常见问题的技巧,助你彻底摆脱云端打包的排队依赖,实现高效、可控的应用构建。

weixin_28835551的博客 559

从零开始:用Xilinx FPGA实现RISC-V单周期CPU(附完整Verilog代码)

本文详细介绍了如何使用Xilinx FPGA从零开始实现RISC-V单周期CPU,包括开发环境搭建、核心架构设计、Verilog代码实现及功能验证。通过实战指南和完整代码示例,帮助开发者掌握RISC-V CPU设计的关键技术,适用于嵌入式系统和定制化计算场景。

weixin_30664051的博客 547

C语言实现扫雷小游戏详解

实现步骤第一步思考要实现的功能第二步实现初级版扫雷扫雷进阶---递归实现自动清空完整的源码写在最后的话 第一步思考要实现的功能 想必大家都知道扫雷这个小游戏,今天我们来用C语言实现一下,首先要扫雷,我们首先就需要有一个布置了雷的棋盘,然后开始扫雷,玩过扫雷的小伙伴都知道,如果选中的格子旁边没有雷,那么旁边的格子就会自动清空,大概的思路有了,现在我们开始实现。 第二步实现 初级版扫雷 首先创建棋盘的作用是用来存储雷的信息,这时我们思考一下,一个棋盘到底够不够用?棋盘多大才合适?我们打印出来的棋盘肯定是不能出现

JunFengYiHan的博客 9146

芯片测试中的DC与AC模式详解:如何选择最适合你的测试方案?

本文深入解析了芯片测试中DC(直流)与AC(交流)模式的核心差异与互补性。DC测试关注静态电气特性,如固定型故障;而AC测试则聚焦于芯片在额定工作速度下的动态时序行为。文章从VLSI设计、电路模块、成本约束、可测试性设计和应用场景五大维度,提供了如何根据工艺节点、工作频率及具体需求,在testMode配置、时钟复位策略和输入输出接口设计中,平衡两种测试模式以制定最优方案的决策框架。

bb456的博客 1088

扫雷游戏(C语言详解)

扫雷游戏(C语言详解)

2301_80667728的博客 2878

【应用】什么是Azure?一文读懂微软云的核心逻辑与全球版图

作为微软的核心云计算服务平台,Azure不仅是数字化转型的引擎,更是全球企业在构建、扩展与优化IT基础设施时的首选平台。在这篇文章中,我们将深入探讨Azure云服务平台的各个方面,涵盖其核心优势、架构、功能、应用场景以及未来发展趋势。

高校图书馆高级系统架构师/研究馆员,推动高校AI从概念演示到可评审、可交付、可运维:路线图与立项评审、PoC交付、评测回归与上线运维(Baseline/Eval/Ops)。 1963

十.镜头知识之畸变问题

对于理想光学系统,在一对共轭的物像平面上,像的放大率是一个常数。但是对于实际的光学系统,当视场较大或很大时,像的放大率就要随视场而异,这样就会使像相对于物体失去相似性。这种使像变形的成像缺陷称为畸变。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 2126

C语言实现扫雷游戏(超详细)

扫雷 思路:先制作一个菜单让玩家选择是玩游戏还是退出游戏,菜单做好了,接着我们开始制作扫雷的棋盘并初始化,初始化弄完了我们下一步开始埋雷,雷埋好了就开始扫雷。 大概思路就是这样具体实现看下面: 菜单的实现代码: int main() { int input = 0; srand((unsigned int)time(NULL)); do { printf("**************************\n"); printf("*** 1. play 0. exit ***\

qq_45326605的博客 1万+

FANUC机器人_CRX协作机器人的开机和示教器的初始化设置基本步骤(二)

FANUC机器人_CRX协作机器人的开机和示教器的初始化设置基本步骤

Robot_PLC_HMI_Automation 2732

C语言实现扫雷游戏完整代码

扫雷游戏的实现. c语言

xyk:的博客 8579

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【C语言】简易扫雷游戏——C语言实现

好玩的简易扫雷游戏——C语言实现

LX18792732127的博客 4万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【C语言】扫雷小游戏详解

还记得大明湖畔的夏雨荷,电脑课上的扫雷吗?一、想法与构思1.想法2.构思二、代码与实现三、完整代码               是他吗? 没错,就是他。你电脑课上偷偷玩过的扫雷,今天我们用C语言做一个扫雷小游戏。 《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。 接下来让我们进入代码的世界: 扫雷小游戏详解:一、想法与构思1.想法2.构思二、代码与实现三、完整代码 目录: 一

恒等于C的博客欢迎您 2842

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

扫雷游戏(c语言实现)

扫雷的代码量并不是很大,使用的知识点也都是基础,通过扫雷的简单实现可以帮助大家对C语言知识点的使用更加熟练以及写代码的逻辑有所帮助,我们只需分析扫雷步骤然后转化成代码的形式。扫雷代码上大家也可以加入自己的想法,这就需要大家自己动手了。希望此文章对大家能有所帮助,我会继续发博客跟着大家一起学习的。

2301_81790481的博客 1734

使用C语言实现【扫雷】游戏

如需引用,注明地址。

2401_82669797的博客 1175

用c语言编写一个扫雷游戏

来记录,其中一个存放布置雷的信息,另一个存放排查出的雷的信息。但是当我们要统计边缘的宫格,统计他们周围8个宫格的雷的数据时,此时。当我们排查雷的时候,如果该位置不是雷,我们要排查周围8个位置的雷的个数,因此为了避免使排查出的雷的个数和雷的标记冲突,我们用。很好,答案符合我们的预期。, 我们就可以对照雷表来判断我们的统计雷的个数的函数,是否写正确了。​ 我们打算采用字符数组,因为我们没排查的时候,宫格中显示的是“*”。很好,根据我们的测试,我们的逻辑没有错误。可见,我们对于雷的布置是成功的。

2302_80898090的博客 2276

c语言实现扫雷游戏

扫雷游戏默认为9*9个格子随机布置10个雷可以排查雷的坐标 ->通过输入坐标点形式例如:2 3表示坐标为(2,3)的坐标如果该位置不是雷,那么显示该坐标9宫格内有几个雷如果该位置是雷,则被炸死且游戏结束如果把不是雷的位置全部排查完,则游戏结束,排雷成功。

cjhbachelor的博客 2007

【C语言】扫雷游戏详解及完整代码

这篇文章将分享利用C语言实现扫雷的全过程讲解及其完整代码。初学C语言的朋友们也能看懂学会哦!这个简单的小游戏非常适合C语言新手小白操作。

weixin_64499321的博客 2929
上一篇: C 语言的分支与循环
下一篇: 深入理解 C 语言指针:从基础到高级应用
THGML
博客等级 码龄3年 49粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值