一、新建项目

二、新建源文件

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. 4.4基于switch语句的译码器

    Q:已知前缀码如右图所示,求0/1字符串“001011101001011001”相对应的译码. a b c 1 01 001 #include<iostream> #include< ...

  2. PC/FORTH 判定

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  3. Java小程序分析

    public class Helloworld { public static void main(String[] args) { System.out.println("hello wo ...

  4. mysql中sql查询使用注意

    1.注意DESC关键字仅适用于在它前面的列名(birth):不影响species列的排序顺序. SELECT name, species, birth FROM pet ORDER BY specie ...

  5. L1-055 谁是赢家

    某电视台的娱乐节目有个表演评审环节,每次安排两位艺人表演,他们的胜负由观众投票和 3 名评委投票两部分共同决定.规则为:如果一位艺人的观众票数高,且得到至少 1 名评委的认可,该艺人就胜出:或艺人的观 ...

  6. 第二节 java流程控制(循环结构)

     1.for循环 for(初始化表达式;循环条件表达式;循环后的操作表达式){ 执行语句 } 2.while循环 while(条件表达式){ 执行语句 } while循环特点是只有条件满足才会执行我们 ...

  7. 界面控件DevExpress发布v18.2.5|附下载

    DevExpress Universal Subscription(又名DevExpress宇宙版或DXperience Universal Suite)是全球使用广泛的.NET用户界面控件套包,De ...

  8. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(二)[超详细教程] ubuntu16.04版本

    本节对应谷歌开源Tensorflow Object Detection API物体识别系统 Quick Start步骤(一): Quick Start: Jupyter notebook for of ...

  9. IDEA中安装ibatis插件

    若想在IDEA中使数据库的相关配置能够快速链接即Ctrl+单击跳转,则安装插件 效果如图,跳转成功

  10. <Spark><Spark Streaming>

    Overview Spark Streaming为用户提供了一套与batch jobs十分相似的API,以编写streaming应用 与Spark的基本概念RDDs类似,Spark Streaming ...