好久不见呀我的粉丝朋友们,由于近段时间太忙碌,导致更新博文的更新速度大幅降低了,在这里先对大家说声不好意思!恰好今天是2025年3月8日,祝各位女性朋友们女神节快乐!
我今这次要跟大家分享的是如何 使用C语言实现一个游戏-----扫雷游戏! 希望看完这篇博文能给你带来帮助,非常感谢大家对博主的支持!
文章目录
- 🎡一、前言
- 🎄二、功能说明
- 🏠三、分析和设计
- ⭐四、多文件处理
- 🚀五、游戏各功能的实现
-
- [1. 创建菜单](#1. 创建菜单)
- [2. 初始化棋盘](#2. 初始化棋盘)
- [3. 打印棋盘](#3. 打印棋盘)
- [4. 布置雷](#4. 布置雷)
- [5. 排查雷](#5. 排查雷)
- [6. 计算九宫格内雷的个数](#6. 计算九宫格内雷的个数)
- 🎉六、整体代码
-
- [1. game.h](#1. game.h)
- [2. game.c](#2. game.c)
- [3. test.c](#3. test.c)
🎡一、前言
扫雷游戏,相信大家对此并不陌生。这次我们使用C语言实现扫雷游戏的目的就是为了巩固我们之前所学习的知识,将我们的所学的知识串联起来,加深我们对知识的理解。
🎄二、功能说明
- 使用控制台实现经典的扫雷游戏
- 游戏可以通过菜单实现是否继续或者退出游戏
- 棋盘大小为9 * 9的规格
- 随机布置10个雷
- 排查雷
(1)如果该位置不是雷,就显示周围有几个雷
(2)若该位置是雷,则被炸死,游戏结束
(3)如果10个雷都被排查出来,说明排雷成功,游戏结束
🏠三、分析和设计
- 数据结构分析
在扫雷的过程中,布置雷的信息和排查出雷的信息都需要被存储起来,因此我们会想到创建一个数组为9 * 9大小用来存储相关信息。 - 如果这个位置是雷,我们就存放'1',否则存放'0'
- 在排雷的过程中,如图一,当我们排查(8,6)这个坐标时,我们发现会产生越界访问,因此在设计数组时,给数组扩大一圈,如图二,布置雷的时候还是布置在中间9*9的坐标上,这样设计就可以避免数组产生越界访问了。
4.我们在棋盘上布置是雷为'1',不是雷为'0'的信息,假设我们排查出某一位置不是雷并统计周围有多少雷的个数时,我们需要将周围雷的个数给打印出来,作为我们排查雷的依据,那么这个周围雷的个数信息该存放在哪呢?如果存放在布置雷的数组中,就会和我们布置雷的信息产生混淆。因此我们想到专门给一个棋盘mine为布置好雷的信息,给另外一个棋盘show为排查出雷的信息,这样就不会互相干扰了。为了保持神秘,我们将show数组全部初始化为 ' * ' ,mine数组全部初始化为 ' 0 ',布置好雷的位置为 ' 1 '。 如下图所示:
⭐四、多文件处理
我们为了代码逻辑清晰,我们一共分为三个文件来实现:
- game.c(完成游戏主要功能代码实现)
- game.h(完成游戏中需要的头文件以及函数声明)
- test.c (测试游戏运行的逻辑)
🚀五、游戏各功能的实现
1. 创建菜单
我们设计当用户输入1的时候则进入游戏,输入0的时候则退出。当用户输入其他数字时我们会提示输入数字非法等相关信息,并重新输入,因此需要使用循环来实现相关功能。
c
void Menu()
{
printf("***********************\n");
printf("******* 1.PLAY ******\n");
printf("******* 0.EXIT ******\n");
printf("***********************\n");
}
int main()
{
int input = 0;
do
{
Menu();
printf("请输入:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("扫雷游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入数字非法,请重新输入\n");
}
} while (input);
return 0;
}
2. 初始化棋盘
c
//初始化棋盘
void InitBoard(char arr[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++)
{
arr[i][j] = set;
}
}
}
3. 打印棋盘
c
//打印棋盘
void PrintBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("-----扫雷游戏--------\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[row][col]);
}
printf("\n");
}
}
效果展示:

4. 布置雷
一、随机产生雷
要想随机产生雷,我们就需要随机数的产生,那要怎么样实现随机数的产生呢?C语言提供了一个函数叫rand来生成随机数,它生成随机数的大小范围为:0-RAND_MAX,而这个最大值通常为32767。使用这一函数时需要包含头文件 <stdlib.h> 但需要注意的是,rand函数生成的是伪随机数,而不是真正的随机数,每一次程序运行时同一个rand函数生成的随机数是相同的,是因为rand的函数是对一个"种子"的基准值进行运算而生成的随机数,而rand的种子默认为1。因此要生成真正的随机数,就要让种子不断发生改变。对此,C语言又提供一个函数叫srand函数。程序每次使用rand函数时先调用srand函数,通过srand种子的改变来改变rand种子所生成的随机数。那么该怎么让srand函数的种子是随机的呢?经过我们的考虑,我们发现时间是一直在改变的,如果我们将时间作为种子,那么rand就可以生成每次不一样的随机数了。C语言也提供了time函数,也需要包含头文件 <time.h> ,该函数的返回类型为time_t。
二、布置雷的范围
由于我们想布置雷的范围为横纵坐标轴1 - 9。因此我们需要确定rand的范围
c
rand() % 9 //所得到的为 0-8的余数
rand() % 9 + 1 // 所得到的为 1-9的余数
了解上述知识后,我们就可以进行代码实现了
c
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EasyCount;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
5. 排查雷
c
//排查雷
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 - EasyCount)
{
printf("请输入你要排查的坐标:>\n");
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");
PrintBoard(mine, ROW, COL);
break;
}
else
{
//统计周围雷的个数
int count = GetCountMine(mine, x, y);
show[x][y] = count + '0';
PrintBoard(show, ROW, COL);
win++;
}
}
else
{
printf("输入坐标已经被排查,请重新输入!\n");
}
}
else
{
printf("输入坐标非法,请重新输入\n");
}
}
if (win == row * col - EasyCount)
{
printf("恭喜你,排雷成功!游戏结束\n");
PrintBoard(show, ROW, COL);
}
}
6. 计算九宫格内雷的个数
字符'0'的ASCII值为49,字符'1'的ASCII值为48,我们只需要将字符'1'减去字符'0',得到的就是数字1,按照这一逻辑我们就可以得到周围雷的个数。
c
int GetCountMine(char mine[ROW][COL],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';
}
🎉六、整体代码
1. game.h
c
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW + 2
#define COLS COL + 2
//雷的个数
#define EasyCount 10
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void PrintBoard(char arr[ROWS][COLS], int row, int col);
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
2. game.c
c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//初始化棋盘
void InitBoard(char arr[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++)
{
arr[i][j] = set;
}
}
}
//打印棋盘
void PrintBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 0;
printf("-----扫雷游戏--------\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col)
{
int count = EasyCount;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
//统计周围雷的个数
int GetCountMine(char mine[ROW][COL],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;
while (win < row * col - EasyCount)
{
printf("请输入你要排查的坐标:>\n");
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");
PrintBoard(mine, ROW, COL);
break;
}
else
{
//统计周围雷的个数
int count = GetCountMine(mine, x, y);
show[x][y] = count + '0';
PrintBoard(show, ROW, COL);
win++;
}
}
else
{
printf("输入坐标已经被排查,请重新输入!\n");
}
}
else
{
printf("输入坐标非法,请重新输入\n");
}
}
if (win == row * col - EasyCount)
{
printf("恭喜你,排雷成功!游戏结束\n");
PrintBoard(show, ROW, COL);
}
}
3. test.c
c
#include"game.h"
void Menu()
{
printf("***********************\n");
printf("******* 1.PLAY ******\n");
printf("******* 0.EXIT ******\n");
printf("***********************\n");
}
void game()
{
//mine数组
char mine[ROWS][COLS] = { 0 };
//show数组
char show[ROWS][COLS] = { 0 };
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
PrintBoard(mine, ROW, COL);
//PrintBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
PrintBoard(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
Menu();
printf("请输入:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("扫雷游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入数字非法,请重新输入\n");
}
} while (input);
return 0;
}
感谢读者们耐心的观看,希望看完这篇文章能给你带来有所帮助,今天的分享到这里就结束了!期待我们下次的相遇(●'◡'●)