当前位置: 首页 > news >正文

第十篇 扫雷游戏 下(末版·精简)

主题:扫雷游戏开发,包括排雷阶段的两个核心问题及解决方案(方阵拓展和双数组设计),以及游戏主体的组装和完整代码实现

 本文Gitee链接:2025.11.13https://gitee.com/donghua-wanli/blog-code/tree/master/2025.11.13https://gitee.com/donghua-wanli/blog-code/tree/master/2025.11.13

书接上回:我们已完成雷区布置(10个雷)并打印布雷方阵,本章将聚焦排雷功能实现,解决开发中的核心问题,并整合完整代码。

目录

  1. 排雷阶段的两个核心问题

  2. 解决方案1:方阵拓展(解决边界排查差异)

    1. 2.1 方阵拓展的核心思路

    2. 2.2 头文件(game.h)宏定义修改

    3. 2.3 核心函数适配(初始化、打印、布雷)

  3. 解决方案2:双数组设计(解决数值歧义)

    1. 3.1 双数组的核心逻辑

    2. 3.2 字符数组初始化函数(chushihua2)

    3. 3.3 排雷函数(paicha)实现(含坐标校验、雷数计算)

  4. 游戏主体(game函数)组装与 extern 关键字应用

  5. 扫雷游戏完整代码(game.h / game.c / 11.13.c)

  6. 结尾

一、排雷阶段的两个核心问题

排雷的基础逻辑是两步:

  1. 判断目标坐标是否为雷(是则游戏结束,否则进入下一步);

  2. 计算目标坐标周围的雷数并展示。

但实际开发中遇到两个致命问题:

  • 问题1(边界排查差异):目标坐标在中间(8个方向)、边上(5个方向)、顶点(3个方向) 时,需写3个不同排查逻辑,程序复杂;

  • 问题2(数值歧义):用同一数组存储“雷(1)/非雷(0)”和“周围雷数(0-8)”时,无法区分“非雷(0)”和“周围雷数为0”,后续排查会受干扰。

二、解决方案1:方阵拓展(解决边界排查差异)

2.1 方阵拓展的核心思路

<span style="color:red; font-weight:bold;">核心逻辑:将9×9游戏方阵向外拓展1圈,形成11×11方阵</span>

  • 仅在中间9×9区域布置雷,拓展的外圈全部设为“非雷(0)”;

  • 此时无论目标坐标在原9×9的哪个位置,都可统一按“中间区域”排查(即检查周围8个方向),无需区分边界/顶点,彻底简化逻辑。

