当前位置:网站首页>用C语言来实现扫雷小游戏
用C语言来实现扫雷小游戏
2022-08-03 05:11:00 【一个隐藏的大佬】
文章目录
前言
这是我第三次写博客,应该能比前两次写的更成熟一点,写的更好一点。
一、扫雷的准备工作
我们还是一样,在写一个项目之前,先规划好创建哪些文件,我一般会分三个模块来写:
- game.h(用来存放头文件,符号常量,还有事先声明要实现的函数)
- game.c(用来存放我们函数具体实现代码)
- test.c(用来测试我们的逻辑)
二、扫雷的具体实现过程
1.分析
在写一个项目之前,一定要分析好这个项目要具体实现哪些功能,要怎么实现,用什么东西来实现,这是我们写代码之前都要分析的东西。我给扫雷定义了四个函数还有一些符号常量:
#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 EASY_COUNT 10 //初始化 void board_init(char arr[ROWS][COLS], int row, int col, char set); //打印 void board_display(char arr[ROWS][COLS], int row, int col); //设置雷 void set_mine(char arr[ROWS][COLS], int row, int col); //找雷 void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
在实现这些函数之前,我们先看看扫雷长什么样,是怎么玩起来的




首先他是由一块9*9的棋盘组成的,最开始全部都是方块,然后我们每点一下,就会出来个数字,这个数字就是用来统计周围8个格子里有几个雷,如果周围8个格子里有一个雷,那么就会在刚刚点的那个格子里显示1,如果我们不小心踩到雷,那么我们就输了,如果我们把所有雷都排除掉,那么我们就赢了,大致逻辑就是这样。
2.实现过程
2.1 初始化
首先我们还是要定义一块棋盘,毕竟我们是用C语言写的,可能写的没上面好看,但是还是要考虑一些其他因素,我们还是采用下标的方式来让玩家实现排雷,但是采用下标就要考虑好几点,首先玩家输入的下标是不是有可能会越界,如果这个下标是合法的,但偏偏是在最边界的位置,那我们在统计周围8个格子是否有雷的情况下,肯定会造成数组下标越界,如果还要一个个判断就太麻烦了,所以我们干脆把棋盘设置成11*11,然后我们只用里面9*9的格子,这样无论玩家怎么下,都不会出现越界的情况,但是我们还要想到的一点就是如何把统计雷的信息展示给玩家看,如果我只设计一个棋盘,然后里面随机放雷,有雷位置都为1,没有雷的位置都为0,那在我们统计周围雷的时候可能会产生歧义,如果周围有1个雷的话,那统计出来的数字就是1,那么这个1到底是雷,还是什么呢?所以我们干脆设计两个棋盘,一个用来存放我们的雷,另一个用来展示给玩家看,玩家随机输入一个坐标,然后我们统计周围八个格子里有几颗雷,把统计到的信息放置到展示的棋盘里面,这样就不会产生歧义,玩家也可以正常排雷了,情况分析完毕之后,具体就是实现代码了,我给第一个棋盘叫mine用来存放雷,一开始我全部初始化为0,另一个棋盘叫show用来展示,一开始我全部初始化为*(星号)。

这就是我们定义的两个棋盘,然后我们都初始化好了,然后我写了一些行号和列号,为了方便给玩家看,打印的函数我就不讲了,遍历一遍就好了,下面是初始化和打印的代码:
//初始化 void board_init(char arr[ROWS][COLS], int row, int col, char set) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { arr[i][j] = set; } } } //打印 void board_display(char arr[ROWS][COLS], int row, int col) { int i = 0; int j = 0; //列号 for (j = 0; 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 ", arr[i][j]); } printf("\n"); } }
2.2 布置雷
棋盘我们已经做好了,剩下就是布置雷和排雷了,布置雷的逻辑很简单,就在9*9的格子里,随机放置雷,有雷的位子,我们放1进去,没有雷就全都是0,这样的好处是什么呢?好处就是到时候统计雷,我们只需要把周围8个格子一加,我就知道周围有几颗雷了。说到随机放雷,大家肯定都能想到rand()函数,可以给我们一个随机值,只要让他%(取模)9,就可以得到0-9之间的数字,但是不包括9,所以我们还需要+1,这样就能得到1-9之间的数字。但是大家别忘了,在调用rand()函数之前,还要调用srand()函数,要不然你每次得到的随机数都是一样的,每次布置雷的位置也都是一样的,这样玩家就没有游戏乐趣了。剩下就是判断,看这个格子是不是0,如果是0,则放雷,如果不是,则重新获取随机数,直到所有雷都放完了,这个函数就结束了。代码如下:
//设置雷 void set_mine(char arr[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (arr[x][y] == '0') { arr[x][y] = '1'; count--; } } }
效果如下:

2.3 排雷
雷已经全部布置好了,就剩下让玩家排雷了,我们首先对玩家下标进行检查,看有没有越界,如果越界则重新输入,第二步就是看玩家下标是不是同一个位置,就是一个位置玩家已经检查过了,然后玩家故意想重新检查一遍,遇到这种情况肯定要重新输入,如果以上都通过了,那就看玩家输入的坐标是不是雷,如果是雷就输了,不是雷就要算周围8个格子里有几颗雷,这里就很好算了,因为有雷的位置就是1,没有雷的位置就是0,直接全部加起来,然后算出总数,把总数放入到展示的棋盘里面,这样玩家就能看到周围有几颗雷了,并且设置一个变量(win),玩家每找出一个不是雷的位置,变量(win)就加1,直到变量(win)==9*9-10,就说明玩家赢了,因为玩家找出了所有不是雷的位置,剩下十个位置都是雷。整个排雷的逻辑就是这样,代码如下:
//算周围8个格子有几颗雷 int get_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 < row * col - EASY_COUNT) { 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"); board_display(mine, ROW, COL); break; } else { int ret = get_count(mine, x, y); show[x][y] = ret + '0'; board_display(show, ROW, COL); win++; } } else { printf("坐标已被排查过,请重新输入\n"); } } else { printf("输入坐标不合法,请重新输入\n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你排雷成功,游戏胜利\n"); board_display(mine, ROW, COL); } }
效果如下:

这里为了测试,我特地把雷的数量设置成80,然后把藏有雷的mine棋盘也同时打印出来了,最后测试结果正如我们所想的一样,并且其他逻辑也正常,我就不一一截图了,你们想测试的话,可以去码云上下载玩一玩,我会把链接放在下方。
总结
这两个游戏算是我学这么多天的一点回报吧!学以致用真的很快乐!希望大家大力支持,我会继续努力的。
链接:https://gitee.com/smnhaaa/c-project.git
边栏推荐
猜你喜欢
随机推荐
【Flask】Flask-SQLAlchemy的增删改查(CRUD)操作
vim命令
-整数求和-
celery工作原理图
力扣561. 数组拆分
背压机制
Build your own web page on raspberry pie (1)
Gradle的安装配置
飞机大战完整版
【转】最小描述长度准则MDL(Minimun Description Length)
【打印菱形】
VSO Downloader Ultimate 5.0.1.45 中文多语免费版 在线视频下载工具
1054 求平均值 (20 分)
UV decomposition of biotin - PEG2 - azide | CAS: 1192802-98-4 biotin connectors
对角矩阵(diagonal matrix)
如何不耍流氓的做运维之-SHELL脚本
Apache DolphinScheduler版本2.0.5分布式集群的安装
Djiango第三次培训
-一尺之棰-
User password verification









