尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【C语言】扫雷游戏详解 - 指南

【C语言】扫雷游戏详解 - 指南
📅 发布时间:2026/6/19 13:20:55

【C语言】扫雷游戏详解 - 指南

扫雷游戏的功能说明

  • 使用控制台来模拟扫雷游戏
  • 控制台中棋盘的大小为 9*9(后续也可以扩大)
  • 默认棋盘中有10个雷
  • 如果排雷位置不是雷,就显示周围有几个雷
  • 如果排雷位置是雷,就被炸死结束游戏
  • 把除了10个雷以外的位置排查完,则排雷成功,游戏结束

扫雷游戏的功能分析

  • 游戏的菜单设计
  • 游戏可能不止玩一次,是否进行游戏,这里我们使用switch通过用户的输入来判定是否继续
  • 在扫雷的过程中,布置好的雷的棋盘和打印在控制台上排雷的棋盘都需要存储,所以这里我们使用两个数组分别进行存储
  • 棋盘是 9*9 的大小,我们用二维数组来实现
  • 考虑到排查的雷如果在99的边缘的某一个,在计算周围雷的数量就会发生越界,所以实际上的棋盘应该是 1111,显示在控制台的大小是 9*9
  • 在棋盘中,没有雷的位置存放0,有雷的位置存放1,雷的生成通过rand和srand来实现
  • 通过字符的形式表示1和0,为了表示神秘感,打印在控制台排雷时,棋盘所有的位置都是*,如果是用整形,有可能会有冲突,为了避免这些情况,我们统一使用字符来表示

实现扫雷游戏必备的知识

  • 头文件的作用
  • 判断
  • 循环
  • 数组
  • 函数

游戏的框架

为了养成良好的代码习惯,我们将使用三个文件分别来实现扫雷游戏
test.c:所有的在进入游戏逻辑之前的代码
game.c: 所有游戏的功能
game.h:所有函数的声明,包含的头文件

游戏的实现

❤️游戏的启动

  • 我们使用 input 这个整形变量来判断游戏是否进行
  • 使用 do...while 循环来包含整个游戏的启动逻辑,需要保证就算游戏不进行第二次,也要有至少一次启动
  • do...while 条件通过 input 来判断,用户输入 1 就表示继续游戏,输入 0 表示退出游戏,当 input 为 0 时,条件值为假,do...while 就不会执行函数体了
  • 使用 srand 来生成 rand 函数的种子,srand 中使用 time 函数来计算当下的时间戳,保证每次生成的种子都不一样,srand 函数中参数要求 unsigned int 类型
  • 游戏启动打印菜单,菜单等后续继续介绍
  • 打印完菜单后,让用户输入 input 的值
  • 使用 switch 语句来判断游戏是退出还是继续
  • 这里使用 game() 函数,所有函数的功能都将放在这个函数中实现
test.c
int main() {
int input = 0;
srand((unsigned int)time(NULL));
do{
menu();
printf("请输入:> ");
scanf("%d", &input);
switch (input) {
case 0:
printf("退出游戏\n");
break;
case 1:
game();
break;
default:
printf("选择错误,请重新输入\n");
break;
}
}while(input);
return 0;
}

❤️菜单的设计

  • 菜单使用 menu() 函数来实现
test.c
void menu() {
printf("------------------------\n");
printf("-------- 1. play -------\n");
printf("-------- 0. exit--------\n");
printf("------------------------\n");
}

❤️游戏逻辑的设计

  • 在整个游戏逻辑的设计中,调用各个游戏的功能来实现游戏
  • 在 game.h 头文件中包含对应的常量和库文件
  • 初始化棋盘:将棋盘初始化为 11*11 的大小,所以使用 ROWS 和 COLS,将数组还有初始化成的字符传入函数
  • 打印棋盘:初始化好后,将棋盘打印,因为只需要打印 9*9 大小的棋盘,所以是 ROW 和 COL
  • 布置雷:传入的参数与上同理,具体实现看下
  • 排查雷:传入的参数与上同理,具体实现看下
