Loading... [http://wp.fivk.cn/saolei.mp4](http://wp.fivk.cn/saolei.mp4) [文件下载](https://wp.fivk.cn/%E6%89%AB%E9%9B%B7.zip) ## 一、基本框架 初始代码,用二维数组。 ```c #include<stdio.h> #define ROW 10 //行 #define COL 10 //列 int map[ROW][COL]; //数组的初始化函数 void GameInit() { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%d ", map[i][j]); } printf("\n"); } } int main() { GameInit(); GameDraw(); printf("版权:贵州师范20大数据\n"); return 0; } ``` <div class='album_block'> [album type="photos"] ![code](https://blog.fivk.cn/usr/uploads/2021/06/2917014622.png) ![debug](https://blog.fivk.cn/usr/uploads/2021/06/4075591017.png) [/album] </div> 我们初始化 ```c srand((unsigned)time(NULL)); ``` 是初始化随机函数种子: 1. 拿当前系统时间作为种子,由于时间是变化的,种子也在变化,可以产生随机数。计算机中的随机数实际上都不是真正的随机数,如果两次给的种子一样,则会生成相同的随机序列。 所以,一般都会以当前的时间作为种子来生成随机数,这样更加的随机。 2. 使用时,参数可以是unsigned型的任意数据,比如srand(10); 3. 如果不使用srand,用rand()产生的随机数,在**多次运行**,结果是一样的。 <div class="tip inlineBlock success"> 我们用随机数布局雷。 </div> ## 二、布雷的操作 ```c void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } } ``` ![布雷](https://blog.fivk.cn/usr/uploads/2021/06/517489194.png) <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-f0b5202a27481542c15cba44106dd3a8100" aria-expanded="true"><div class="accordion-toggle"><span style="">存档1</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-f0b5202a27481542c15cba44106dd3a8100" class="collapse collapse-content"><p></p> ```c #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 int map[ROW][COL]; //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%d ", map[i][j]); } printf("\n"); } } int main() { GameInit(); GameDraw(); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> ## 三、判断周围雷 判断周围雷时,我们可能会遇到数组越界,因为到边界的时候判断8个方向。 <div class="tip inlineBlock success"> 根据雷的分布区填充其他不为零的数据的两个方法。 </div> * 方案一: ![](https://blog.fivk.cn/usr/uploads/2021/06/1388653844.png) 看图不解释了,学过C语言的人100%懂。不解释 * 方案二: 可惜了方案一这么简单的一个方法,哎这人啊,有时候就是有点固执,没办法,我就想判断数组是否越界。 ```c const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } ``` <div class="tip inlineBlock warning"> 我的思路是用dx,dy数组控制方向,x,y是位置。就是回溯经常用的那个方法。 </div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-dc7df9cc0a2dd116a0f3366975f091cd55" aria-expanded="true"><div class="accordion-toggle"><span style="">存档2</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-dc7df9cc0a2dd116a0f3366975f091cd55" class="collapse collapse-content"><p></p> ```c #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 int map[ROW][COL]; //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); } printf("\n"); } } int main() { GameInit(); GameDraw(); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> ## 四、添加图像 ### graphics.h 的下载及安装: [https://www.easyx.cn/downloads/](https://https://www.easyx.cn/downloads/) 下载EasyX库(附带graphics.h) 下载后运行即可。 <div class='album_block'> [album type="photos"] ![](https://blog.fivk.cn/usr/uploads/2021/06/3812734351.png) ![](https://blog.fivk.cn/usr/uploads/2021/06/1940992231.png) [/album] </div> 这里小白都会了吧。 现在我们就可以使用graphics.h做图形了。 注意必须要安装EasyX库,因为编译器默认是没有EasyX库的。 <div class="tip inlineBlock warning"> 注意,这里有一个魔鬼细节,我们文件后缀要改为cpp,应为EasyX库是用c++实现的,要不然会报错。(太坑了) </div> ![](https://blog.fivk.cn/usr/uploads/2021/06/109417924.png) ### 给图片赋值 ```cpp loadimage(&img[0], L"0.jpg", SIZE, SIZE); loadimage(&img[1], L"1.jpg", SIZE, SIZE); loadimage(&img[2], L"2.jpg", SIZE, SIZE); loadimage(&img[3], L"3.jpg", SIZE, SIZE); loadimage(&img[4], L"4.jpg", SIZE, SIZE); loadimage(&img[5], L"5.jpg", SIZE, SIZE); loadimage(&img[6], L"6.jpg", SIZE, SIZE); loadimage(&img[7], L"7.jpg", SIZE, SIZE); loadimage(&img[8], L"8.jpg", SIZE, SIZE); loadimage(&img[9], L"9.jpg", SIZE, SIZE); loadimage(&img[10], L"10.jpg", SIZE, SIZE); loadimage(&img[11], L"11.jpg", SIZE, SIZE); ``` > 格式是:数组,图片,宽,高 **如果用了上面的方法下面的可以不看,实现的东西都是一样的。** **可以直接到下一个节 "给图片赋值"** **读者嫌麻烦可以 break** 但是,哎,不想多说,发现了问题不解决人啊,心里过不去,,就一直想搞,你说是吧 就是感觉这样太多了,我去问了以下万能的群友,果然有简便的方法,牛啊 <div class='album_block'> [album type="photos"] ![1.png](https://blog.fivk.cn/usr/uploads/2021/06/3747228010.png) ![2.png](https://blog.fivk.cn/usr/uploads/2021/06/3566545588.png) ![3.png](https://blog.fivk.cn/usr/uploads/2021/06/4060159043.png) ![4.png](https://blog.fivk.cn/usr/uploads/2021/06/1140869199.png) [/album] </div> ```cpp std::wstring image_url; for (int count = 0; count < 12; count++) { image_url = std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } ``` 勉强可以看懂std::是命名空间,对了wstring内容在string函数里面,需要包含#include< string > 刚刚那个大佬说让我改一下,下面是我改的。我想吧图片放到image下但是根据上面那大佬的方法只能放到当前目录。 <div class='album_block'> [album type="photos"] ![5.png](https://blog.fivk.cn/usr/uploads/2021/06/1836394130.png) ![6.png](https://blog.fivk.cn/usr/uploads/2021/06/1298204035.png) ![7.png](https://blog.fivk.cn/usr/uploads/2021/06/818223798.png) ![8.png](https://blog.fivk.cn/usr/uploads/2021/06/621014584.png) [/album] </div> 真的是我一点一点试出来的qvq现在都凌晨1点了。。。 ```cpp std::wstring image_url; for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } ``` <div class="tip inlineBlock success"> 除了获取数字其他的部分都为 L" const char* " 看似简单实则我想了很久很久,不过现在挺开心的^_^ </div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-f8548271a4e0d107d8b74ae3b080506137" aria-expanded="true"><div class="accordion-toggle"><span style="">存档3</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-f8548271a4e0d107d8b74ae3b080506137" class="collapse collapse-content"><p></p> ```cpp #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); } printf("\n"); } } int main() { std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ GameInit(); GameDraw(); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> ### 贴图片输出 ```cpp putimage(坐标x, 坐标y, 图片地址); ``` ```cpp //绘制函数 (打印二维数组中所有的元素) void GameDraw() { //参数:putimage(坐标x,坐标y,图的地址) /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); if (map[i][j] == -1) { //贴出雷的图片 putimage(j * SIZE, i * SIZE, &img[9]); } else if (map[i][j] >= 0 && map[i][j] <= 8) { //贴出数字图片 //map[i][j]的值刚好对应数字 putimage(j * SIZE, i * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //贴出空白图片 putimage(j * SIZE, i * SIZE, &img[10]); } else if (map[i][j] >= 30) { //贴出标记图片 putimage(j * SIZE, i * SIZE, &img[11]); } } printf("\n"); } } ``` ### 写控制台图像界面 ```cpp initgraph(行,列, SHOWCONSOLE); //SHOWCONSOLE 是控制台 ``` <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-bbdf3bc35fe76e9f806d5ebc94a6cc2242" aria-expanded="true"><div class="accordion-toggle"><span style="">存档4</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-bbdf3bc35fe76e9f806d5ebc94a6cc2242" class="collapse collapse-content"><p></p> ```cpp #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { //参数:putimage(坐标x,坐标y,图的地址) /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); if (map[i][j] == -1) { //贴出雷的图片 putimage(j * SIZE, i * SIZE, &img[9]); } else if (map[i][j] >= 0 && map[i][j] <= 8) { //贴出数字图片 //map[i][j]的值刚好对应数字 putimage(j * SIZE, i * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //贴出空白图片 putimage(j * SIZE, i * SIZE, &img[10]); } else if (map[i][j] >= 30) { //贴出标记图片 putimage(j * SIZE, i * SIZE, &img[11]); } } printf("\n"); } } int main() { initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE); std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ GameInit(); GameDraw(); while (1); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> 这样我们就得到了两个窗口,一个是控制台窗口,一个是游戏的窗口。 ![终于有点样子了.png](https://blog.fivk.cn/usr/uploads/2021/06/2757105810.png) 当然,玩扫雷的时候肯定不是这个样子的,这只是先看看效果。 ## 五、游戏加密 我们玩扫雷的时候最开始根本不知到那个是雷,所以我们要进行加密。 **加密策略:** | 元素 | 对应图片 | 加密操作 | 加密结果 | | -------- | ---------- | ---------- | ---------- | | 0-8 | img[0-8] | +20 | 20-8 | | -1 | img[9] | +20 | 19 | | 19-28 | img[10] | —— | —— | | 大于30 | img[11] | —— | —— | ![加密操作.png](https://blog.fivk.cn/usr/uploads/2021/06/451094328.png) ![对应图片.png](https://blog.fivk.cn/usr/uploads/2021/06/2809224571.png) 加密后我们在游戏界面就不知道哪里会有雷了。这是游戏的初始化 ![加密后.png](https://blog.fivk.cn/usr/uploads/2021/06/2806593804.png) <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-365c192452818e1daf06bd623f36e47315" aria-expanded="true"><div class="accordion-toggle"><span style="">存档5</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-365c192452818e1daf06bd623f36e47315" class="collapse collapse-content"><p></p> ```cpp #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } //加密 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] += 20; } } } //绘制函数 (打印二维数组中所有的元素) void GameDraw() { //参数:putimage(坐标x,坐标y,图的地址) /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); if (map[i][j] == -1) { //贴出雷的图片 putimage(j * SIZE, i * SIZE, &img[9]); } else if (map[i][j] >= 0 && map[i][j] <= 8) { //贴出数字图片 //map[i][j]的值刚好对应数字 putimage(j * SIZE, i * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //贴出空白图片 putimage(j * SIZE, i * SIZE, &img[10]); } else if (map[i][j] >= 30) { //贴出标记图片 putimage(j * SIZE, i * SIZE, &img[11]); } } printf("\n"); } } int main() { initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE); std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ GameInit(); GameDraw(); while (1); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> 我先睡了。。。。qvq ### 继续写 醒来发生了一些有趣的事哈哈哈 <div class='album_block'> [album type="photos"] ![9.png](https://blog.fivk.cn/usr/uploads/2021/06/3598296418.png) ![10.png](https://blog.fivk.cn/usr/uploads/2021/06/3018463599.png) ![11.png](https://blog.fivk.cn/usr/uploads/2021/06/1346367530.png) ![12.png](https://blog.fivk.cn/usr/uploads/2021/06/1854220397.png) ![13.png](https://blog.fivk.cn/usr/uploads/2021/06/880575843.png) ![14.png](https://blog.fivk.cn/usr/uploads/2021/06/2771867834.png) [/album] </div> 技术顾问哈哈哈。 **感觉现在main.cpp里面函数有点多了,我分成多个文件来写。** **存档6:** <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-480ee7ba5b6e791016985aa1a9a82ccb29" aria-expanded="true"><div class="accordion-toggle"><span style="">Fivk.h</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-480ee7ba5b6e791016985aa1a9a82ccb29" class="collapse collapse-content"><p></p> ```cpp #pragma once //这个就是防止头文件重复包含,不然要报错说很多东西从定义呀 #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //下面是实现的函数部分 extern void GameInit(); extern void GameDraw(); //数组设置为全extern extern int map[ROW][COL]; extern IMAGE img[12]; ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-5e9019e854ffe54c306732f5a71d8a6833" aria-expanded="true"><div class="accordion-toggle"><span style="">main.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-5e9019e854ffe54c306732f5a71d8a6833" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 int main() { initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE); std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ GameInit(); GameDraw(); while (1); printf("版权:贵州师范20大数据"); return 0; } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-f7f8707bfdb408de3cfd507184daf4d511" aria-expanded="true"><div class="accordion-toggle"><span style="">GameItit.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-f7f8707bfdb408de3cfd507184daf4d511" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } //加密 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] += 20; } } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-8fa0e837c45361fec75bee6b1e041a144" aria-expanded="true"><div class="accordion-toggle"><span style="">GameDarw.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-8fa0e837c45361fec75bee6b1e041a144" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //自己写的头文件 //绘制函数 (打印二维数组中所有的元素) void GameDraw() { //参数:putimage(坐标x,坐标y,图的地址) /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); if (map[i][j] == -1) { //贴出雷的图片 putimage(j * SIZE, i * SIZE, &img[9]); } else if (map[i][j] >= 0 && map[i][j] <= 8) { //贴出数字图片 //map[i][j]的值刚好对应数字 putimage(j * SIZE, i * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //贴出空白图片 putimage(j * SIZE, i * SIZE, &img[10]); } else if (map[i][j] >= 30) { //贴出标记图片 putimage(j * SIZE, i * SIZE, &img[11]); } } printf("\n"); } } ``` <p></p></div></div></div> ### 我们为什么要加密? 首先我们为什么这样加密。你想一下,我们加密的时候加了20,这个时候显示的图片都是空白。那么当我们玩游戏时,点击一个区域,然后让-20。他不就显示为原来的图了吗?这样我们就可以看到我们的游戏实现了。 ## 六、游戏的实现 ### 点击图片 我们要实现点击图片时间操作,我们必须知道图片的位置。其实,我们鼠标和窗口默认是有位置的 ![坐标位置](https://blog.fivk.cn/usr/uploads/2021/06/1220189053.png) 有应为我们图片大小为SIZE现在是50,所以每一格的间隔有50,我们这样用数组直接方位就越界了。 $msg.x$和 $msg.y$就是鼠标的坐标。但图片大小是SIZE,所以我们还要除以图片大小,就是对应的我们数组坐标。 ```cpp int PlayGame() { int r, c;//表示数组坐标 //定义一个鼠标消息 MOUSEMSG msg = { 0 }; while (1) { //不断的获取鼠标消息 msg = GetMouseMsg(); switch (msg.uMsg) //鼠标操作对应分支 { //鼠标左键 case WM_LBUTTONDOWN: //翻开空白图片 r = msg.y / SIZE; c = msg.x / SIZE; if (map[r][c] >= 19 && map[r][c] <= 28) { //解密,显示原本的数据 map[r][c] -= 20; } return map[r][c]; break; //鼠标右键 case WM_RBUTTONDOWN: //标记一个空白图片 或 取消一个标记图片 r = msg.y / SIZE; c = msg.x / SIZE; //进行标记 if (map[r][c] >= 19 && map[r][c] <= 28) { map[r][c] += 50; //只要让他最后的结果大于30就好了(我们加50肯定大于30了) } else if (map[r][c] >= 30) { //如果不满足上面if的条件就是已经标记过了,所以我们要取消标记 map[r][c] -= 50; } return map[r][c]; break; } } } ``` 这样就可以实现图片的翻开和标记了。 <div class="tip inlineBlock warning"> 值得注意的是,我这里数组下标是 r和c ,r对应y,c对应x。还有不能吧返回值放到switch (msg.uMsg)外面,不然所有的鼠标操作都要返回这样会出错,我们只判断左键和右键的操作。 </div> ![](https://blog.fivk.cn/usr/uploads/2021/06/1080145021.png) ### 踩到雷的处理 前面我们反转后吧他解密,就是得到他原来的样子。吧这个数值返回,我们进行判断 ```cpp if (PlayGame() == -1) //点到雷了 { GameDraw(); //显示一下点到雷的最新图片 MessageBox(hwnd, L"游戏失败了qvq\n版权:贵州师范20大数据", L"", MB_OK); break; } ``` 这样我们踩到雷就直接结束游戏了。 ![](https://blog.fivk.cn/usr/uploads/2021/06/1783018396.png) 这个就是判断踩到雷,游戏结束。 ### 游戏胜利 我们知道,数组一共有 $RNW*COL$个元素(在Fivk.h文件里面定义的),其中雷有$NUM$个。所以我们可以定义一个变量Count,来记住我们正确翻开空白的次数,当把所有的空白翻开时(即$Count=RNW*COL-NUM$),我们就判断游戏胜利。 我们吧Count写在main.c文件里面,在正确翻转时Count++ <div class='album_block'> [album type="photos"] ![](https://blog.fivk.cn/usr/uploads/2021/06/3992508866.png) ![](https://blog.fivk.cn/usr/uploads/2021/06/61426018.png) [/album] </div> ![](https://blog.fivk.cn/usr/uploads/2021/06/1049644696.png) 所以我们目前就做好了游戏的基本样式。 **存档7:** <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-5c2370b28ac54a1d1bb48d7df394ba8349" aria-expanded="true"><div class="accordion-toggle"><span style="">Fivk.h</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-5c2370b28ac54a1d1bb48d7df394ba8349" class="collapse collapse-content"><p></p> ```c #pragma once //这个就是防止头文件重复包含,不然要报错说很多东西从定义呀 #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //下面是实现的函数部分 extern void GameInit(); extern void GameDraw(); extern int PlayGame(); //数组设置为全extern extern int map[ROW][COL]; extern IMAGE img[12]; //计数的变量 extern int Count; ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-e959d817b16bb1894873ca0a0eecb27b53" aria-expanded="true"><div class="accordion-toggle"><span style="">main.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-e959d817b16bb1894873ca0a0eecb27b53" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 int Count = 0; //判断游戏状态 (点开的个数,判断游戏是否胜利) int main() { //HWND 是窗口的句柄 HWND hwnd = initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE); std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } //数组随机初始化(随机布雷) GameInit(); while (1) { //游戏图像和操作 都要不断更新显示 GameDraw(); if (PlayGame() == -1) //点到雷了 { GameDraw(); //显示一下点到雷的最新图片 MessageBox(hwnd, L"游戏失败了qvq\n版权:贵州师范20大数据", L"", MB_OK); break; } if (ROW * COL - NUM == Count) { GameDraw(); //显示一下游戏胜利最新图片 MessageBox(hwnd, L"游戏胜利^_^\n版权:贵州师范20大数据", L"", MB_OK); break; } } return 0; } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-6a950e78f1fb6b10a1900148bfad57e618" aria-expanded="true"><div class="accordion-toggle"><span style="">GameInit.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-6a950e78f1fb6b10a1900148bfad57e618" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } //加密 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] += 20; } } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-721cf52bf6daa1637463c0f3c366700d41" aria-expanded="true"><div class="accordion-toggle"><span style="">GameDraw.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-721cf52bf6daa1637463c0f3c366700d41" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } //加密 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] += 20; } } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-78fa066c381c528527c03c7f2b9e9fc211" aria-expanded="true"><div class="accordion-toggle"><span style="">PlayGame.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-78fa066c381c528527c03c7f2b9e9fc211" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" int PlayGame() { int r, c;//表示数组坐标 //定义一个鼠标消息 MOUSEMSG msg = { 0 }; while (1) { //不断的获取鼠标消息 msg = GetMouseMsg(); switch (msg.uMsg) //鼠标操作对应分支 { //鼠标左键 case WM_LBUTTONDOWN: //翻开空白图片 r = msg.y / SIZE; c = msg.x / SIZE; if (map[r][c] >= 19 && map[r][c] <= 28) { //解密,显示原本的数据 map[r][c] -= 20; · //反转次数加一 Count++; } return map[r][c]; break; //鼠标右键 case WM_RBUTTONDOWN: //标记一个空白图片 或 取消一个标记图片 r = msg.y / SIZE; c = msg.x / SIZE; //进行标记 if (map[r][c] >= 19 && map[r][c] <= 28) { map[r][c] += 50; //只要让他最后的结果大于30就好了(我们加50肯定大于30了) } else if (map[r][c] >= 30) { //如果不满足上面if的条件就是已经标记过了,所以我们要取消标记 map[r][c] -= 50; } return map[r][c]; break; } } } ``` <p></p></div></div></div> ## 七、游戏优化 我们真正玩扫雷时,翻到一个0,游戏会成片的翻开,会自动翻开哪些一看就知道不是雷的地方,应为我们都知道,0的周围都没有雷,所以我们翻到0就自动把0周边的空白翻开。如果空白里面也有0,也会翻开这个0的周围,以此类推。现在我们就是要实现这样一个东西。 <div class="tip inlineBlock success"> 在这里我们写一个Openzero来翻开周围的函数。 </div> ```cpp #include "Fivk.h" void OpenZero(int r, int c) { //解密,显示原本的数据 map[r][c] -= 20; //反转次数加一 Count++; //遍历周边 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int k = 0; k < 8; k++) { x = r + dx[k]; y = c + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && (map[x][y] >= 19 && map[x][y] <= 28)) //保证数组不越界 还有 是空白,没有被翻过和标记过的才能翻 { if (map[x][y] != 20) { //解密,显示原本的数据 map[x][y] -= 20; //反转次数加一 Count++; } else { OpenZero(x, y); } } } } ``` 我们采用递归实现对0周围的空白翻开。 首先我们得到0,在Openzero函数前面将数字还原,再将周围的空白分开,翻到0,进行递归。其实还是挺简单的。 并且我们在PlayGame函数里面我们添加对0的判断 ![](https://blog.fivk.cn/usr/uploads/2021/06/516280593.png) 这样我们就实现了扫雷。现在正式结束了。 我们可以修改 长、宽、雷的个数修改游戏难度 ![](https://blog.fivk.cn/usr/uploads/2021/06/3815429156.png) **最终存档:** <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-1d92a9523ae88e15bb6664861ab5b83799" aria-expanded="true"><div class="accordion-toggle"><span style="">Fivk.h</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-1d92a9523ae88e15bb6664861ab5b83799" class="collapse collapse-content"><p></p> ```cpp #pragma once //这个就是防止头文件重复包含,不然要报错说很多东西从定义呀 #include<stdio.h> #include<stdlib.h> //srand获取随机值 #include<time.h> //获取时间 #include<graphics.h> //EasyX库 #include<string> //字符串容器,不解释 #define ROW 10 //行 #define COL 10 //列 #define NUM 10 //雷的个数 #define SIZE 50 //图片大小 //下面是实现的函数部分 extern void GameInit(); //初始化 extern void GameDraw(); //打印图片 extern int PlayGame(); //游戏操作 extern void OpenZero(int, int); //翻开0的周围 //数组设置为全extern extern int map[ROW][COL]; extern IMAGE img[12]; //计数的变量 extern int Count; ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-5959f04acac6f8652016e1337f1005053" aria-expanded="true"><div class="accordion-toggle"><span style="">main.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-5959f04acac6f8652016e1337f1005053" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //用二维数组布局 int map[ROW][COL]; //存放图片 IMAGE img[12]; //img存放12张图片 int Count = 0; //判断游戏状态 (点开的个数,判断游戏是否胜利) int main() { //HWND 是窗口的句柄 HWND hwnd = initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE); std::wstring image_url; //0 ~ 8 是数字图片,9是雷,10是空白,11是标记图片 for (int count = 0; count < 12; count++) { image_url = L".//image//" + std::to_wstring(count) + L".jpg"; loadimage(&img[count], image_url.c_str(), SIZE, SIZE); } //数组随机初始化(随机布雷) GameInit(); while (1) { //游戏图像和操作 都要不断更新显示 GameDraw(); if (PlayGame() == -1) //点到雷了 { GameDraw(); //显示一下点到雷的最新图片 MessageBox(hwnd, L"游戏失败了qvq\n版权:贵州师范20大数据", L"", MB_OK); break; } if (ROW * COL - NUM == Count) { GameDraw(); //显示一下游戏胜利最新图片 MessageBox(hwnd, L"游戏胜利^_^\n版权:贵州师范20大数据", L"", MB_OK); break; } } return 0; } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-d73d9be97d5daa17cc68c7453132619950" aria-expanded="true"><div class="accordion-toggle"><span style="">GameInit.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-d73d9be97d5daa17cc68c7453132619950" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //数组的初始化函数 void GameInit() { srand((unsigned int)time(NULL)); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] = 0; } } //雷 -1 表示雷 一共有 NUM 个雷 int n = 0; while (n < NUM) { //随机数的种子 int r = rand() % ROW; // 取[0,ROW]范围内的任意一个数 int c = rand() % COL; // 取[0,COL]范围内的任意一个数 if (map[r][c] == 0) { map[r][c] = -1; n++; } } //得到雷的提示信息 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { //遍历二维数组,找到不是雷的元素,将数值替换为周围雷的个数 //也就是根据雷的布局,填充其他不为雷的数据 if (map[i][j] != -1) //找到不为雷的元素 { x = i; y = j; for (int k = 0; k < 8; k++) { x = i + dx[k]; y = j + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && map[x][y] == -1) { map[i][j]++; } } } } } //加密 for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { map[i][j] += 20; } } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-22c11090ea0b670cda4dd7342a34b16c35" aria-expanded="true"><div class="accordion-toggle"><span style="">GameDraw.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-22c11090ea0b670cda4dd7342a34b16c35" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" //自己写的头文件 //绘制函数 (打印二维数组中所有的元素) void GameDraw() { //参数:putimage(坐标x,坐标y,图的地址) /********************************************************** * 图片显示原理 * * * 元素 图片 操作 结果 * * 0-8 img[1-8] +20 20-28 * -1 img[9] +20 19 * 19-28 img[10] * 大于30 img[11] ***********************************************************/ printf("\n\n"); for (int i = 0; i < ROW; i++) { for (int j = 0; j < COL; j++) { printf("%2d ", map[i][j]); if (map[i][j] == -1) { //贴出雷的图片 putimage(j * SIZE, i * SIZE, &img[9]); } else if (map[i][j] >= 0 && map[i][j] <= 8) { //贴出数字图片 //map[i][j]的值刚好对应数字 putimage(j * SIZE, i * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //贴出空白图片 putimage(j * SIZE, i * SIZE, &img[10]); } else if (map[i][j] >= 30) { //贴出标记图片 putimage(j * SIZE, i * SIZE, &img[11]); } } printf("\n"); } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-68b1c34ece3a838e7aba9812a09f507c48" aria-expanded="true"><div class="accordion-toggle"><span style="">PlayGame.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-68b1c34ece3a838e7aba9812a09f507c48" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" int PlayGame() { int r, c;//表示数组坐标 //定义一个鼠标消息 MOUSEMSG msg = { 0 }; while (1) { //不断的获取鼠标消息 msg = GetMouseMsg(); switch (msg.uMsg) //鼠标操作对应分支 { //鼠标左键 case WM_LBUTTONDOWN: //翻开空白图片 r = msg.y / SIZE; c = msg.x / SIZE; if (map[r][c] >= 19 && map[r][c] <= 28) { if (map[r][c] == 20) //表示我们翻到0了,我们要将四周都翻开 { OpenZero(r, c); } else { //解密,显示原本的数据 map[r][c] -= 20; //反转次数加一 Count++; } } return map[r][c]; break; //鼠标右键 case WM_RBUTTONDOWN: //标记一个空白图片 或 取消一个标记图片 r = msg.y / SIZE; c = msg.x / SIZE; //进行标记 if (map[r][c] >= 19 && map[r][c] <= 28) { map[r][c] += 50; //只要让他最后的结果大于30就好了(我们加50肯定大于30了) } else if (map[r][c] >= 30) { //如果不满足上面if的条件就是已经标记过了,所以我们要取消标记 map[r][c] -= 50; } return map[r][c]; break; } } } ``` <p></p></div></div></div> <div class="panel panel-default collapse-panel box-shadow-wrap-lg"><div class="panel-heading panel-collapse" data-toggle="collapse" data-target="#collapse-d78297fc17eb27d16887702ce0072bd080" aria-expanded="true"><div class="accordion-toggle"><span style="">openZero.cpp</span> <i class="pull-right fontello icon-fw fontello-angle-right"></i> </div> </div> <div class="panel-body collapse-panel-body"> <div id="collapse-d78297fc17eb27d16887702ce0072bd080" class="collapse collapse-content"><p></p> ```cpp #include "Fivk.h" void OpenZero(int r, int c) { //解密,显示原本的数据 map[r][c] -= 20; //反转次数加一 Count++; //遍历周边 const int dx[] = { -1,-1,0,1,1,1,0,-1 }; const int dy[] = { 0,1,1,1,0,-1,-1,-1 }; int x, y; for (int k = 0; k < 8; k++) { x = r + dx[k]; y = c + dy[k]; if ((x >= 0 && x < ROW) && (y >= 0 && y < COL) && (map[x][y] >= 19 && map[x][y] <= 28)) //保证数组不越界 还有 是空白,没有被翻过和标记过的才能翻 { if (map[x][y] != 20) { //解密,显示原本的数据 map[x][y] -= 20; //反转次数加一 Count++; } else { OpenZero(x, y); } } } } ``` <p></p></div></div></div> ## 八、背景音乐 加入头文件 ```cpp #pragma comment(lib,"winmm.lib") ``` ```cpp //读取音乐标记为muisc(可以修改) mciSendString(L"open bgm//begin.mp3 alias muisc", 0, 0, 0); //播放muisc mciSendString(L"play muisc", 0, 0, 0); ``` ![](https://blog.fivk.cn/usr/uploads/2021/08/3822961177.jpg) <div class='album_block'> [album type="photos"] ![](https://blog.fivk.cn/usr/uploads/2021/06/481473187.png) ![](https://blog.fivk.cn/usr/uploads/2021/06/150736995.png) [/album] </div> 最后修改:2021 年 08 月 02 日 © 禁止转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