- 前言
- 1.扫雷思路
- 2.扫雷代码实现
- 2.1主函数构建:
- 2.2 初始化扫雷棋盘
- 2.3随机布置雷
- 2.4扫雷
- 扫雷总代码
- 总结
✨✨✨学习的道路很枯燥,希望我们能并肩走下来!
编程真是一件很奇妙的东西。你只是浅尝辄止,那么只会觉得枯燥乏味,像对待任务似的应付它。但你如果深入探索,就会发现其中的奇妙,了解许多所不知道的原理。知识的力量让你沉醉,甘愿深陷其中并发现宝藏。
前言
| 本篇通过扫雷小游戏,加强对循环,选择,分支的练习,对于初学者小游戏能提高我们的兴趣,让我们一起操作起来吧!如有错误,请在评论区指正,让我们一起交流,共同进步! |
本文开始
扫雷这个大家所熟知的小游戏,你是否玩过呢,他是你记忆中的一部分?
今天让我们来实操一下,如何用代码写出简单的扫雷,这里的扫雷,不能像真正的扫雷一样,只是大概思路相同,简单编写一个10个雷的简易模式,如果想让扫雷更加真实,请根据这篇文章,自我思考,自己编写一下吧!
让我们先从 扫雷棋盘的格式 入手:
扫雷的区域构建肯定需要用到二维数组,但怎么考虑呢?
对于9*9的扫雷棋盘我们构建完够用吗?
构建扫雷棋盘我们还应该考虑到对于你选定的位置周围的8个方格如何计算,方格数是否满足?
我们通过以下图片来分析一下.
如何构建扫雷棋盘
对于黑方块所选内容为正常我们需考虑的,使用二维数组对于 红方块内容,则是会 出现越界访问的问题,如何解决呢,这里需要我们主动设置一个更大的扫雷棋盘,满足我们的要求.
需要 9 * 9 扫雷棋盘 --> 9 * 9的二维数组 -->考虑用11*11扫雷棋盘 (如图外层绿色方框)
放置雷,如何安放呢,怎么更好统计呢?
设置两个扫雷棋盘
①这里使用会使用两个扫雷棋盘(两个数组),一个mine数组用来放置雷信息,一个show数组用来放置排查出雷的信息
②开始设置:mine数组(设计者自己观察调整的扫雷棋盘)全初始化 ’0‘,布置为雷时改为 ’1‘;show数组(玩家观看)全初始化为 ’*‘,排雷后,玩家输入的位置改为数字字符(8个方格有几个雷),如:’3‘;
这里会有小伙伴问为什么用两个扫雷棋盘?
如果只有一个扫雷棋盘,计算出玩家所在周围有1个雷,会与开始放置的雷(1为雷)所重复,没法判断是雷(1),还是所处位置周围的雷(1);
为什么不用 *,#直接在一个棋盘表示?
2.扫雷代码实现对于扫雷代码,我们一般不放在一个.c文件下,会显得思路不够简洁,代码整体太乱!
所以我们一般分为三个:
①text.c 扫雷游戏的测试逻辑
②game.h 游戏函数的声明
③game.c 游戏函数的实现
先构建扫雷游戏的测试逻辑
2.1主函数构建:制作简易菜单(menu);选择输入是否开始游戏(switch);设置游戏循环条件(do while)
#include"game.h"
void menu()
{
printf("**********************n");
printf("******* 1.play ******n");
printf("******* 0.exit ******n");
printf("***********************n");
}
void game()
{
printf("扫雷n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择(0/1):>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏n");
break;
default :
printf("输入错误,请重新输入n");
break;
}
} while (input);
return 0;
}
当我们构建完主函数,接下来主要构建game()函数
game():
①创建扫雷棋盘
②初始化扫雷棋盘
③布雷
④排雷
[注]由于怕越界,创建扫雷棋盘都以11*11创建
初始化两个扫雷棋盘除了初始化内容不同,其他代码相同,为了使代码简便,我们只把需要初始化的参数传给函数即可,简化了代码
#include"game.h"
void init_board(char board[ROWS][COLS], int rows, int cols,int ret)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
//只需所要的初始化的值传过来就行
mine[i][j] = ret;
}
}
}
//打印扫雷棋盘
void display_board(char mine[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("%c ", mine[i][j]);
}
printf("n");
}
}
开始打印扫雷棋盘:
扫雷棋盘虽然创建好了,但是不容易看每行坐标,我么来加上序号看一下!
扫雷棋盘优化:
- 打印扫雷棋盘时先打印一行从0-9
再打印数据时,每一行前面打印 i (i从1-9)
形成类似坐标的样子方便观察
#include"game.h"
void display_board(char board[ROWS][COLS], int row, int col)
{
//row--行,col--列
int i = 0;
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("n");
for (i = 1; i <= row; i++)
{
int j = 0;
//打印数据开始,先打印每一行行号1-9
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("n");
}
}
代码结果:
2.3随机布置雷
这里用到之前文章讲的随机函数,产生随机值
rand(),srand(),time();
如果不了解随机值的产生,可以点开这篇文章看一下哦!
猜数字游戏里关于rand,srand的使用说明
[注]
- 这里利用全局变量EASY_COUNT来控制布雷数量,如果想更改雷的数量,可以改变全局变量,来改变程序中的雷的数量(一改所有EASY_COUNT都改)
- 这为了让电脑产生的随机值在1-9范围内,我们需要rand()%row,rand()%col,获取0-8以内的值,再+1获得1-9以内的值
代码示范:
void set_mine(char mine[ROWS][COLS], int row, int col)
{
//布置10个雷
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;
//本来余9是得到0-8的数,+1是得到1-9的数,正好与设置的序号对应
int y = rand() & col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
2.4扫雷
这是玩家所能操作的棋盘,需要玩家输入位置,就开始了扫雷
[注]
- 扫雷游戏结束范围,找到所以不是雷的位置,游戏结束
例如:以9 * 9扫雷棋盘为例,想要全部扫完雷,需要找到9 * 9(所有方格范围)-10(雷的个数)=71()不是雷的个数 - 玩家输入扫雷范围满足:
①输入范围满足扫雷区域 (1<=x<=9,1<=y<=9)
②输入位置没有重复
③输入位置没有雷 - 扫雷返回值的计算
代码示范:
int get_mine_count(char mine[ROWS][COLS],int x,int y)
{
return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1]
+ mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1]-8*'0');
}
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
printf("请输入坐标:> ");
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");
display_board(mine, ROW, COL);
break;
}
else
{
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';
//show中需要存字符数字,需要加上'0'字符0,如:'a'+2=‘c'
display_board(show, ROW, COL);
win++;
}
}
else
{
printf("该坐标已经被排除过了n");
}
}
else
{
printf("坐标超出范围,请重新输入n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功n");
display_board(mine, ROW, COL);
}
}
扫雷总代码
//game.h #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 80 #include总结#include #include //初始化 void init_board(char board[ROWS][COLS], int rows, int cols,int ret); //打印 void display_board(char board[ROWS][COLS], int row, int col); //布雷 void set_mine(char mine[ROWS][COLS], int row, int col); //排雷 void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); //text.c //#include"game.h" void menu() { printf("**********************n"); printf("******* 1.play ******n"); printf("******* 0.exit ******n"); printf("**********************n"); } void game() { //printf("扫雷n"); //创建布雷区域 char mine[ROWS][COLS] = { 0 }; //创建显示雷有几个的棋盘--玩家眼中的区域 char show[ROWS][COLS] = { 0 }; //初始化雷区域全为字符0,‘0’ //如何定义一个函数让两个全部初始化,只需要把初始化的内容传参传过去,就可以不要重复写一样的代码了 init_board(mine, ROWS, COLS, '0'); //display_board(mine, ROW, COL); //打印发现这样不容易观看,我们可以考虑为它们打印序号 //初始化扫雷区域为‘*’ init_board(show, ROWS, COLS, '*'); //display_board(show, ROW, COL); //布雷 set_mine(mine, ROW, COL); display_board(mine, ROW, COL); //排雷 display_board(show, ROW, COL); find_mine(mine,show, ROW, COL); } int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择(0/1):>"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏n"); break; default: printf("输入错误,请重新输入n"); break; } } while (input); return 0; } //game,c //#include"game.h" void init_board(char board[ROWS][COLS], int rows, int cols, int ret) { int i = 0; for (i = 0; i < rows; i++) { int j = 0; for (j = 0; j < cols; j++) { board[i][j] = ret; } } } void display_board(char board[ROWS][COLS], int row, int col) { int i = 0; for (i = 0; i <= row; i++) { printf("%d ", i); } printf("n"); for (i = 1; i <= row; i++) { int j = 0; //打印数据开始,先打印每一行行号1-9 printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("n"); } } void set_mine(char mine[ROWS][COLS], int row, int col) { //布置10个雷 int count = EASY_COUNT; while (count) { int x = rand() % row + 1;//本来余9是得到0-8的数,+1是得到1-9的数,正好与设置的序号对应 int y = rand() & col + 1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } int get_mine_count(char mine[ROWS][COLS],int x,int y) { return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1]-8*'0'); } 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 printf("请输入坐标:> "); 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"); display_board(mine, ROW, COL); break; } else { int count = get_mine_count(mine, x, y); show[x][y] = count + '0';//show中需要存字符数字,需要加上'0'字符0,'a'+2=‘c' display_board(show, ROW, COL); win++; } } else { printf("该坐标已经被排除过了n"); } } else { printf("坐标超出范围,请重新输入n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功n"); display_board(mine, ROW, COL); } }
✨✨✨各位读友,本篇分享到内容是否更好的让你理解了扫雷小游戏的乐趣,让你对代码的兴趣有了提升呢?如果文章对你有帮助希望给个赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!



