一、新建项目

二、新建源文件

main.cpp和mining,cpp

三、新建头文件

mining.h

四、图片资源添加

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

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

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

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

五、VS安装图形库

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

接下来是相关代码:

头文件部分:

mining.h文件

 #include<time.h> //该种方式引用的头文件是c自带的头文件
#include<stdlib.h>
#include<graphics.h> //图形库的头文件 #define MAP_WIDTH 500 //定义地图宽度 宏定义方式 即MAP_WIDTH就等于550 #define MAP_HEIGHT 550 //定义地图的高度 #define EACH_SIZE 50 //每一个格子的大小 #define MAX_X (MAP_WIDTH/EACH_SIZE) //计算每一行有多少个 #define MAX_Y (MAP_HEIGHT/EACH_SIZE) //计算每一列有多少个 #define MINE_COUNT 20 //雷的个数 //1.初始化地图
void InitMap(); //定义一个函数 是一个模块 只做属于自己的事情 //2.实现雷的周围加一
void ChangeState(int x,int y); //3.判断是否越界
int IsPosOk(int x, int y); //4.贴图
void DrawMap(); //5.显示信息
void ShowInfo(); //6.实现鼠标点击 ** 还未实现
int IsOpenMine(); //7.进行递归翻开格子 ** 还未实现
void OpenZeroRecursively(int x,int y); //8.翻开所有格子
void OpenAll(); //9.判断输赢 点击到地雷就输了 ** 还未实现
void RenGame();

源文件部分:

main.cpp

 #include"mining.h"
#include<stdio.h> int main()
{
initgraph(MAP_WIDTH, MAP_HEIGHT);//画出地图窗口 InitMap();//初始换函数 DrawMap();//贴图函数
getchar(); OpenAll();//翻开所有格子
DrawMap();//贴图 getchar();
return ;
getchar();//防止结果闪退
}

mining.cpp

 #include"mining.h"  //这种方式引用的头文件是我们自己定义的
#include"resource.h" int Map[MAX_X][MAX_Y]; //定义一个二维数组 制作地图 int nCountOpen; //打开格子的个数 int nCountFlag; //标记的个数 void InitMap() //第一个函数 初始化函数
{
//1.初始化数组
for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++)
{
Map[i][j] = ;
}
} nCountOpen = ; //初始化 nCountFlag = ; //初始化 //2.埋地雷---> 地雷是随机的 srand((unsigned int)time()); // 种下随机数种子 int x, y; int nCount=; //统计埋雷的个数 //开始埋雷
while (nCount<MINE_COUNT) //当前埋雷的个数 小于埋雷的最大个数 就一直循环
{
x = rand() % MAX_X; // ? %10==0~9 rand 获取随机数 y = rand() % (MAX_Y - ) + ; // if (- == Map[x][y]) //-1 表示地雷
{//随机下标是一个地雷
continue; //跳过本次循环 不是结束循环(break)
}
Map[x][y] = -; // 埋雷 nCount++; //埋雷的个数加一
} //实现地雷九宫格周围加一
for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++) //因为第一行没有雷 我们是用来显示信息的 所以不能从0开始
{
if (- == Map[i][j]) //判断是不是一颗地雷 -1写在左边的原因-->左值 Map[i][j]=-1这种形式是错误的
{
ChangeState(i, j); //下标
}
}
}
} void ChangeState(int x, int y) //第二个函数 实现雷的周围加一 九宫格范围
{
for (int i = x - ; i <= x + ; i++)
{
for (int j = y - ; j <= y + ; j++)
{
if (- == Map[i][j]||IsPosOk(i,j)== ) //这个位置是一颗地雷并且判断是否越界
{
continue; //跳出本次循环
}
Map[i][j]+=; //和Map[i][j]++;是一样的
}
}
} int IsPosOk(int x, int y) //第三个函数 判断当前的下标是不是越界了
{
//逻辑表达式的值 0和1
return (x >= && x <= MAX_X&&y <= && y < MAX_Y); //越界返回0 没越界返回1
} void DrawMap() //第四个函数 对地图贴图贴图
{
IMAGE img; for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++)
{
if (Map[i][j] < ) //雷的周围1最大是8个不会超过九 小于9 说明格子没有被翻开
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG13), EACH_SIZE, EACH_SIZE); //L宽字节 jpg13是没有翻开的情况的图片
}
else //已经被翻开
{ //翻开一个格子 让这个格子+10 表示已经被翻开
if (Map[i][j] >= && Map[i][j] <= ) //11~18表示1~8
{
loadimage(&img, L"JPG", MAKEINTRESOURCE(IDR_JPG1 + Map[i][j] - , EACH_SIZE, EACH_SIZE)); //通过这个算法 判断贴哪一张图片
}
else if (Map[i][j] == ) //9-10==-1 -1是地雷
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG10), EACH_SIZE, EACH_SIZE); //贴地雷图片
}
else if (Map[i][j] == ) //10-10==0 0表示空白
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG11), EACH_SIZE, EACH_SIZE); //贴空地图片
}
else
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG9), EACH_SIZE, EACH_SIZE); //贴标记图片
}
}
putimage(i*EACH_SIZE, j*EACH_SIZE, &img);
}
}
ShowInfo();
} void ShowInfo() //第五个函数 显示信息
{
//埋雷的个数 打开的个数 标记的个数
//设置字体的样式
settextstyle(, , L"wingding.ttf"); //字体样式标号 //背景颜色
setbkmode(TRANSPARENT); //字体颜色
settextcolor(YELLOW); //设置字体的位置
WCHAR szOpen[];
WCHAR szFlag[];
WCHAR szAllMine[]; //字符串格式化
//与printf scanf类似
wsprintf(szAllMine, L"埋雷:%d", MINE_COUNT);//埋雷:20 把“埋雷”这个字符串放到szAllMine里面 格式化成字符串类型
wsprintf(szOpen, L"打开:%d", nCountOpen);
wsprintf(szFlag, L"标记:%d", nCountFlag); //调整坐标
outtextxy(, , szAllMine);
outtextxy(, , szOpen);
outtextxy(, , szFlag); } void OpenZeroRecursively(int x, int y) //第七个函数 进行递归翻开格子
{ } void OpenAll() //第八个函数 翻开所有格子
{
for (int i = ; i < MAX_X; i++)
{
for (int j=;j<MAX_Y;j++)
{
if (Map[i][j] < )
{
Map[i][j] += ;
}
}
}
} void RenGame() //第九个函数 判断输赢
{ }

