欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++学习(二十二)(C语言部分)之 扫雷项目实例

程序员文章站 2022-03-30 11:31:04
一、新建项目 二、新建源文件 main.cpp和mining,cpp 三、新建头文件 mining.h 四、图片资源添加 添加完成后会在头文件里面生成一个.h头文件,用来调用资源 打开之后可以看到,对每一个资源文件进行了定义 这里面的顺序和你添加文件时的顺序是一样的,是根据你添加资源的先后顺序进行排 ......

一、新建项目

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 二、新建源文件

main.cpp和mining,cpp

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 三、新建头文件

mining.h

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 四、图片资源添加

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 添加完成后会在头文件里面生成一个.h头文件,用来调用资源

C++学习(二十二)(C语言部分)之 扫雷项目实例

 打开之后可以看到,对每一个资源文件进行了定义

这里面的顺序和你添加文件时的顺序是一样的,是根据你添加资源的先后顺序进行排列定义的

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 在资源文件夹下回显示添加的资源

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 五、vs安装图形库

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

 C++学习(二十二)(C语言部分)之 扫雷项目实例

 安装完成后重启vs之后就可以在项目中调用图形库的头文件----->  #include<graphics.h>  //图形库的头文件

 接下来是相关代码:

 

头文件部分:

mining.h文件

 1 #include<time.h> //该种方式引用的头文件是c自带的头文件
 2 #include<stdlib.h>
 3 #include<graphics.h>  //图形库的头文件
 4 
 5 #define map_width 500 //定义地图宽度  宏定义方式  即map_width就等于550
 6 
 7 #define map_height 550 //定义地图的高度
 8 
 9 #define each_size 50 //每一个格子的大小
10 
11 #define max_x (map_width/each_size) //计算每一行有多少个
12 
13 #define max_y (map_height/each_size) //计算每一列有多少个
14 
15 #define mine_count 20 //雷的个数
16 
17 //1.初始化地图  
18 void initmap(); //定义一个函数 是一个模块 只做属于自己的事情
19 
20 //2.实现雷的周围加一
21 void changestate(int x,int y);
22 
23 //3.判断是否越界
24 int isposok(int x, int y);
25 
26 //4.贴图
27 void drawmap();
28 
29 //5.显示信息
30 void showinfo();
31 
32 //6.实现鼠标点击  **  还未实现
33 int isopenmine();
34 
35 //7.进行递归翻开格子  **  还未实现
36 void openzerorecursively(int x,int y);  
37 
38 //8.翻开所有格子
39 void openall();
40 
41 //9.判断输赢 点击到地雷就输了  **  还未实现
42 void rengame();

 

源文件部分:

main.cpp

 1 #include"mining.h"
 2 #include<stdio.h>
 3 
 4 int main()
 5 {
 6     initgraph(map_width, map_height);//画出地图窗口
 7 
 8     initmap();//初始换函数
 9 
10     drawmap();//贴图函数
11     getchar();
12 
13     openall();//翻开所有格子
14     drawmap();//贴图
15 
16     getchar();
17     return 0;
18     getchar();//防止结果闪退
19 }

 