game.h
#include <stdio.h>#include <stdlib.h>#include <time.h>#define EASY_COUNT 10  // 雷的个数#define ROW 9   // 数组的行#define COL 9    // 数组的列#define ROWS ROW+2#define COLS COL+2
test.c
void game() {
char mine[ROWS][COLS];  // 存放布置好的雷
char show[ROWS][COLS];  // 存放排查出来的雷
// 初始化棋盘
// 1.mine数组最开始全是 '0'
// 2.show数组最开始全是 '*'
InitBoard(mine,ROWS,COLS,'0');
InitBoard(show,ROWS,COLS,'*');
// 打印棋盘
//DisplayBoard(mine,ROW,COL);
DisplayBoard(show,ROW,COL);
// 布置雷
SetMine(mine,ROW,COL);
//DisplayBoard(mine,ROW,COL);
// 排查雷
FindMine(mine,show,ROW,COL);
}

❤️初始化棋盘

  • 使用嵌套循环来控制数组,分别使用 row、col 来控制循环,set 控制存放的字符
void InitBoard(char board[ROWS][COLS],int row,int col,char set) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
board[i][j] = set;
}
}
}

❤️打印棋盘

  • 将 row 和 col 参数传进函数,使用循环来打印棋盘
  • 并且在打印棋盘的基础上,让棋盘有序号来标识
  • 第一次循环,先使用循环,打印 0~9,来表示每列的序号
  • 第二次循环,每行打印棋盘前,先打印行号,因为第一次循环,已经打印了 0,并且,打印棋盘从 1 开始打印,如果从 0 开始打印,打印的是棋盘的边界,所以变量 i 和 j 都从 1 开始打印

在这里插入图片描述

void DisplayBoard(char board[ROWS][COLS],int row,int col) {
printf("------扫雷游戏------\n");
for (int i = 0 ; i <= row; i++) {
printf("%d ",i);
}
printf("\n");
for (int i = 1; i <= row; i++) {
printf("%d ",i);
for (int j = 1; j <= col; j++) {
printf("%c ",board[i][j]);
}
printf("\n");
}
}

❤️排查雷

  • 定义变量 x 和 y,让 rand 函数随机生辰 1~9 的随机数
  • 再使用 while 循环以 count 来作为直接条件
  • 判断数组中,如果是 0,也就是没有雷,就变成 1,表示布置雷,每变一次,count 值就少一个,就像雷,放一个就少一个,当雷放置完了,count 等于 0,while 循环体就不执行了
void SetMine(char board[ROWS][COLS],int row,int col) {
// 布置 10 个雷
// 生成随机的坐标,布置雷
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--;
}
}
}

❤️排查雷

  • 依旧定义变量 x 和 y,来表示棋盘坐标
  • 定义变量 win,来表示排雷的次数,循环的条件,当 win 的值等于棋盘上所有格子的个数减去雷的个数,就是没有雷的个数,当 win 大于这个值,就表示所有坐标位置都排查完了,排雷成功
  • 首先先判断用户输入的坐标是不是合法的,如果不合法,直接结束循环,重新开始
  • 如果坐标合法,开始判断输入的坐标位置是不是雷,如果是雷就炸死,游戏结束,重新开始
  • 如果不是雷,就显示当前坐标周围的雷的个数,排雷次数 win+1 ,具体实现看下
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col) {
// 初始化坐标
int x = 0 ;
int y = 0 ;
int win = 0; // 排雷的过程,成功排一次 win+1
while (win < row * col - EASY_COUNT) {   // 排雷的次数应该小于棋盘的总数-雷的个数
printf("请输入要排查的坐标:> ");
scanf("%d %d", &x,&y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine,ROW,COL);
break;
}
else {
// 如果这个位置不是雷,就要统计周围有几个雷
int count = GetMineCount(mine,x,y);
show[x][y] = count + '0';
DisplayBoard(show,ROW,COL);
win++;
}
}
else {
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT) {
printf("恭喜你,排雷成功\n");
DisplayBoard(mine,ROW,COL);
}
}

❤️排查坐标周围的雷的个数

  • 计算周围雷的个数我们单独用一个函数来计算
  • 当输入合法坐标,并且不是雷时,判断周围坐标中累的个数
  • x 是横坐标,y 是纵坐标
  • 图中是坐标周围的坐标,基于图片的这些坐标,来判断雷的个数
  • 因为我们存储的都是字符,1 的 ascll 是 49,0 的 ascll 是 48
  • 假设周围有 2 个雷,周围的情况就是 6个0,2个1,6*48+2*49-8*48=386-284=2