注:

设置字体样式:

目前实现的结果如下:

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

2019-03-20   13:09:47

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

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

 mining.h文件
#include<time.h> //该种方式引用的头文件是c自带的头文件
#include<stdlib.h>
#include<graphics.h> //图形库的头文件 #define MAP_WIDTH 500 //定义地图宽度 宏定义方式 即MAP_WIDTH就等于550 #define MAP_HEIGHT 550 //定义地图的高度 #define EACH_SIZE 50 //每一个格子的大小 #define MAX_X (MAP_WIDTH/EACH_SIZE) //计算每一行有多少个 #define MAX_Y (MAP_HEIGHT/EACH_SIZE) //计算每一列有多少个 #define MINE_COUNT 5//雷的个数 //1.初始化地图
void InitMap(); //定义一个函数 是一个模块 只做属于自己的事情 //2.实现雷的周围加一
void ChangeState(int x,int y); //3.判断是否越界
int IsPosOk(int x, int y); //4.贴图
void DrawMap(); //5.显示信息
void ShowInfo(); //6.实现鼠标点击
int IsOpenMine(); //7.进行递归翻开格子
void OpenZeroRecursively(int x,int y); //8.翻开所有格子
void OpenAll(); //9.判断输赢 点击到地雷就输了
void RenGame(); //以上是对使用函数的一个声明 mining.cpp文件
#include"mining.h" //这种方式引用的头文件是我们自己定义的
#include"resource.h" int Map[MAX_X][MAX_Y]; //定义一个二维数组 制作地图 int nCountOpen; //打开格子的个数 int nCountFlag; //标记的个数 void InitMap() //第一个函数 初始化函数
{
//1.初始化数组
for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++)
{
Map[i][j] = ;
}
} nCountOpen = ; //初始化 nCountFlag = ; //初始化 //2.埋地雷---> 地雷是随机的 srand((unsigned int)time()); // 种下随机数种子 int x, y; int nCount=; //统计埋雷的个数 //开始埋雷
while (nCount<MINE_COUNT) //当前埋雷的个数 小于埋雷的最大个数 就一直循环
{
x = rand() % MAX_X; // ? %10==0~9 rand 获取随机数 y = rand() % (MAX_Y - ) + ; // if (- == Map[x][y]) //-1 表示地雷
{//随机下标是一个地雷
continue; //跳过本次循环 不是结束循环(break)
}
Map[x][y] = -; // 埋雷 nCount++; //埋雷的个数加一
} //实现地雷九宫格周围加一
for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++) //因为第一行没有雷 我们是用来显示信息的 所以不能从0开始
{
if (- == Map[i][j]) //判断是不是一颗地雷 -1写在左边的原因-->左值 Map[i][j]=-1这种形式是错误的
{
ChangeState(i, j); //下标
}
}
}
} void ChangeState(int x, int y) //第二个函数 实现雷的周围加一 九宫格范围
{
for (int i = x - ; i <= x + ; i++)
{
for (int j = y - ; j <= y + ; j++)
{
if (- == Map[i][j]||IsPosOk(i,j)== ) //这个位置是一颗地雷并且判断是否越界
{
continue; //跳出本次循环
}
Map[i][j]+=; //和Map[i][j]++;是一样的
}
}
} int IsPosOk(int x, int y) //第三个函数 判断当前的下标是不是越界了
{
//逻辑表达式的值 0和1
return (x >= && x < MAX_X &&y >= && y < MAX_Y); //越界返回0 没越界返回1
} void DrawMap() //第四个函数 对地图贴图贴图
{
IMAGE img;
BeginBatchDraw(); //批量绘图 解决闪屏问题 cleardevice(); for (int i = ; i < MAX_X; i++)
{
for (int j = ; j < MAX_Y; j++)
{
if (Map[i][j] < ) //雷的周围1最大是8个不会超过九 小于9 说明格子没有被翻开
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG13), EACH_SIZE, EACH_SIZE); //L宽字节 jpg13是没有翻开的情况的图片
}
else //已经被翻开
{ //翻开一个格子 让这个格子+10 表示已经被翻开
if (Map[i][j] >= && Map[i][j] <= ) //11~18表示1~8
{
loadimage(&img, L"JPG", MAKEINTRESOURCE(IDR_JPG1 + Map[i][j] - ), EACH_SIZE, EACH_SIZE); //通过这个算法 判断贴哪一张图片
}
else if (Map[i][j] == ) //9-10==-1 -1是地雷
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG10), EACH_SIZE, EACH_SIZE); //贴地雷图片
}
else if (Map[i][j] == ) //10-10==0 0表示空白
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG12), EACH_SIZE, EACH_SIZE); //贴空地图片
}
else
{
loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG9), EACH_SIZE, EACH_SIZE); //贴标记图片
}
}
putimage(i*EACH_SIZE, j*EACH_SIZE, &img);
}
}
ShowInfo();
EndBatchDraw();
} void ShowInfo() //第五个函数 显示信息
{
//埋雷的个数 打开的个数 标记的个数
//设置字体的样式
settextstyle(, , L"wingding.ttf"); //字体样式标号 //背景颜色
setbkmode(TRANSPARENT); //字体颜色
settextcolor(YELLOW); //设置字体的位置
WCHAR szOpen[];
WCHAR szFlag[];
WCHAR szAllMine[]; //字符串格式化
//与printf scanf类似
wsprintf(szAllMine, L"埋雷:%d", MINE_COUNT);//埋雷:20 把“埋雷”这个字符串放到szAllMine里面 格式化成字符串类型
wsprintf(szOpen, L"打开:%d", nCountOpen);
wsprintf(szFlag, L"标记:%d", nCountFlag); //调整坐标
outtextxy(, , szAllMine);
outtextxy(, , szOpen);
outtextxy(, , szFlag); } int IsOpenMine()
{
MOUSEMSG m = { };//保存鼠标消息 while () //死循环
{
m = GetMouseMsg();//获取鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN: //鼠标左键按下
if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] == -) //点击到了地雷
{
Map[m.x / EACH_SIZE][m.y / EACH_SIZE] += ; //int a=5; a+=10 a=a+10 翻开格子+10 表示已经翻开
return ; //返回0说明点击的是一颗雷
}
else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] == ) //点击到的是一个空地
{
OpenZeroRecursively(m.x / EACH_SIZE, m.y / EACH_SIZE);
return ;
}
else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] > && Map[m.x / EACH_SIZE][m.y / EACH_SIZE] < ) //表示 点击的位置的值是1~8 9表示的是已经被翻开的
{
Map[m.x / EACH_SIZE][m.y / EACH_SIZE] += ;
nCountOpen++;
return ;
} break;
case WM_RBUTTONDOWN:
if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] < )
{
Map[m.x / EACH_SIZE][m.y / EACH_SIZE ]+= ; //加多少都可以 只是一个标记
nCountFlag++;
}
else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE]>)
{
Map[m.x / EACH_SIZE][m.y / EACH_SIZE] -= ;
nCountFlag--;
}
return ;
}
}
} void OpenZeroRecursively(int x, int y) //第七个函数 进行递归翻开格子
{
Map[x][y] += ;
nCountOpen++;
for (int i = x - ; i <= x + ; i++)
{
for (int j = y - ; j <= y + ; j++)
{
if (IsPosOk(i, j)==)
{
continue;
}
if (==Map[i][j])
{
OpenZeroRecursively(i, j);
}
if (Map[i][j] < )
{
Map[i][j] += ;
nCountOpen++;
}
}
}
} void OpenAll() //第八个函数 翻开所有格子 游戏结束
{
for (int i = ; i < MAX_X; i++)
{
for (int j=;j<MAX_Y;j++)
{
if (Map[i][j] < )
{
Map[i][j] += ;
}
}
}
} void RenGame() //第九个函数 判断输赢
{
while (nCountOpen<((MAX_X*(MAX_Y-))-MINE_COUNT)) //100个格子 有20个地雷 10*111=110 10*10
{
if (IsOpenMine()==)
{
OpenAll();
DrawMap();
MessageBox(GetHWnd(), L"你太菜了!再去修炼吧!", L"提示",MB_OK);
return ; //结束函数
}
DrawMap();
}
DrawMap();
MessageBox(GetHWnd(), L"恭喜你,你赢了", L"提示", MB_OK);
} main.cpp文件
#include"mining.h"
#include<stdio.h> int main()
{
initgraph(MAP_WIDTH, MAP_HEIGHT);//画出地图窗口 InitMap();//初始换函数
DrawMap();//贴图 while (true) //循环游戏
{
RenGame();
InitMap();
DrawMap();
}
getchar();
return ;
}

