一、问题的描述本篇文章主要为大家介绍C语言如何实现扫雷游戏,感兴趣的小伙伴们可以参考一下
二、游戏设计的基本流程雷区中随机布置一定数量的地雷,玩家需要尽快找出所有不是地雷的方块,但不许踩到地雷。玩家标记所有地雷后,选择排雷结束,然后游戏判断玩家是否完成扫雷。
三、程序的具体实现 1. 菜单界面1、创建游戏菜单。
2、创建和初始化雷区。
3、打印排雷雷区。
4、玩家选择相关操作,并输入坐标。5、玩家选择排雷完成。
6、判断扫雷是否完成。
用户选择 1 开始游戏, 选择 0 退出游戏。
void menu() {
printf("*************************n");
printf("****** 1. play *****n");
printf("****** 0. exit *****n");
printf("*************************nn");
}
void test() {
int input = 0;
srand((unsigned int)time(NULL));
menu();
do
{
printf("请输入你的选择:");
scanf("%d", &input);
switch (input)
{
case 1:
system("cls");
game();
menu();
break;
case 0:
break;
default:
printf("您的输入有误,请重新输入");
Sleep(200);
system("cls");
menu();
break;
}
} while (input);
system("cls");
printf("欢迎下次使用!!!nn");
Sleep(300);
}
int main() {
test();
return 0;
}
2. 创建雷区
要进行游戏,我们首先要创建一个雷区。
雷区:使用11行11列的二维数组来表示,元素类型是char。使用宏定义:
1.推高代码可读性。
2.提高扩展性,便于修改雷区尺寸和地雷数量。
#ifndef __HEAD_H__ #define __HEAD_H__ #define _CRT_SECURE_NO_WARNINGS 1 #include#include #include #include #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 #endif
// 1. 布置好的雷的信息
char mine[ROWS][COLS] = { 0 };
// 2. 排查雷的信息
char show[ROWS][COLS] = { 0 };
3. 初始化雷区
用 * 来初始化排雷区,隐藏雷区上面的地雷。
用 1 来初始化雷的位置,设置雷区的地雷。
void InitBoard(char board[ROWS][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;
}
}
}
4. 随机布雷
电脑随机设置地雷:
1.使用 随机数种子 srand((unsigned int)time(NULL))。
2.要在雷区空的地方布雷。
void SetMine(char board[ROWS][COLS], int row, int col) {
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--;
}
}
}
5. 打印雷区
用户在玩游戏的时候,要看到雷区。
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
for (int i = 0; i <= row; i++) {
printf(" %d ",i);
if(i < row)
printf("|");
}
printf("n");
for (int i = 0; i <= row; i++) {
printf("---");
if (i < row)
printf("|");
}
printf("n");
for (int i = 1; i <= row; i++) {
printf(" %d |", i);
for(int j = 1; j <= col; j++) {
printf(" %c ", board[i][j]);
if (j < col) {
printf("|");
}
}
printf("n");
if (i < row) {
for (int j = 0; j <= row; j++) {
printf("---");
if (j < row)
printf("|");
}
printf("n");
}
}
printf("n");
}
6. 玩家排雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int ck = 0;
char ch = ' ';
while (1) {
DisplayBoard(show, ROW, COL);
printf("-----------------------n");
printf("--> p. 排雷 n");
printf("--> b. 标记 n");
printf("--> e. 标记完成 n");
printf("-----------------------nn");
Flag:
printf("请输入您的操作: ");
getchar();
scanf("%c", &ch);
switch (ch)
{
case 'p':
{ P_1:
printf("请输入坐标: ");
scanf("%d", &x);
scanf("%d", &y);
if (x <= row && x >= 1 && y <= col && y >= 1) {
if (mine[x][y] == '1') // 踩雷
{
system("cls");
printf("nT_T T_T T_T T_T T_T T_Tn");
printf("很遗憾,你被炸死了!!!n");
printf("T_T T_T T_T T_T T_T T_Tnn");
DisplayBoard(mine, ROW, COL);
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
else // 不是雷
{
// 计算x,y 周围有几个雷?
get_mine_count(mine, show, x, y);
//DisplayBoard(show, ROW, COL);
system("cls");
}
}
else
{
printf("您输入坐标有误, 请重新输入^_^n");
goto P_1;
}
}
break;
case 'b':
{ B_1:
printf("请输入坐标: ");
scanf("%d", &x);
scanf("%d", &y);
if (x <= row && x >= 1 && y <= col && y >= 1) {
MarkMine(mine, show, x, y);
system("cls");
}
else
{
printf("您输入坐标有误, 请重新输入^_^n");
goto B_1;
}
}
break;
case 'e':
// 检查玩家的扫雷状态
ck = judge(mine, show);
if (ck == 1) {
system("cls");
printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
printf("恭喜你,扫雷完成!!!n");
printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
else
{
system("cls");
printf("nT_T T_T T_T T_T T_T T_Tn");
printf("很遗憾,扫雷失败!!!n");
printf("T_T T_T T_T T_T T_T T_Tnnn");
DisplayBoard(mine, ROW, COL);
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
break;
default:
printf("您输入操作有误, 请重新输入^_^n");
goto Flag;
break;
}
}
End:
;
}
7. 查看周围地雷数量
// 展开功能的实现,递归
int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
if (x <= ROW && x >= 1 && y <= COL && y >= 1)
{
if (show[x][y] == ' ')
{
return 0;
}
int n = mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y] +
mine[x + 1][y - 1] +
mine[x + 1][y + 1] - 8 * '0';
if (n == 0) {
show[x][y] = ' ';
get_mine_count(mine, show, x - 1, y);
get_mine_count(mine, show, x-1, y-1);
get_mine_count(mine, show, x-1, y+1);
get_mine_count(mine, show, x, y-1);
get_mine_count(mine, show, x, y+1);
get_mine_count(mine, show, x+1, y);
get_mine_count(mine, show, x+1, y-1);
get_mine_count(mine, show, x+1, y+1);
}
else
{
show[x][y] = '0' + n;
return 0;
}
}
return 0;
}
8. 标记地雷
int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
if (show[x][y] == '$') {
show[x][y] = '*';
}
else
{
show[x][y] = '$';
}
return 0;
}
9. 判断成败
int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
int count = 0;
for (int i = 1; i <= ROW; i++) {
for (int j = 1; j <= COL; j++) {
if (show[i][j] == '$') {
if (mine[i][j] == '1') {
count++;
}
}
}
}
if (count == EASY_COUNT) {
return 1;
}
return 0;
}
四、完整代码
1. head.h
#ifndef __HEAD_H__ #define __HEAD_H__ #define _CRT_SECURE_NO_WARNINGS 1 #include2. game.c#include #include #include #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 void game(); void InitBoard(char board[ROWS][COLS], int rows, int cols, 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); int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y); int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y); int judge(char mine[ROWS][COLS], char show[ROWS][COLS]); #endif // !__HEAD_H__
#include"head.h"
void game() {
// 雷的信息存储
// 1. 布置好的雷的信息
char mine[ROWS][COLS] = { 0 };
// 2. 排查雷的信息
char show[ROWS][COLS] = { 0 };
// 初始化
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
// 打印棋盘
//DisplayBoard(mine, ROW, COL);
// 布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
// 扫雷
FindMine(mine,show,ROW,COL);
}
void InitBoard(char board[ROWS][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;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
for (int i = 0; i <= row; i++) {
printf(" %d ",i);
if(i < row)
printf("|");
}
printf("n");
for (int i = 0; i <= row; i++) {
printf("---");
if (i < row)
printf("|");
}
printf("n");
for (int i = 1; i <= row; i++) {
printf(" %d |", i);
for(int j = 1; j <= col; j++) {
printf(" %c ", board[i][j]);
if (j < col) {
printf("|");
}
}
printf("n");
if (i < row) {
for (int j = 0; j <= row; j++) {
printf("---");
if (j < row)
printf("|");
}
printf("n");
}
}
printf("n");
}
void SetMine(char board[ROWS][COLS], int row, int col) {
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--;
}
}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
int x = 0;
int y = 0;
int ck = 0;
char ch = ' ';
while (1) {
DisplayBoard(show, ROW, COL);
printf("-----------------------n");
printf("--> p. 排雷 n");
printf("--> b. 标记 n");
printf("--> e. 标记完成 n");
printf("-----------------------nn");
Flag:
printf("请输入您的操作: ");
getchar();
scanf("%c", &ch);
switch (ch)
{
case 'p':
{ P_1:
printf("请输入坐标: ");
scanf("%d", &x);
scanf("%d", &y);
if (x <= row && x >= 1 && y <= col && y >= 1) {
if (mine[x][y] == '1') // 踩雷
{
system("cls");
printf("nT_T T_T T_T T_T T_T T_Tn");
printf("很遗憾,你被炸死了!!!n");
printf("T_T T_T T_T T_T T_T T_Tnn");
DisplayBoard(mine, ROW, COL);
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
else // 不是雷
{
// 计算x,y 周围有几个雷?
get_mine_count(mine, show, x, y);
//DisplayBoard(show, ROW, COL);
system("cls");
}
}
else
{
printf("您输入坐标有误, 请重新输入^_^n");
goto P_1;
}
}
break;
case 'b':
{ B_1:
printf("请输入坐标: ");
scanf("%d", &x);
scanf("%d", &y);
if (x <= row && x >= 1 && y <= col && y >= 1) {
MarkMine(mine, show, x, y);
system("cls");
}
else
{
printf("您输入坐标有误, 请重新输入^_^n");
goto B_1;
}
}
break;
case 'e':
// 检查玩家的扫雷状态
ck = judge(mine, show);
if (ck == 1) {
system("cls");
printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
printf("恭喜你,扫雷完成!!!n");
printf("^_^^_^^_^^_^^_^^_^^_^^_^n");
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
else
{
system("cls");
printf("nT_T T_T T_T T_T T_T T_Tn");
printf("很遗憾,扫雷失败!!!n");
printf("T_T T_T T_T T_T T_T T_Tnnn");
DisplayBoard(mine, ROW, COL);
printf("nn按任意键结束!nn");
getchar();
getchar();
system("cls");
goto End;
}
break;
default:
printf("您输入操作有误, 请重新输入^_^n");
goto Flag;
break;
}
}
End:
;
}
// 展开功能的实现,递归
int get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
if (x <= ROW && x >= 1 && y <= COL && y >= 1)
{
if (show[x][y] == ' ')
{
return 0;
}
int n = mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x - 1][y + 1] +
mine[x][y - 1] +
mine[x][y + 1] +
mine[x + 1][y] +
mine[x + 1][y - 1] +
mine[x + 1][y + 1] - 8 * '0';
if (n == 0) {
show[x][y] = ' ';
get_mine_count(mine, show, x - 1, y);
get_mine_count(mine, show, x-1, y-1);
get_mine_count(mine, show, x-1, y+1);
get_mine_count(mine, show, x, y-1);
get_mine_count(mine, show, x, y+1);
get_mine_count(mine, show, x+1, y);
get_mine_count(mine, show, x+1, y-1);
get_mine_count(mine, show, x+1, y+1);
}
else
{
show[x][y] = '0' + n;
return 0;
}
}
return 0;
}
int MarkMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
if (show[x][y] == '$') {
show[x][y] = '*';
}
else
{
show[x][y] = '$';
}
return 0;
}
int judge(char mine[ROWS][COLS], char show[ROWS][COLS]) {
int count = 0;
for (int i = 1; i <= ROW; i++) {
for (int j = 1; j <= COL; j++) {
if (show[i][j] == '$') {
if (mine[i][j] == '1') {
count++;
}
}
}
}
if (count == EASY_COUNT) {
return 1;
}
return 0;
}
3. main.c
#include "head.h"
void menu() {
printf("*************************n");
printf("****** 1. play *****n");
printf("****** 0. exit *****n");
printf("*************************nn");
}
void test() {
int input = 0;
srand((unsigned int)time(NULL));
menu();
do
{
printf("请输入你的选择:");
scanf("%d", &input);
switch (input)
{
case 1:
system("cls");
game();
menu();
break;
case 0:
break;
default:
printf("您的输入有误,请重新输入");
Sleep(200);
system("cls");
menu();
break;
}
} while (input);
system("cls");
printf("欢迎下次使用!!!nn");
Sleep(300);
}
int main() {
test();
return 0;
}
五、游戏演示
1. 菜单界面
2. 游戏界面
3. 完成界面



