C 语言实现经典扫雷游戏|从零到一完整教程(含详细注释 + 源码)
大家好,今天带大家用纯 C 语言从零实现经典的扫雷游戏!这个项目非常适合 C 语言新手,能巩固二维数组、函数封装、随机数、逻辑判断等核心知识点,代码完整可直接运行,保姆级教学,新手也能轻松学会~
一、游戏需求分析
我们要实现的扫雷功能:
- 9×9 的游戏棋盘(外围加一圈安全边距,防止坐标越界)
- 随机布置 80 个地雷(难度可自定义)
- 输入坐标排查地雷:踩到雷直接游戏结束,没踩到显示周围雷数
- 排查完所有非雷区域,游戏胜利
二、整体设计思路
扫雷需要两个二维数组,分工明确:
- mine 数组:存放地雷布局(
'0'= 无雷,'1'= 有雷),不对玩家展示 - show 数组:玩家看到的界面(
'*'= 未排查,数字 = 周围雷数) - 函数模块化:初始化棋盘、布置雷、打印棋盘、排查雷
三、分模块代码实现
我们采用多文件编程,代码更清晰:
game.h:头文件(宏定义、函数声明、头文件包含)game.c:游戏功能函数实现test.c:主函数、游戏逻辑入口模块 1:头文件 game.h
统一管理宏定义和函数声明,方便后期修改游戏参数
-
#pragma once // 防止头文件重复包含
-
#include <stdio.h>
-
#include <time.h>
-
#include <stdlib.h> // rand、srand函数需要 // 宏定义(修改这里就能调整棋盘大小/雷数)
-
#define ROW 9 // 实际游戏行
-
#define COL 9 // 实际游戏列
-
#define ROWS ROW+2 // 带边距行(防止越界)
-
#define COLS COL+2 // 带边距列
-
#define EASY_COUNT 80// 简易模式雷数 // 函数声明
-
void menu(); // 菜单
-
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); // 初始化棋盘
-
void SetMine(char board[ROWS][COLS], int row, int col); // 布置地雷
-
void DisplayBoard(char board[ROWS][COLS], int row, int col); // 打印棋盘
-
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); // 排查地雷
-
模块 2:游戏函数实现 game.c
包含所有游戏核心功能,代码带详细注释
-
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"// 1. 游戏菜单
void menu()
{
printf("----------------------\n");
printf("------ 0. 退出 -------\n");
printf("------ 1. 开始 -------\n");
printf("----------------------\n");
}// 2. 初始化棋盘:把数组所有元素设置为指定字符set
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}// 3. 随机布置地雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT; // 需要布置的雷数
while (count)
{
// 生成1~9的随机坐标(避开边距)
int x = rand() % row + 1;
int y = rand() % col + 1;if (board[x][y] == '0') // 该位置无雷,才布置
{
board[x][y] = '1';
count--;
}
}
}// 4. 打印棋盘(带坐标提示,方便玩家输入)
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
// 打印列号
int i = 0;
int j = 0;
printf(" ");
for (j = 1; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");// 打印行号+棋盘内容
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}// 5. 计算(x,y)坐标周围8个格子的地雷数量
int GetMineCount(char board[ROWS][COLS], int x, int y)
{
// 字符'0'=48,'1'=49,相加后减8*'0',直接得到数字
return board[x - 1][y - 1] +
board[x - 1][y] +
board[x - 1][y + 1] +
board[x][y - 1] +
board[x][y + 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1] -
8 * '0';
}// 6. 排查地雷(核心逻辑)
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0; // 已排查的非雷格子数// 总非雷数 = 总格子 - 雷数
while (win < row * col - EASY_COUNT)
{
printf("请输入排查坐标(行 列):");
scanf("%d %d", &x, &y);// 1. 判断坐标合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
// 2. 踩到雷 → 游戏结束
if (mine[x][y] == '1')
{
printf("💣 很遗憾,你踩到地雷了!\n");
DisplayBoard(mine, ROW, COL); // 展示雷区
break;
}
// 3. 没踩到雷 → 计算周围雷数
else
{
if (show[x][y] == '*') // 未被排查过
{
// 把数字存入show数组
show[x][y] = GetMineCount(mine, x, y) + '0';
DisplayBoard(show, ROW, COL);
win++;
}
else
{
printf("⚠️ 该坐标已排查过!\n");
}
}
}
else
{
printf("❌ 坐标非法,请重新输入!\n");
}
}// 所有非雷都排查完 → 胜利
if (win == row * col - EASY_COUNT)
{
printf("🎉 恭喜你,扫雷成功!\n");
}
}
模块 3:主逻辑 test.c
游戏入口,控制开始 / 退出 -
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"// 游戏核心流程
void game()
{
// 定义两个数组
char mine[ROWS][COLS] = { 0 }; // 存放雷
char show[ROWS][COLS] = { 0 }; // 展示界面// 1. 初始化数组
InitBoard(mine, ROWS, COLS, '0'); // mine全初始化为'0'
InitBoard(show, ROWS, COLS, '*'); // show全初始化为'*'// 2. 布置地雷
SetMine(mine, ROW, COL);// 调试用:打印雷区(正式游戏可注释)
// DisplayBoard(mine, ROW, COL);// 3. 打印玩家界面
DisplayBoard(show, ROW, COL);// 4. 排查地雷
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:
printf("🎮 开始扫雷!\n");
game();
break;
default:
printf("❌ 选择错误,请重新输入!\n");
break;
}
} while (input);return 0;
}
四、关键知识点讲解
1. 为什么要用 ROWS=ROW+2?
9×9 的棋盘,排查边缘坐标时(比如(1,1)),需要访问(0,0),会数组越界崩溃。
加一圈边距,所有排查逻辑都不用判断边界,代码更简单安全!
2. 字符数字计算原理
字符'0'的 ASCII 码是 48,'1'是 49
8 个格子相加后,减去8*'0',直接得到整数雷数
最后加'0',转回字符存入数组
3. 随机数布置地雷
rand()生成随机数
rand()%9+1 → 生成 1~9 的合法坐标
srand((unsigned int)time(NULL)):用时间戳做种子,保证每次雷区不同
五、运行效果
菜单界面
玩家初始界面(全*)
输入坐标排查,显示数字
踩雷 → 展示全部雷区
排完所有非雷 → 游戏胜利
六、可扩展优化方向
添加标记地雷功能(输入特殊符号标记雷)
实现自动展开(点开 0 周围无雷,自动展开一片)
增加难度选择(简单 / 中等 / 困难)
美化界面(加颜色、分隔线)
七、总结
这个扫雷项目完美覆盖了 C 语言数组、函数、循环、随机数、逻辑判断等核心知识点,代码结构清晰、注释详细,非常适合新手练习。
跟着教程一步步敲,你不仅能写出可运行的游戏,更能理解模块化编程的思想,这对后续学习 C 语言、数据结构都非常有帮助!
需要完整源码文件的同学可以直接复制代码,创建三个文件即可运行~有问题欢迎评论区交流!
1516

被折叠的 条评论
为什么被折叠?