2019-03-20  23:57:46

C++学习(二十二)(C语言部分)之 项目扫雷实例的更多相关文章

  1. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  2. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  3. 学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环

    目录 学习笔记:CentOS7学习之二十二: 结构化命令case和for.while循环 22.1 流程控制语句:case 22.2 循环语句 22.1.2 for-do-done 22.3 whil ...

  4. (C/C++学习笔记) 二十二. 标准模板库

    二十二. 标准模板库 ● STL基本介绍 标准模板库(STL, standard template library): C++提供的大量的函数模板(通用算法)和类模板. ※ 为什么我们一般不需要自己写 ...

  5. python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字

    python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...

  6. Tensorflow深度学习之十二:基础图像处理之二

    Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474   首先放出原始图像: ...

  7. Bootstrap <基础二十二>超大屏幕(Jumbotron)

    Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ...

  8. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  9. VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池

    VMware vSphere 服务器虚拟化之二十二桌面虚拟化之创建View Composer链接克隆的虚拟桌面池 在上一节我们创建了完整克隆的自动专有桌面池,在创建过程比较缓慢,这次我们将学习创建Vi ...

  10. JAVA之旅(二十二)——Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习

    JAVA之旅(二十二)--Map概述,子类对象特点,共性方法,keySet,entrySet,Map小练习 继续坚持下去吧,各位骚年们! 事实上,我们的数据结构,只剩下这个Map的知识点了,平时开发中 ...