这也是之前将方阵行、列定义为9的“笨拙之处”——用宏定义(#define)可轻松修改方阵大小。

2.2 头文件(game.h)宏定义修改

只需修改行(Hang)、列(Lie)的宏定义,其他声明暂不变:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>// 关键修改:从9改为11(拓展为11×11方阵)
#define Hang 11   
#define Lie 11    // 函数声明(后续会补充)
void chushihua(int landmine[Hang][Lie]);// 整形数组初始化(存雷)
void zhanshi(int landmine[Hang][Lie]);// 打印数组
void setmine(int landmine[Hang][Lie]);// 布置雷

2.3 核心函数适配(初始化、打印、布雷)

拓展方阵后,需调整3个核心函数的逻辑(仅修改关键部分,尽量保留原代码):

(1)初始化函数(chushihua)——无需修改

因拓展的外圈需设为“非雷(0)”,而原初始化逻辑是将所有元素设为0,完全符合需求:

void chushihua(int landmine[Hang][Lie])// 整形数组初始化(存雷)
{int a;for (a = 0; a < Hang; a++){int b;for (b = 0; b < Lie; b++){landmine[a][b] = 0; // 外圈默认非雷,无需额外修改}}
}

(2)打印函数(zhanshi)——仅打印中间9×9区域

拓展后方阵为11×11,但玩家只需看原9×9游戏区,因此循环条件改为“1 ≤ 索引 ≤ 9”(即跳过外圈):

void zhanshi(int landmine[Hang][Lie])
{int a;// 关键修改:从0→Hang改为1→Hang-1(跳过外圈,打印中间9×9)for (a = 1; a < Hang - 1; a++){int b;for (b = 1; b < Lie - 1; b++){printf("%d", landmine[a][b]);}printf("\n");}
}
(3)布雷函数(setmine)——仅在中间9×9布雷

随机生成的坐标需限定在“1 ≤ x/y ≤ 9”,避免雷布到外圈,修改随机数生成逻辑:

void setmine(int landmine[Hang][Lie])
{int count = 10; // 共10个雷while (count){// 关键修改:rand()%(Hang-2)+1 → 生成1~9的随机数(跳过外圈)int x = rand() % (Hang - 2) + 1;int y = rand() % (Lie - 2) + 1;if (landmine[x][y] == 0) // 确保不重复布雷{landmine[x][y] = 1;count--;}}
}

三、解决方案2:双数组设计(解决数值歧义)

3.1 双数组的核心逻辑

<span style="color:red; font-weight:bold;">核心思路:用两个数组分别存储“雷的位置”和“排查结果”</span>

  • int landmine[Hang][Lie]:整形数组,仅存“雷(1)/非雷(0)”,不对外展示;

  • char showmine[Hang][Lie]:字符数组,对外展示——未排查用'*',排查后用字符数字(如'2'表示周围2个雷),彻底避免歧义。

3.2 字符数组初始化函数(chushihua2)

需新增一个函数,将showmine数组全部初始化为'*'(表示未排查),并在game.h中声明:

(1)game.h 补充声明
// 新增:字符数组初始化(存排查结果)
void chushihua2(char landmine[Hang][Lie]);
// 修改:打印函数参数改为字符数组(后续仅展示排查结果)
void zhanshi(char showmine[Hang][Lie]);
(2)chushihua2 函数实现
void chushihua2(char landmine[Hang][Lie])// 字符数组初始化(存排查结果)
{int a;for (a = 0; a < Hang; a++){int b;for (b = 0; b < Lie; b++){landmine[a][b] = '*'; // 所有位置默认未排查(*)}}
}

3.3 排雷函数(paicha)实现

排雷函数是核心,需完成坐标校验、雷判断、雷数计算、结果存储,步骤如下:

(1)game.h 声明排雷函数
// 排雷函数:参数为“雷数组”和“排查结果数组”
void paicha(int landmine[Hang][Lie], char showmine[Hang][Lie]);
(2)paicha 函数实现(关键逻辑标注)
void paicha(int landmine[Hang][Lie], char showmine[Hang][Lie])
{int a;int b;printf("请输入排查的坐标:");
chonglai:scanf("%d%d", &a, &b);if (a >= 1 && a <= 9 && b >= 1 && b <= 9){if (landmine[a][b] == 1){printf("你踩到雷了,炸死,游戏结束");return;}else{// 新增:判断坐标是否已排查if (showmine[a][b] != '*'){printf("该坐标已排查,请重新输入:");goto chonglai;}int c = 0; // 存储周围雷数// 后续雷数计算逻辑不变...int i;for (i = a - 1; i <= a + 1; i++){int j;for (j = b - 1; j <= b + 1; j++) {c += landmine[i][j];}}showmine[a][b] = c + 48;}}else{printf("输入错误,请输入符合格式的坐标:");goto chonglai;}}

(ASCII转换原理:字符'0'的ASCII值为48,因此c=2时,2+48=50对应字符'2',直接赋值给字符数组即可展示)

四、游戏主体(game函数)组装与 extern 关键字应用

4.1 问题:数组跨文件访问

landmineshowmine数组在11.13.c中定义,但game函数在game.c中实现,编译器会提示“未定义数组”。

解决方案:用extern关键字在game.c开头声明数组(表示“数组在其他文件中定义,此处仅引用”)。

4.2 game函数实现(整合所有逻辑)

(1)game.h 声明 game 函数
// 游戏主体函数
void game();

(2)game.c 中实现 game 函数

// 关键:用extern声明数组(来自11.13.c)
extern int landmine[Hang][Lie];
extern char showmine[Hang][Lie];void game()
{// 步骤1:初始化两个数组chushihua(landmine);    // 初始化雷数组(0=非雷)chushihua2(showmine);   // 初始化排查结果数组(*=未排查)// 步骤2:布置10个雷setmine(landmine);// 步骤3:排雷逻辑(需排71次非雷区域:9×9-10=71)int success_count = 0; // 成功排雷次数while (success_count < 71){paicha(landmine, showmine); // 一次排雷zhanshi(showmine);          // 打印当前排查结果success_count++;}// 步骤4:排完所有非雷,游戏胜利if (success_count == 71){printf("恭喜你排雷成功,游戏结束");}
}

五、扫雷游戏完整代码

5.1 game.h(头文件:宏定义+函数声明)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>// 方阵大小:11×11(中间9×9为游戏区,外圈用于简化边界判断)
#define Hang 11
#define Lie 11// 函数声明
void chushihua(int landmine[Hang][Lie]);// 整形数组初始化(存雷)
void chushihua2(char landmine[Hang][Lie]);// 字符数组初始化(存排查结果)
void setmine(int landmine[Hang][Lie]);// 布置雷
void paicha(int landmine[Hang][Lie], char showmine[Hang][Lie]);// 排雷
void zhanshi(char showmine[Hang][Lie]);// 打印排查结果
void game();// 游戏主体
 

5.2 game.c(函数实现)


extern int landmine[Hang][Lie];//制作存放雷的方阵:
extern char showmine[Hang][Lie];//制作存放排查结果的方阵:#include"game.h"void chushihua(int landmine[Hang][Lie])//将整形数组初始化
{int a;for (a = 0; a < Hang; a++){int b;for (b = 0; b < Lie; b++){landmine[a][b] = 0;}}
}void zhanshi(char showmine[Hang][Lie])
{int a;for (a = 1; a < Hang - 1; a++){int b;for (b = 1; b < Lie - 1; b++){printf("%c", showmine[a][b]);}printf("\n");}
}void setmine(int landmine[Hang][Lie])
{int count = 10;while (count){int x = rand() % (Hang - 2) + 1;int y = rand() % (Lie - 2) + 1;if (landmine[x][y] == 0){landmine[x][y] = 1;count--;}}
}void paicha(int landmine[Hang][Lie], char showmine[Hang][Lie])
{int a;int b;printf("请输入排查的坐标:");
chonglai:scanf("%d%d", &a, &b);if (a >= 1 && a <= 9 && b >= 1 && b <= 9){if (landmine[a][b] == 1){printf("你踩到雷了,炸死,游戏结束");return;}else{// 新增:判断坐标是否已排查if (showmine[a][b] != '*'){printf("该坐标已排查,请重新输入:");goto chonglai;}int c = 0; // 存储周围雷数// 后续雷数计算逻辑不变...int i;for (i = a - 1; i <= a + 1; i++){int j;for (j = b - 1; j <= b + 1; j++) {c += landmine[i][j];}}showmine[a][b] = c + 48;}}else{printf("输入错误,请输入符合格式的坐标:");goto chonglai;}}void chushihua2(char landmine[Hang][Lie])//将字符数组初始化
{int a;for (a = 0; a < Hang; a++){int b;for (b = 0; b < Lie; b++){landmine[a][b] = '*';}}
}void game()
{chushihua(landmine);chushihua2(showmine);//初始化两方阵setmine(landmine);//布置雷paicha(landmine, showmine);//排雷int a = 0;while (a<71){zhanshi(showmine);//打印排查结果a++;}if (a == 71){printf("恭喜你排雷成功,游戏结束");}}

5.3 11.13.c(主函数:菜单+入口)

#include"game.h"// 定义全局数组(供game.c用extern引用)
int x;
int landmine[Hang][Lie];// 存雷的整形数组
char showmine[Hang][Lie];// 存排查结果的字符数组int main()
{// 设置随机数种子(确保每次布雷位置不同)srand((unsigned int)time(NULL));// 游戏菜单printf("*******************************************\n");printf("*************** 扫雷游戏 *****************\n");printf("*** 请选择:1.开始游玩  2.退出游戏 ***\n");printf("*******************************************\n");printf("*******************************************\n");printf("*******************************************\n");scanf("%d", &x);switch (x){case 1:printf("************* 开始游戏 ***************\n");game(); // 进入游戏主体break;case 2:printf("************* 退出游戏 ***************\n");break;default:printf("************* 输入错误 ***************\n");break;}return 0;
}

六、结尾

嗯,希望能够得到你的关注,希望我的内容能够给你带来帮助,希望有幸能够和你一起成长。

写这篇博客的时候天气有点凉,冷风吹过阳台,裹着深夜的孤独。我走到阳台拍下了一张宿舍对面的照片作为本文的封面。

http://www.dtcms.com/a/613467.html

相关文章:

  • 开发者获取Claude API Key 申请指南:从注册到 Python 调用的实战教程
  • pyinstaller 介绍
  • 建设网站与服务器专业网页设计哪家好
  • 【大语言模型 125】开放域对话实战:自然流畅的闲聊系统完全指南
  • FastAPI基础项目:实现用户管理系统,实现基本的搜索和增删改查功能
  • 小众做的好的网站手机下载工具app
  • Qt for HarmonyOS 3D图片轮播组件开源鸿蒙开发实战
  • Evolution_07_环境
  • MinIO 不再“开放”,RustFS 能否成为更优选择?
  • DMLDCL
  • 大型ERP管理系统多语言分层架构设计
  • WordPress网站404公益页面公司网站建设策划书
  • B-树分析
  • 关于做网站建设公司你应该知道的宣传网站建设方案
  • VSCode 1.106 版本发布 —— 更强 AI 特性,更丝滑的编程体验!
  • F046 新闻推荐可视化大数据系统vue3+flask+neo4j
  • SpringMVC基础教程(3)--SSM框架整合
  • 1.硬件测试测试方案设计方法
  • 个人网站名字大全大学生创意产品设计
  • 基于 **Three.js** 开发的 3D 炮弹发射特效系统
  • 前端构建工具缓存清理,npm cache与yarn cache
  • 【开题答辩全过程】以 翡翠仓库管理系统为例,包含答辩的问题和答案
  • 2025 批量下载微博内容/图片/视频,导出word和pdf,微博点赞/评论/转发等数据导出excel
  • 高级网站开发工程师证书天眼查网站建设公司
  • 11.3 实战:使用FastGPT开发企业级智能问答Agent
  • Spring AI接入DeepSeek:构建你的第一个AI应用
  • 中国最大免费wap网站wordpress转代码
  • Unable to load class ‘org.slf4j.LoggerFactory‘.解决
  • 2025年印尼服务器选型指南:跨境业务落地的合规与性能双解
  • 【C++】C++11:右值引用和移动语义