当前位置:网站首页>C语言实现扫雷游戏
C语言实现扫雷游戏
2022-08-11 05:30:00 【CHAKMING1】
目录
一、问题描述
首先,再写这个游戏之前,我们要知道这个游戏是怎么玩的,扫雷是一个n*n的区域内,放入一定数量的雷,这些雷是隐藏起来的,那么玩家就是通过点击隐藏的区域一步一步的猜测雷可能放置的位置,将所有不是雷的区域排查出去。那么,要怎么知道一个区域有没有可能是雷呢?扫雷这个游戏,会将非雷区的数字改为周围的八个位置累的总数显示出来,那么玩家胜利的条件就是通过知道周围雷的个数,一步一步筛选,最终达到游戏胜利。
二、问题拆解
1.创建一个游戏基本的菜单
2.创建一个存放雷的区域以及排查雷的区域
3.对这两个区域进行初始化
4.展示雷区给玩家
5.布置雷到雷区
6.玩家进行排查雷
7.设计一个总方案
三、代码实现
1.游戏基本菜单
void menu()
{
printf("*************************\n");
printf("******* 1.play ********\n");
printf("******* 0.exit ********\n");
printf("*************************\n");
}
void test()
{
int input = 0;
// 菜单
do {
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出成功\n");
break;
default:
printf("输入错误,请按照规定范围输入\n");
break;
}
} while (input);
}
2.创建一个雷的区域和排查雷的区域
为了实现方便,我们创建了两个二维数组,mine数组单单只是存放雷的情况,如果当前位置有雷则输出‘0’,否则输出'1',注意我这里是字符,然后show数组,是展示给玩家看的,如果这个地方玩家未排查,则显示'*',如果已排查,会显示周围雷的个数。
注意:
1. 这里创建一个行和列为11的数组原因是为了不用计算角落周围雷的总数,而产生越界的情况。
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
// mine数组是用来存放雷的信息
char mine[ROWS][COLS] = { 0 };
// show数组是用来存放排查雷的信息
char show[ROWS][COLS] = { 0 };
3.对这两个区域进行初始化
这一步是为了将两个棋盘进行初始化,mine数组存放字符0,show数组存放字符*。
// 初始化
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*'); // *代表未知
// 初始化棋盘
void init_board(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i, j;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
arr[i][j] = set;
}
}
}
4.展示雷区给玩家
这一步骤可以直接理解为打印棋盘,在打印棋盘的时候,最好将行和列的序号也一并打印,这样为了能让玩家更好的找到相应的位置。
// 打印棋盘
void Print_board(char arr[ROWS][COLS], int row, int col)
{
int i, j;
printf("--------------------\n");
for (i = 0; i <= row; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
printf("--------------------\n");
}
5.布置雷到雷区
这一步是进行随机将雷放在不同位置上,所以这里引用了rand的函数,那么为了能够让rand函数产生随机值,就必须用一个srand函数设置,参考下面用法。
//必须写在main函数中
srand((unsigned int)time(NULL));
// 布置雷
void Set_mine(char mine[ROWS][COLS], int row, int col)
{
// 设置坐标
int x = 0;
int y = 0;
int count = EASY_COUNT;
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
6.玩家进行排查雷
这一步骤其实将玩家输入、获取周围雷的总数以及胜利条件一并写入,玩家在进行输出的时候,可以判断当前mine数组的位置是不是雷,如果是雷,则游戏失败,如果当前以及将所有非雷位置排除,则游戏胜利。
那么获得周围雷的个数,首先得判断这个范围在哪,行的范围是(x-1)~(x+1),列的范围是(y-1)~(y+1),那么我们在进入这个函数之前,其实就能知道当前位置肯定是非雷区,那么就不用把当前位置排除。
#define EASY_COUNT 10 // 难度设置
// 获取当前坐标周围雷的数量
int get_mine_number(char mine[ROWS][COLS], int row, int col)
{
int i, j;
int sum = 0;
for (i = row - 1; i <= row + 1; i++)
{
for (j = col - 1; j <= col + 1; j++)
{
// 首先当前位置肯定不是雷,这个循环就不用判断当前位置,其他位置只要为1则雷的个数加一
if (mine[i][j] == '1')
sum++;
}
}
return sum;
}
// 排查雷
void Find_mine(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);
// 判断输入合法性
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
// 当前位置是炸弹,说明已经失败了,退出游戏
if (mine[x][y] == '1')
{
printf("很遗憾,您被炸没了\n");
Print_board(mine, ROW, COL);
break;
}
else
{
int count = get_mine_number(mine, x, y);
show[x][y] = '0' + count;
Print_board(show, ROW, COL);
}
}
else
printf("您的输入超出范围,请重新输入\n");
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,获得游戏胜利\n");
Print_board(mine, ROW, COL);
}
}
7.设计一个总方案
void game()
{
// 扫雷游戏的实现
// mine数组是用来存放雷的信息
char mine[ROWS][COLS] = { 0 };
// show数组是用来存放排查雷的信息
char show[ROWS][COLS] = { 0 };
// 初始化
init_board(mine, ROWS, COLS, '0');
init_board(show, ROWS, COLS, '*'); // *代表未知
// 打印棋盘
//Print_board(mine, ROW, COL);
Print_board(show, ROW, COL);
//设置雷
Set_mine(mine, ROW, COL);
//排查雷
Find_mine(mine, show, ROW, COL);
}
四、总结
以上就是代码的所有实现,我是创建了三个文件(其中一个为头文件),头文件负责对函数进行声明以及定义一些常量和头文件,另外两个文件,一个文件为game.c,是负责存放函数的实现方式,另一个文件为test.c,是存放一些简单功能和主函数的位置。这样写,有利于区分每个文件所要实现什么样的功能,也能够更加明确。
边栏推荐
- js常用方法对象及属性
- 贡献者任务第三期精彩来袭
- 第一章 Verilog语言和Vivado初步使用
- swagger错误:WARN i.s.m.p.AbstractSerializableParameter - [getExample,421] - Illegal DefaultValue null
- 第四范式OpenMLDB优化创新论文被国际数据库顶会VLDB录用
- 深度学习Matlab工具箱代码注释
- Day 75
- 无效的修订:3.18.1-g262b901-dirty
- Intelligent risk control China design and fall to the ground
- js学习进阶BOM部分(pink老师笔记)
猜你喜欢
The official website of OpenMLDB is upgraded, and the mysterious contributor map will take you to advance quickly
本地缓存cookie的使用
将一个excel文件中多个sheet页“拆分“成多个“独立“excel文件
js 学习进阶(事件高级 pink老师教学笔记)
Day 85
论文解读TransFG: A Transformer Architecture for Fine-grained Recognition
微信小程序云开发项目wx-store代码详解
星盟-pwn-babyheap
父子节点数据格式不一致的树状列表实现
Day 84
随机推荐
mk file introduction
星盟-pwn-babyheap
Day 68
JS小技巧,让你编码效率杠杠的,快乐摸鱼
Tinker接入全流程---编译篇
Day 75
2021年vscode终端设置为bash模式
OpenMLDB Pulsar Connector: Efficiently connect real-time data to feature engineering
mysql basic summary
贡献者任务第三期精彩来袭
OpenMLDB Meetup No.2 会议纪要
PyQt5中调用.ui转换的.py文件代码解释
The role of the port
Day 70
Day 79
Jetpack's dataBinding
深度学习Matlab工具箱代码注释
C语言实现简易扫雷(附带源码)
Use the adb command to manage applications
场景驱动的特征计算方式OpenMLDB,高效实现“现算先用”