mining.cpp

  1 #include"mining.h"  //这种方式引用的头文件是我们自己定义的
  2 #include"resource.h"
  3 
  4 int map[max_x][max_y]; //定义一个二维数组 制作地图
  5 
  6 int ncountopen;  //打开格子的个数
  7 
  8 int ncountflag;  //标记的个数
  9 
 10 void initmap()  //第一个函数 初始化函数
 11 {
 12     //1.初始化数组
 13     for (int i = 0; i < max_x; i++)
 14     {
 15         for (int j = 0; j < max_y; j++)
 16         {
 17             map[i][j] = 0;
 18         }
 19     }
 20 
 21     ncountopen = 0;  //初始化
 22 
 23     ncountflag = 0;  //初始化
 24 
 25     //2.埋地雷--->  地雷是随机的
 26 
 27     srand((unsigned int)time(0));  // 种下随机数种子
 28 
 29     int x, y;
 30 
 31     int ncount=0;  //统计埋雷的个数
 32 
 33     //开始埋雷
 34     while (ncount<mine_count)  //当前埋雷的个数 小于埋雷的最大个数 就一直循环
 35     {
 36         x = rand() % max_x;  // ? %10==0~9  rand 获取随机数
 37 
 38         y = rand() % (max_y - 1) + 1;  // 
 39 
 40         if (-1 == map[x][y])  //-1 表示地雷
 41         {//随机下标是一个地雷
 42             continue;  //跳过本次循环 不是结束循环(break)
 43         }
 44         map[x][y] = -1;  // 埋雷
 45 
 46         ncount++;  //埋雷的个数加一
 47     }
 48 
 49     //实现地雷九宫格周围加一
 50     for (int i = 0; i < max_x; i++)  
 51     {
 52         for (int j = 1; j < max_y; j++)  //因为第一行没有雷 我们是用来显示信息的 所以不能从0开始
 53         {
 54             if (-1 == map[i][j])  //判断是不是一颗地雷  -1写在左边的原因-->左值  map[i][j]=-1这种形式是错误的
 55             {
 56                 changestate(i, j);  //下标
 57             }
 58         }
 59     }    
 60 }
 61 
 62 void changestate(int x, int y)  //第二个函数 实现雷的周围加一 九宫格范围
 63 {
 64     for (int i = x - 1; i <= x + 1; i++)
 65     {
 66         for (int j = y - 1; j <= y + 1; j++)
 67         {
 68             if (-1 == map[i][j]||isposok(i,j)==0 ) //这个位置是一颗地雷并且判断是否越界
 69             {
 70                 continue;   //跳出本次循环
 71             }
 72             map[i][j]+=1;  //和map[i][j]++;是一样的
 73         }
 74     }
 75 }
 76 
 77 int isposok(int x, int y)  //第三个函数 判断当前的下标是不是越界了
 78 {
 79     //逻辑表达式的值 0和1
 80     return (x >= 0 && x <= max_x&&y <= 1 && y < max_y);  //越界返回0 没越界返回1
 81 }
 82 
 83 void drawmap()  //第四个函数 对地图贴图贴图
 84 {
 85     image img;
 86 
 87     for (int i = 0; i < max_x; i++)
 88     {
 89         for (int j = 1; j < max_y; j++)
 90         {
 91             if (map[i][j] < 9)  //雷的周围1最大是8个不会超过九  小于9 说明格子没有被翻开
 92             {
 93                 loadimage(&img, l"jpg", makeintresource(idr_jpg13), each_size, each_size);  //l宽字节 jpg13是没有翻开的情况的图片
 94             }
 95             else  //已经被翻开
 96             {   //翻开一个格子 让这个格子+10 表示已经被翻开
 97                 if (map[i][j] >= 11 && map[i][j] <= 18)  //11~18表示1~8
 98                 {
 99                     loadimage(&img, l"jpg", makeintresource(idr_jpg1 + map[i][j] - 11, each_size, each_size));  //通过这个算法 判断贴哪一张图片
100                 }
101                 else if (map[i][j] == 9)  //9-10==-1  -1是地雷
102                 {
103                     loadimage(&img, l"jpg", makeintresource(idr_jpg10), each_size, each_size);  //贴地雷图片
104                 }
105                 else if (map[i][j] == 10)  //10-10==0  0表示空白
106                 {
107                     loadimage(&img, l"jpg", makeintresource(idr_jpg11), each_size, each_size);  //贴空地图片
108                 }
109                 else
110                 {
111                     loadimage(&img, l"jpg", makeintresource(idr_jpg9), each_size, each_size);  //贴标记图片
112                 }
113             }
114             putimage(i*each_size, j*each_size, &img);
115         }
116     }
117     showinfo();
118 }
119 
120 void showinfo()  //第五个函数  显示信息
121 {
122     //埋雷的个数  打开的个数  标记的个数
123     //设置字体的样式
124     settextstyle(20, 20, l"wingding.ttf");  //字体样式标号
125     
126     //背景颜色
127     setbkmode(transparent);
128 
129     //字体颜色
130     settextcolor(yellow);
131     
132     //设置字体的位置
133     wchar szopen[32];
134     wchar szflag[32];
135     wchar szallmine[32];
136 
137       //字符串格式化
138       //与printf  scanf类似 
139     wsprintf(szallmine, l"埋雷:%d", mine_count);//埋雷:20  把“埋雷”这个字符串放到szallmine里面 格式化成字符串类型
140     wsprintf(szopen, l"打开:%d", ncountopen);
141     wsprintf(szflag, l"标记:%d", ncountflag);
142     
143       //调整坐标
144     outtextxy(20, 20, szallmine);
145     outtextxy(190, 20, szopen);
146     outtextxy(350, 20, szflag);
147 
148 }
149 
150 
151 
152 
153 
154 
155 void openzerorecursively(int x, int y)  //第七个函数 进行递归翻开格子
156 {
157 
158 }
159 
160 void openall()  //第八个函数 翻开所有格子
161 {
162     for (int i = 0; i < max_x; i++)
163     {
164         for (int j=1;j<max_y;j++)
165         {
166             if (map[i][j] < 9)
167             {
168                 map[i][j] += 10;
169             }
170         }
171     }
172 }
173 
174 void rengame()  //第九个函数 判断输赢
175 {
176 
177 }

 