在这里插入图片描述

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

到这,游戏的功能全都实现了,扩展功能后续再分享

游戏的代码

test.c

#include "game.h"
void menu() {
printf("------------------------\n");
printf("-------- 1. play -------\n");
printf("-------- 0. exit--------\n");
printf("------------------------\n");
}
void game() {
char mine[ROWS][COLS];  // 存放布置好的雷
char show[ROWS][COLS];  // 存放排查出来的雷
// 初始化棋盘
// 1.mine数组最开始全是 '0'
// 2.show数组最开始全是 '*'
InitBoard(mine,ROWS,COLS,'0');
InitBoard(show,ROWS,COLS,'*');
// 打印棋盘
//DisplayBoard(mine,ROW,COL);
DisplayBoard(show,ROW,COL);
// 布置雷
SetMine(mine,ROW,COL);
//DisplayBoard(mine,ROW,COL);
// 排查雷
FindMine(mine,show,ROW,COL);
}
int main() {
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入:> ");
scanf("%d", &input);
switch (input) {
case 0:
printf("退出游戏\n");
break;
case 1:
game();
break;
default:
printf("选择错误,请重新输入\n");
break;
}
}while (input);
return 0;
}

game.h

#ifndef GAME_H
#define GAME_H
#include <stdio.h>#include <stdlib.h>#include <time.h>#define EASY_COUNT 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 board[ROWS][COLS],int row,int col) ;// 排查雷void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col) ;#endif //GAME_H

game.c

#include "game.h"
// 初始化棋盘
void InitBoard(char board[ROWS][COLS],int row,int col,char set) {
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
board[i][j] = set;
}
}
}
// 打印棋盘
void DisplayBoard(char board[ROWS][COLS],int row,int col) {
printf("------扫雷游戏------\n");
for (int i = 0 ; i <= row; i++) {
printf("%d ",i);
}
printf("\n");
for (int i = 1; i <= row; i++) {
printf("%d ",i);
for (int j = 1; j <= col; j++) {
printf("%c ",board[i][j]);
}
printf("\n");
}
}
// 布置雷
void SetMine(char board[ROWS][COLS],int row,int col) {
// 布置 10 个雷
// 生成随机的坐标,布置雷
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--;
}
}
}
// 排查坐标周围的雷
int GetMineCount(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');
}
// 排查雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col) {
// 初始化坐标
int x = 0 ;
int y = 0 ;
int win = 0; // 排雷的过程,成功排一次 win+1
while (win < row * col - EASY_COUNT) {   // 排雷的次数应该小于棋盘的总数-雷的个数
printf("请输入要排查的坐标:> ");
scanf("%d %d", &x,&y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine,ROW,COL);
break;
}
else {
// 如果这个位置不是雷,就要统计周围有几个雷
int count = GetMineCount(mine,x,y);
show[x][y] = count + '0';
DisplayBoard(show,ROW,COL);
win++;
}
}
else {
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT) {
printf("恭喜你,排雷成功\n");
DisplayBoard(mine,ROW,COL);
}
}

相关新闻

  • 完整教程:从零开始搭建 flask 博客实验(3)
  • PbootCMS内容详情页标签
  • 2025年12月雅思机构深度测评:5家高性价比选择,真实提分数据全解析

最新新闻

  • CTF密码学实战:Python AES加解密核心原理与攻击技巧
  • 2026 南宁钻石回收最新行情,克拉钻裸钻实时报价参考 - 讯息早知道
  • 北京东城区黄金回收指南:收的顶专业机构VS银行VS金店怎么选? - 奢侈品回收测评
  • 2026西安黄金行情解析|高位变现时机与门店测评 - 奢侈品回收测评
  • 旧饰焕新颜,财富再启航。广州首饰回收传递生活新希望 - 奢品小当家
  • 2026武汉黄金回收TOP5优质商家推荐【6月最新版】设备硬核资金足报价高变现无忧 - 名奢变现站

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号