随机推荐

  1. Win10系列:C#应用控件基础4

    ComboBox控件 ComboBox控件包含一个不可编辑的文本框和一个下拉列表,这个下拉列表是由多个ComboBoxItem子元素组成的.使用ComboBox控件可以节省界面空间,因为ComboBo ...

  2. Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)

    本篇项目地址,名字是AudioRecord录音(能暂停,将pch转换为wav),求starhttps://github.com/979451341/Audio-and-video-learning-m ...

  3. datatime 模块

    import datetime # 这个是一个包 里面包含 对时间的处理 对日期的处理datetime.date # 日期相关datetime.time # 时间相关 # 获取当前详细时间print( ...

  4. Linux防火墙iptables的策略

    iptables策略 iptables -L #查看现有防火墙所有策略 iptables -F #清除现有防火墙策略 只允许特定流量通过,禁用其他流量 1.允许SSH流量(重要) iptables - ...

  5. day36 数据库表操作 数据类型 完整性约束

    今日内容 1.存储引擎表类型 2.数据类型 3.完整性约束 1.存储引擎表类型 指令: 1.show engines:#查看MySQL所有的引擎, 2.show variables like &quo ...

  6. 每天CSS学习之letter-spacing

    letter-spacing是CSS的一个属性,其作用是设置字符之间的距离.letter意为字符. 1.normal:规定字符之间没有额外的空间.该值是默认值.如下示例: p{ letter-spac ...

  7. 8.4 C++标准输入流

    参考:http://www.weixueyuan.net/view/6410.html 总结: 所谓标准输入是指从标准输入设备中输入设备,通常来讲我们可以将标准输入设备理解为键盘. cin是标准输入类 ...

  8. DevExpress ASP.NET Bootstrap Controls v18.2新功能详解(一)

    行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress ASP.NET Boot ...

  9. nw.js的localStorage的物理储存位置

    前言 因为在做美团外卖商家端的nw.js壳子项目,需要保证在壳子里面使用localStorage的数据可以持久化保存. 发现nw可以保存,即使删除应用重写打包也可以保存,所以解决了这个需求,但是还是需 ...

  10. synchronized(九)

    在Java中是有常量池缓存的功能的,就是说如果我先声明了一个String str1 = “a”; 再声明一个一样的字符串的时候,取值是从原地址去取的,也就是说是同一个对象.这也就导致了在锁字符串对象的 ...