注:

设置字体样式:

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

目前实现的结果如下:

C++学习(二十二)(C语言部分)之 扫雷项目实例

C++学习(二十二)(C语言部分)之 扫雷项目实例

 

之后的以后有机会写好之后再补充

 

2019-03-20   13:09:47

 

之前写的代码并不完整,而且还有一些错误,在经过一番学习添加修改后,

最终添加修改完善后的代码如下所示:

 

  1 mining.h文件
  2 #include<time.h> //该种方式引用的头文件是c自带的头文件
  3 #include<stdlib.h>
  4 #include<graphics.h>  //图形库的头文件
  5 
  6 #define map_width 500 //定义地图宽度  宏定义方式  即map_width就等于550
  7 
  8 #define map_height 550 //定义地图的高度
  9 
 10 #define each_size 50   //每一个格子的大小
 11 
 12 #define max_x (map_width/each_size) //计算每一行有多少个
 13 
 14 #define max_y (map_height/each_size) //计算每一列有多少个
 15 
 16 #define mine_count 5//雷的个数
 17 
 18 //1.初始化地图  
 19 void initmap(); //定义一个函数 是一个模块 只做属于自己的事情
 20 
 21 //2.实现雷的周围加一
 22 void changestate(int x,int y);
 23 
 24 //3.判断是否越界
 25 int isposok(int x, int y);
 26 
 27 //4.贴图
 28 void drawmap();
 29 
 30 //5.显示信息
 31 void showinfo();
 32 
 33 //6.实现鼠标点击  
 34 int isopenmine();
 35 
 36 //7.进行递归翻开格子 
 37 void openzerorecursively(int x,int y);  
 38 
 39 //8.翻开所有格子
 40 void openall();
 41 
 42 //9.判断输赢 点击到地雷就输了 
 43 void rengame();
 44 
 45 //以上是对使用函数的一个声明
 46 
 47 
 48 mining.cpp文件
 49 #include"mining.h"  //这种方式引用的头文件是我们自己定义的
 50 #include"resource.h"
 51 
 52 int map[max_x][max_y]; //定义一个二维数组 制作地图
 53 
 54 int ncountopen;  //打开格子的个数
 55 
 56 int ncountflag;  //标记的个数
 57 
 58 void initmap()  //第一个函数 初始化函数
 59 {
 60     //1.初始化数组
 61     for (int i = 0; i < max_x; i++)
 62     {
 63         for (int j = 0; j < max_y; j++)
 64         {
 65             map[i][j] = 0;
 66         }
 67     }
 68 
 69     ncountopen = 0;  //初始化
 70 
 71     ncountflag = 0;  //初始化
 72 
 73     //2.埋地雷--->  地雷是随机的
 74 
 75     srand((unsigned int)time(0));  // 种下随机数种子
 76 
 77     int x, y;
 78 
 79     int ncount=0;  //统计埋雷的个数
 80 
 81     //开始埋雷
 82     while (ncount<mine_count)  //当前埋雷的个数 小于埋雷的最大个数 就一直循环
 83     {
 84         x = rand() % max_x;  // ? %10==0~9  rand 获取随机数
 85 
 86         y = rand() % (max_y - 1) + 1;  // 
 87 
 88         if (-1 == map[x][y])  //-1 表示地雷
 89         {//随机下标是一个地雷
 90             continue;  //跳过本次循环 不是结束循环(break)
 91         }
 92         map[x][y] = -1;  // 埋雷
 93 
 94         ncount++;  //埋雷的个数加一
 95     }
 96 
 97     //实现地雷九宫格周围加一
 98     for (int i = 0; i < max_x; i++)  
 99     {
100         for (int j = 1; j < max_y; j++)  //因为第一行没有雷 我们是用来显示信息的 所以不能从0开始
101         {
102             if (-1 == map[i][j])  //判断是不是一颗地雷  -1写在左边的原因-->左值  map[i][j]=-1这种形式是错误的
103             {
104                 changestate(i, j);  //下标
105             }
106         }
107     }    
108 }
109 
110 void changestate(int x, int y)  //第二个函数 实现雷的周围加一 九宫格范围
111 {
112     for (int i = x - 1; i <= x + 1; i++)
113     {
114         for (int j = y - 1; j <= y + 1; j++)
115         {
116             if (-1 == map[i][j]||isposok(i,j)==0 ) //这个位置是一颗地雷并且判断是否越界
117             {
118                 continue;   //跳出本次循环
119             }
120             map[i][j]+=1;  //和map[i][j]++;是一样的
121         }
122     }
123 }
124 
125 int isposok(int x, int y)  //第三个函数 判断当前的下标是不是越界了
126 {
127     //逻辑表达式的值 0和1
128     return (x >= 0 && x < max_x &&y >= 1 && y < max_y);  //越界返回0 没越界返回1
129 }
130 
131 void drawmap()  //第四个函数 对地图贴图贴图
132 {
133     image img;
134     beginbatchdraw();  //批量绘图  解决闪屏问题
135 
136     cleardevice();
137     
138 
139     for (int i = 0; i < max_x; i++)
140     {
141         for (int j = 1; j < max_y; j++)
142         {
143             if (map[i][j] < 9)  //雷的周围1最大是8个不会超过九  小于9 说明格子没有被翻开
144             {
145                 loadimage(&img, l"jpg", makeintresource(idr_jpg13), each_size, each_size);  //l宽字节 jpg13是没有翻开的情况的图片
146             }
147             else  //已经被翻开
148             {   //翻开一个格子 让这个格子+10 表示已经被翻开
149                 if (map[i][j] >= 11 && map[i][j] <= 18)  //11~18表示1~8
150                 {
151                     loadimage(&img, l"jpg", makeintresource(idr_jpg1 + map[i][j] - 11), each_size, each_size);  //通过这个算法 判断贴哪一张图片
152                 }
153                 else if (map[i][j] == 9)  //9-10==-1  -1是地雷
154                 {
155                     loadimage(&img, l"jpg", makeintresource(idr_jpg10), each_size, each_size);  //贴地雷图片
156                 }
157                 else if (map[i][j] == 10)  //10-10==0  0表示空白
158                 {
159                     loadimage(&img, l"jpg", makeintresource(idr_jpg12), each_size, each_size);  //贴空地图片
160                 }
161                 else
162                 {
163                     loadimage(&img, l"jpg", makeintresource(idr_jpg9), each_size, each_size);  //贴标记图片
164                 }
165             }
166             putimage(i*each_size, j*each_size, &img);
167         }
168     }
169     showinfo();
170     endbatchdraw();
171 }
172 
173 void showinfo()  //第五个函数  显示信息
174 {
175     //埋雷的个数  打开的个数  标记的个数
176     //设置字体的样式
177     settextstyle(20, 20, l"wingding.ttf");  //字体样式标号
178     
179     //背景颜色
180     setbkmode(transparent);
181 
182     //字体颜色
183     settextcolor(yellow);
184     
185     //设置字体的位置
186     wchar szopen[32];
187     wchar szflag[32];
188     wchar szallmine[32];
189 
190       //字符串格式化
191       //与printf  scanf类似 
192     wsprintf(szallmine, l"埋雷:%d", mine_count);//埋雷:20  把“埋雷”这个字符串放到szallmine里面 格式化成字符串类型
193     wsprintf(szopen, l"打开:%d", ncountopen);
194     wsprintf(szflag, l"标记:%d", ncountflag);
195     
196       //调整坐标
197     outtextxy(20, 20, szallmine);
198     outtextxy(190, 20, szopen);
199     outtextxy(350, 20, szflag);
200 
201 }
202 
203 int isopenmine()
204 {
205     mousemsg m = { 0 };//保存鼠标消息
206 
207     while (1)  //死循环
208     {
209         m = getmousemsg();//获取鼠标消息
210         switch (m.umsg)
211         {
212         case wm_lbuttondown:  //鼠标左键按下
213             if (map[m.x / each_size][m.y / each_size] == -1)  //点击到了地雷
214             {
215                 map[m.x / each_size][m.y / each_size] += 10;  //int a=5; a+=10  a=a+10 翻开格子+10 表示已经翻开
216                 return 0;  //返回0说明点击的是一颗雷
217             }
218             else if (map[m.x / each_size][m.y / each_size] == 0)  //点击到的是一个空地
219             {
220                 openzerorecursively(m.x / each_size, m.y / each_size);
221                 return 1;
222             }
223             else if (map[m.x / each_size][m.y / each_size] > 0 && map[m.x / each_size][m.y / each_size] < 9)  //表示 点击的位置的值是1~8  9表示的是已经被翻开的
224             {
225                 map[m.x / each_size][m.y / each_size] += 10;
226                 ncountopen++;
227                 return 1;
228             }
229             
230             break;
231         case wm_rbuttondown:
232             if (map[m.x / each_size][m.y / each_size] < 9)
233             {
234                 map[m.x / each_size][m.y / each_size ]+= 100;  //加多少都可以 只是一个标记
235                 ncountflag++;
236             }
237             else if (map[m.x / each_size][m.y / each_size]>19)
238             {
239                 map[m.x / each_size][m.y / each_size] -= 100;
240                 ncountflag--;
241             }
242             return 1;
243         }
244     }
245 }
246 
247 void openzerorecursively(int x, int y)  //第七个函数 进行递归翻开格子
248 {
249     map[x][y] += 10;
250     ncountopen++;
251     for (int i = x - 1; i <= x + 1; i++)
252     {
253         for (int j = y - 1; j <= y + 1; j++)
254         {
255             if (isposok(i, j)==0)
256             {
257                 continue;
258             }
259             if (0==map[i][j])
260             {
261                 openzerorecursively(i, j);
262             }
263             if (map[i][j] < 9)
264             {
265                 map[i][j] += 10;
266                 ncountopen++;
267             }
268         }
269     }
270 }
271 
272 void openall()  //第八个函数 翻开所有格子  游戏结束
273 {
274     for (int i = 0; i < max_x; i++)
275     {
276         for (int j=1;j<max_y;j++)
277         {
278             if (map[i][j] < 9)
279             {
280                 map[i][j] += 10;
281             }
282         }
283     }
284 }
285 
286 void rengame()  //第九个函数 判断输赢
287 {
288     while (ncountopen<((max_x*(max_y-1))-mine_count))  //100个格子 有20个地雷  10*111=110   10*10
289     {
290         if (isopenmine()==0)
291         {
292             openall();
293             drawmap();
294             messagebox(gethwnd(), l"你太菜了!再去修炼吧!", l"提示",mb_ok);
295             return ;  //结束函数
296         }
297         drawmap();
298     }
299     drawmap();
300     messagebox(gethwnd(), l"恭喜你,你赢了", l"提示", mb_ok);
301 }
302 
303 
304 
305 main.cpp文件
306 #include"mining.h"
307 #include<stdio.h>
308 
309 int main()
310 {
311     initgraph(map_width, map_height);//画出地图窗口
312 
313     initmap();//初始换函数
314     drawmap();//贴图
315 
316     while (true)  //循环游戏
317     {
318         rengame();
319         initmap();
320         drawmap();
321     }
322     getchar();
323     return 0;
324 }

 

 

 

2019-03-20  23:57:46