建设一站式服务网站,网站开发合同是否要交印花税,长春网站改版,优化seo搜索目录 效果展示
游玩链接#xff08;无需安装图形库及VS#xff09;
开发环境及准备
1.VS2022版本
2.图形库
游戏初始化
1.头文件
2.创建窗口
3.主函数框架
开始界面函数
1.初始化
1-1.设置背景颜色及字体
1-2.处理背景音乐及图片素材
1-3.处理背景图位置
2.选…目录 效果展示
游玩链接无需安装图形库及VS
开发环境及准备
1.VS2022版本
2.图形库
游戏初始化
1.头文件
2.创建窗口
3.主函数框架
开始界面函数
1.初始化
1-1.设置背景颜色及字体
1-2.处理背景音乐及图片素材
1-3.处理背景图位置
2.选择模式
2-1.获取鼠标信息
2-2.处理颜色变化
2-3.判断鼠标按下的键
普通模式
1.随机生成地雷
1-1.清空map数组并播随机数种子。
1-2.随机布雷
2.确定数字
3.判断输赢
画图
递归函数
困难模式
生成日志
1.获取时间
2.输出内容
完整源代码
回顾编程过程 源代码三连博主私信回复“扫雷”领取
效果展示 游玩链接无需安装图形库及VS
怎么样还不错吧快去链接处下载吧
EXE链接下载点我
开发环境及准备
1.VS2022版本 其他版本也可以别太老就行。 2.图形库 本代码用到图形库需要安装。 图形库简介EasyX 是EasyX Graphics Library 是针对 Visual C 的免费绘图库支持 VC6.0 ~VC2022简单易用学习成本极低应用领域广泛。 安装网址EasyX Graphics Library for C 游戏初始化
1.头文件
在游戏过程中需要用到很多头文件包括但不仅限于时间函数图形库……
#include iostream//C头文件
#include time.h//时间函数
#include stdio.h//标准输出输入库
#include graphics.h //图形库
#include mmsystem.h//windows SDK 播放函数
#include fstream //文件库
#include windows.h//windows api
#include string2.创建窗口
因为窗口大小是以像素计数的我们得先提前设定好格子的长和宽像素个数我们用50就够了。
而扫雷一般是有10x10一百个格子的所以我们定义N为每行格子数M为每格像素边长。
#define N 10 //格子数
#define M 50 //一个格子的像素
那么窗口的边长就是每格像素长×格子数N×M。
initgraph(N * M, N * M);//初始化绘图窗口宽500高500像素
3.主函数框架
我们先把主函数写好再去实现相应的功能。 根据扫雷的不同难度游戏划分为“15雷模式”和“35雷模式”增加了挑战性和趣味性。 注意writeLogMsg是生成日志的函数当初是方便我调试的但对游戏体验没有影响。 int main()
{writeLogMsg(天天扫雷开始执行);writeLogMsg(开始界面开始执行);//initgraph(N * M, N * M,EW_SHOWCONSOLE);//, EW_SHOWCONSOLE初始化绘图窗口宽500高500像素initgraph(N * M, N * M);//初始化绘图窗口宽500高500像素//测试日志//int log[4] {0,1,2,3};//writeLog(log, 9);writeLogMsg(开始界面开始执行);StartWindow();//调用开始界面函数。writeLogMsg(开始界面结束执行);//1.设置开始页面背景透明、字体、背景音乐、背景图片2.加载待使用的图片列表。3.判定鼠标位置和点击事件确定用户选择的是15雷模式还是35雷模式if (gamemodel 0) {normalModel();//15雷模式}else {BTmodel();//35雷模式}closegraph();writeLogMsg(天天扫雷结束执行);
}
开始界面函数
1.初始化
1-1.设置背景颜色及字体
因为我们有图片所有不需要有背景颜色即把背景颜色设置为透明色。
setbkmode(TRANSPARENT); //设置背景 透明风格
字体推荐楷体当然你也可以自行调整比如“宋体”“仿宋”……
settextstyle(40, 18, L楷体); //设置开始界面字体大小 L设置字符集
1-2.处理背景音乐及图片素材
音乐为天空之城当然你也可以自己修改。
mciSendString(Lopen ./天空之城.mp3 alias bgm, 0, 0, 0); //L为设置字符集./表示当前文件夹
mciSendString(Lplay bgm repeat, 0, 0, 0);//重复播放bgm
图片素材名称不要打错了加载图片的函数用法如下。
//加载图片
/*
从图片文件获取图像(bmp / gif / jpg / png / tif / emf / wmf / ico)
void loadimage(IMAGE * pDstImg, // 保存图像的 IMAGE 对象指针LPCTSTR pImgFile, // 图片文件名int nWidth 0, // 图片的拉伸宽度int nHeight 0, // 图片的拉伸高度bool bResize false // 是否调整 IMAGE 的大小以适应图片
);
*/ 加载
loadimage(image[0], L./image/blank.jpg, M, M);
loadimage(image[1], L./image/1.jpg, M, M);
loadimage(image[2], L./image/2.jpg, M, M);
loadimage(image[3], L./image/3.jpg, M, M);
loadimage(image[4], L./image/4.jpg, M, M);
loadimage(image[5], L./image/5.jpg, M, M);
loadimage(image[6], L./image/6.jpg, M, M);
loadimage(image[7], L./image/7.jpg, M, M);
loadimage(image[8], L./image/8.jpg, M, M);
loadimage(image[9], L./image/lei.jpg, M, M);
loadimage(image[10], L./image/tag.jpg, M, M);
loadimage(image[11], L./image/start.jpg, N * M, N * M);
loadimage(image[12], L./image/0.jpg, M, M);
1-3.处理背景图位置
放一张图片到窗口的函数是putimage用法及参数如下
/*
// 绘制图像
void putimage(int dstX, // 绘制位置的 x 坐标int dstY, // 绘制位置的 y 坐标IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针DWORD dwRop SRCCOPY // 三元光栅操作码
);
*/ 把开始界面的背景图放到窗口正中间也就是0,0的位置。
putimage(0, 0, image[11]);//将image[11]显示在屏幕上坐标0,0
2.选择模式
2-1.获取鼠标信息
这个函数我试了好多个目前我的版本GetMouseMsg( )是可以的。
MOUSEMSG msg { 0 };//鼠标事件信息
while (1)
{msg GetMouseMsg();//获取鼠标位置存到msg里面
}
2-2.处理颜色变化
当鼠标放到某一个模式上时我们让那个模式的字体颜色变红更加真实美观。
//判断鼠标位置是否在15雷模式上如果在设置颜色为红色
if ((msg.x 180 msg.x 320) ( msg.y 250 msg.y 290))
{settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 250, L15雷模式);//输出 15雷模式 在x180y250//outtextxyS
}
//判断鼠标位置是否在35雷模式上如果在设置颜色为红色
else if ((msg.x 180 msg.x 320) ( msg.y 330 msg.y 370))
{settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 330, L35雷模式);//输出 35雷模式 在x180y330
}
//判断鼠标位置是否在退出上如果在设置颜色为红色
else if (msg.x 180 msg.x 320 msg.y 410 msg.y 450)
{settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 410, L退出);//输出 退出 在x180y410
}
//判断鼠标位置是否在背景部分如果在设置颜色为黑色
else
{settextcolor(RGB(0, 0, 0)); //设置字体颜色为黑色outtextxy(180, 250, L15雷模式);outtextxy(180, 330, L35雷模式);outtextxy(180, 410, L退出);
}
2-3.判断鼠标按下的键
根据不同的坐标执行不同的模式或者退出程序。
其中判断是否按下左键的函数是WM_LBUTTONDOWN按下返回真否则返回假。
switch (msg.uMsg)
{case WM_LBUTTONDOWN://当点击鼠标左键后判定鼠标坐标位置。//如果以下坐标区域则设置为正常模式0if (msg.x 180 msg.x 320 msg.y 250 msg.y 290) {gamemodel 0;//将游戏模式设为015雷模式return;}//如果以下坐标区域则设置为风控模式1else if (msg.x 180 msg.x 320 msg.y 330 msg.y 370) {gamemodel 1;//将游戏模式设为135雷模式return;}//如果以下坐标区域则退出游戏else if (msg.x 180 msg.x 320 msg.y 410 msg.y 450) {exit(0);//退出游戏终止}
}
普通模式
1.随机生成地雷
1-1.清空map数组并播随机数种子。
srand((unsigned)time(NULL));//播种随机数种子
for (int i 0; i N 2; i)
{for (int j 0; j N 2; j){map[i][j] 0;//把该数组的位置归0}
}
1-2.随机布雷
while (flag 15)//控制总雷数不超过15个
{x rand() % 10 1;//随机生成在第几行1-10行y rand() % 10 1;//随机生成在第几列1-10列//随机方格坐标string msgXY may[ to_string(x) ][ to_string(y ) ]当前数值value is to_string(map[x][y]);if (map[x][y] ! -1) //随机获取坐标为map[x][y]的值判定是否不等于-1-1表示雷如果等于-1则表示该位置已经是雷。{map[x][y] -1;//如果不等于-1则赋值该位置为-1布雷flag;//总雷数增加1个writeLogMsg(may[ to_string(x) ][ to_string(y) ] 当前数值value is to_string(map[x][y]) 埋雷成功累计埋雷个数 to_string(flag));}
}
2.确定数字
遍历整个数组看八个方向有一个雷就1。
for (int i 1; i N; i) //扫描数组10X10显示部分
{//writeLogMsg(扫描第【to_string(i)】行开始执行);for (int j 1; j N; j){squ_num;if (map[i][j] ! -1)//如果这个数组的位置不是-1即表示不是地雷{//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】不是雷开始扫描周围雷总数。当前map【】【】 valuse isto_string(map[i][j]));for (int m i - 1; m i 1; m) //扫描包含该数字周围的九个格子{for (int n j - 1; n j 1; n){if (map[m][n] -1){map[i][j];//确定除了雷每个格子中间数字也就是周围八个格子的总雷数 } } }//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】不是雷扫描周围雷总数共计map[i][j]值为 to_string(map[i][j]) 个); }else{//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】是雷,不扫锚周围map[i][j]值为 to_string(map[i][j]) );}}//writeLogMsg(扫描第【 to_string(i) 】行结束执行);
}
3.判断输赢 这里用到了一个函数DrawGraph( )是用来画图显示的下面会讲。 while (1)
{whileCount;writeLogMsg(根据map[i][j]存放数值设置对应图片开始执行);DrawGraph();//更新雷的图片数字对应的图片writeLogMsg(根据map[i][j]存放数值设置对应图片结束执行);type MouseClick();if (type -1) //判断用户是否点到雷了{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L很遗憾失败, MB_ICONINFORMATION |MB_OK) IDOK) break;//输出提示框}if (win 0)//判断用户是否赢了胜利条件为除了雷的所有方块点完即可{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L恭喜成功, MB_ICONINFORMATION |MB_OK) IDOK) break;//输出提示框}writeLogMsg(type MouseClick()当前type值》 to_string(type));writeLogMsg(win当前win值》 to_string(win));writeLogMsg(设置图片循环次数 to_string(whileCount));
}
画图
这个函数是程序的精髓特别难理解一定要多推敲推敲
int count_num0;//计数器方格数
for (int i 1; i N; i)
{for (int j 1; j N; j) {count_num;//writeLogMsg(DrawGraph当前扫描第【 to_string(count_num) 】map【 to_string(i) 】行第【 to_string(j) 】map[i][j]值为 to_string(map[i][j]));switch (map[i][j]){case 9:putimage((i - 1) * M, (j - 1) * M, image[9]); break;case 10:putimage((i - 1) * M, (j - 1) * M, image[0]); break;case 11:putimage((i - 1) * M, (j - 1) * M, image[1]); break;case 12:putimage((i - 1) * M, (j - 1) * M, image[2]); break;case 13:putimage((i - 1) * M, (j - 1) * M, image[3]); break;case 14:putimage((i - 1) * M, (j - 1) * M, image[4]); break;case 15:putimage((i - 1) * M, (j - 1) * M, image[5]); break;case 16:putimage((i - 1) * M, (j - 1) * M, image[6]); break;case 17:putimage((i - 1) * M, (j - 1) * M, image[7]); break;case 18:putimage((i - 1) * M, (j - 1) * M, image[8]); break;case 29:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 30:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 31:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 32:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 33:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 34:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 35:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 36:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 37:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 38:putimage((i - 1) * M, (j - 1) * M, image[10]); break;default:putimage((i - 1) * M, (j - 1) * M, image[12]); break;}}
}
递归函数 通过不断地递归调用自己来实现点一大片的情况。 void loadingPlay(int x, int y)
{map[x][y] 10;win--;for (int i x - 1; i x 1; i) {for (int j y - 1; j y 1; j) {if (i 0 || i 11 || j 0 || j 11) continue; //防止越界if (map[i][j] 8) {if (map[i][j] 0) {loadingPlay(i, j);}else if (map[i][j] ! -1) {map[i][j] 10;win--;}}}}
}
困难模式 思路和普通模式一样就不解析了有注释。 {while (1){cleardevice();//清屏win N * N - 35;//设置胜利条件为把除了雷的所有方块点完即可int type 0;HWND hWnd GetHWnd();//这个函数用于获取绘图窗口句柄int x, y, flag 0;srand((unsigned)time(NULL));//播种随机数种子//通过双重for循环把所有数组归零for (int i 0; i N 2; i) {for (int j 0; j N 2; j) {map[i][j] 0;//把该数组的位置归0}}//布雷循环while (flag 35)//控制总雷数不超过35个{x rand() % 10 1;//随机生成在第几行y rand() % 10 1;//随机生成在第几列if (map[x][y] ! -1) //为了判断所生成的雷有没有重复{map[x][y] -1;//将此数组设为-1-1表示雷flag;//总雷数增加1个}}//布数字for (int i 1; i N; i) //扫描数组10X10显示部分{for (int j 1; j N; j){if (map[i][j] ! -1)//如果这个数组的位置不是-1地雷{for (int m i - 1; m i 1; m) //扫描包含该数字周围的九个格子{for (int n j - 1; n j 1; n){if (map[m][n] -1){map[i][j];//确定除了雷每个格子中间数字也就是周围八个格子的总雷数}}}}}}//判断输赢while (1){DrawGraph();type MouseClick();if (type -1) //判断用户是否点到雷了{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L很遗憾失败, MB_ICONINFORMATION|MB_OK) IDOK) break;//输出提示框}if (win 0)//判断用户是否赢了 {DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L恭喜成功, MB_ICONINFORMATION| MB_OK) IDOK) break;//输出提示框}}}
}
生成日志
1.获取时间 用到函数SYSTEMTIME可以调取年月日时秒分。 2.输出内容
你想看到的后台调试信息都可以放进去。
for (int i 0; i count; i)
{cout log.txt 【Write】第 i 行 endl;myFile 【 sys.wYear - sys.wMonth - sys.wDay sys.wHour sys.wMinute sys.wSecond . sys.wMilliseconds 星期 sys.wDayOfWeek 】 \t squ[0] \t squ[1] \t squ[2] \t squ[3] endl;
}
完整源代码
#includeiostream//C头文件
#includetime.h//时间函数
#includestdio.h//标准输出输入库
#includegraphics.h //图形库 EasyX 是EasyX Graphics Library 是针对 Visual C 的免费绘图库支持 VC6.0 ~VC2022简单易用学习成本极低应用领域广泛
#includemmsystem.h//windows SDK 播放函数#include fstream //文件库
#include windows.h//windows api
#includestring//#pragma comment(lib,winmm.lib)
#define N 10 //格子数
#define M 50 //一个格子的像素
using namespace std;//命名空间IMAGE image[13]; //存放图片数量为13张
int map[N 2][N 2]; //定义整形12行12列二维数组
int gamemodel;//定义游戏模式
int win N * N - 15;
void StartWindow(); //开始界面
void normalModel(); //15雷模式
void BTmodel(); //35雷模式
void DrawGraph(); //画扫雷地图
int MouseClick(); //鼠标点击事件
void loadingPlay(int x, int y); //定义loadingPlay函数为了运用递归实现点击一大片//void writeLog(int a [],int b);
void writeLogMsg(string msgStr);
int map_num;//map格子编号
int SquareInfo[4];//定义单个方格信息整型数组 用来存在单方格的基本信息。包括方格编号方格数值方格x,y坐标值。
int squ_num;//方格编号 从左往右从第一行到最后一行计数编号。
int squ_value;//方格存放数值
int index_x;//定义格子坐标 X表示横Y表示纵
int index_y;
int Square[100][4];//存放100个方格基本信息int main() {writeLogMsg(天天扫雷开始执行);writeLogMsg(开始界面开始执行);//initgraph(N * M, N * M,EW_SHOWCONSOLE);//, EW_SHOWCONSOLE初始化绘图窗口宽500高500像素initgraph(N * M, N * M);//初始化绘图窗口宽500高500像素//测试日志//int log[4] {0,1,2,3};//writeLog(log, 9);writeLogMsg(开始界面开始执行);StartWindow();//调用开始界面函数。writeLogMsg(开始界面结束执行);//1.设置开始页面背景透明、字体、背景音乐、背景图片2.加载待使用的图片列表。3.判定鼠标位置和点击事件确定用户选择的是15雷模式还是35雷模式if (gamemodel 0) {normalModel();//15雷模式}else {BTmodel();//35雷模式}closegraph();writeLogMsg(天天扫雷结束执行);
}
void StartWindow() {writeLogMsg(设置界面背景、字体开始执行);setbkmode(TRANSPARENT); //设置背景 透明风格settextstyle(40, 18, L楷体);//设置开始界面字体大小 L设置字符集//初始化页面//播放音乐writeLogMsg(设置界面背景、字体结束执行);writeLogMsg(设置播放背景音乐开始执行);mciSendString(Lopen ./天空之城.mp3 alias bgm, 0, 0, 0); //L为设置字符集./表示当前文件夹mciSendString(Lplay bgm repeat, 0, 0, 0);//重复播放bgmwriteLogMsg(设置播放背景音乐结束执行);//加载图片/* 从图片文件获取图像(bmp / gif / jpg / png / tif / emf / wmf / ico)void loadimage(IMAGE * pDstImg, // 保存图像的 IMAGE 对象指针LPCTSTR pImgFile, // 图片文件名int nWidth 0, // 图片的拉伸宽度int nHeight 0, // 图片的拉伸高度bool bResize false // 是否调整 IMAGE 的大小以适应图片);*/writeLogMsg(加载图片资源开始执行);loadimage(image[0], L./image/blank.jpg, M, M);loadimage(image[1], L./image/1.jpg, M, M);loadimage(image[2], L./image/2.jpg, M, M);loadimage(image[3], L./image/3.jpg, M, M);loadimage(image[4], L./image/4.jpg, M, M);loadimage(image[5], L./image/5.jpg, M, M);loadimage(image[6], L./image/6.jpg, M, M);loadimage(image[7], L./image/7.jpg, M, M);loadimage(image[8], L./image/8.jpg, M, M);loadimage(image[9], L./image/lei.jpg, M, M);loadimage(image[10], L./image/tag.jpg, M, M);loadimage(image[11], L./image/start.jpg, N * M, N * M);loadimage(image[12], L./image/0.jpg, M, M);writeLogMsg(加载图片资源开始执行);/*// 绘制图像
void putimage(int dstX, // 绘制位置的 x 坐标int dstY, // 绘制位置的 y 坐标IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针DWORD dwRop SRCCOPY // 三元光栅操作码
);*/writeLogMsg(设置开始界面显示图片开始执行);putimage(0, 0, image[11]);//将image[11]显示在屏幕上坐标0,0writeLogMsg(设置开始界面显示图片结束执行);writeLogMsg(获取鼠标事件信息、设置15、35雷模式字体坐标区域开始执行);MOUSEMSG msg { 0 };//鼠标事件信息while (1) {msg GetMouseMsg();//获取鼠标位置存到msg里面//判断鼠标位置是否在15雷模式上如果在设置颜色为红色if ((msg.x 180 msg.x 320) ( msg.y 250 msg.y 290)){settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 250, L15雷模式);//输出 15雷模式 在x180y250//outtextxyS}//判断鼠标位置是否在35雷模式上如果在设置颜色为红色else if ((msg.x 180 msg.x 320) ( msg.y 330 msg.y 370)){settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 330, L35雷模式);//输出 35雷模式 在x180y330}//判断鼠标位置是否在退出上如果在设置颜色为红色else if (msg.x 180 msg.x 320 msg.y 410 msg.y 450){settextcolor(RGB(255, 0, 0)); //设置字体颜色红色outtextxy(180, 410, L退出);//输出 退出 在x180y410}//判断鼠标位置是否在背景部分如果在设置颜色为黑色else{settextcolor(RGB(0, 0, 0)); //设置字体颜色为黑色outtextxy(180, 250, L15雷模式);outtextxy(180, 330, L35雷模式);outtextxy(180, 410, L退出);}switch (msg.uMsg){case WM_LBUTTONDOWN://当点击鼠标左键后判定鼠标坐标位置。//如果以下坐标区域则设置为正常模式0if (msg.x 180 msg.x 320 msg.y 250 msg.y 290) {gamemodel 0;//将游戏模式设为015雷模式return;}//如果以下坐标区域则设置为风控模式1else if (msg.x 180 msg.x 320 msg.y 330 msg.y 370) {gamemodel 1;//将游戏模式设为135雷模式return;}//如果以下坐标区域则退出游戏else if (msg.x 180 msg.x 320 msg.y 410 msg.y 450) {exit(0);//退出游戏终止}}}writeLogMsg(获取鼠标事件信息、设置15、35雷模式字体坐标区域结束执行);
}
void normalModel()//15雷模式普通模式
{writeLogMsg(15雷模式开始执行);while (1){cleardevice();//清屏win N * N - 15;//设置胜利条件为把除了雷的所有方块点完即可int type 0;HWND hWnd GetHWnd();//GetHWnd()这个函数用于获取绘图窗口句柄int x, y, flag 0;srand((unsigned)time(NULL));//播种随机数种子writeLogMsg(初始化map[][]每个坐标的值开始执行);//通过双重for循环把所有数组归零for (int i 0; i N 2; i) {for (int j 0; j N 2; j){map[i][j] 0;//把该数组的位置归0}}writeLogMsg(初始化map[][]每个坐标的值结束执行);//随机布雷writeLogMsg(随机布雷开始执行);while (flag 15)//控制总雷数不超过15个{x rand() % 10 1;//随机生成在第几行1-10行y rand() % 10 1;//随机生成在第几列1-10列//随机方格坐标string msgXY may[ to_string(x) ][ to_string(y ) ]当前数值value is to_string(map[x][y]);if (map[x][y] ! -1) //随机获取坐标为map[x][y]的值判定是否不等于-1-1表示雷如果等于-1则表示该位置已经是雷。{map[x][y] -1;//如果不等于-1则赋值该位置为-1布雷flag;//总雷数增加1个writeLogMsg(may[ to_string(x) ][ to_string(y) ] 当前数值value is to_string(map[x][y]) 埋雷成功累计埋雷个数 to_string(flag));}}writeLogMsg(随机布雷结束执行);writeLogMsg(计算每个方格周围雷数量开始执行);//计算除了已布雷的格子之外每个格子周围雷的数量并确定数字for (int i 1; i N; i) //扫描数组10X10显示部分{//writeLogMsg(扫描第【to_string(i)】行开始执行);for (int j 1; j N; j){squ_num;if (map[i][j] ! -1)//如果这个数组的位置不是-1即表示不是地雷{//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】不是雷开始扫描周围雷总数。当前map【】【】 valuse isto_string(map[i][j]));for (int m i - 1; m i 1; m) //扫描包含该数字周围的九个格子{for (int n j - 1; n j 1; n){if (map[m][n] -1){map[i][j];//确定除了雷每个格子中间数字也就是周围八个格子的总雷数}}}//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】不是雷扫描周围雷总数共计map[i][j]值为 to_string(map[i][j]) 个);}else{//writeLogMsg(方格编号【 to_string(squ_num) 】扫描第map【 to_string(i) 】行第【 to_string(j) 】是雷,不扫锚周围map[i][j]值为 to_string(map[i][j]) );}}//writeLogMsg(扫描第【 to_string(i) 】行结束执行);}writeLogMsg(计算每个方格周围雷数量结束执行);//判断输赢int whileCount 0;while (1){whileCount;writeLogMsg(根据map[i][j]存放数值设置对应图片开始执行);DrawGraph();//更新雷的图片数字对应的图片writeLogMsg(根据map[i][j]存放数值设置对应图片结束执行);type MouseClick();if (type -1) //判断用户是否点到雷了{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L很遗憾失败, MB_ICONINFORMATION |MB_OK) IDOK) break;//输出提示框}if (win 0)//判断用户是否赢了胜利条件为除了雷的所有方块点完即可{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L恭喜成功, MB_ICONINFORMATION |MB_OK) IDOK) break;//输出提示框}writeLogMsg(type MouseClick()当前type值》 to_string(type));writeLogMsg(win当前win值》 to_string(win));writeLogMsg(设置图片循环次数 to_string(whileCount));}}writeLogMsg(15雷模式结束执行);
}
void BTmodel() //35雷模式疯狂模式
{while (1){cleardevice();//清屏win N * N - 35;//设置胜利条件为把除了雷的所有方块点完即可int type 0;HWND hWnd GetHWnd();//这个函数用于获取绘图窗口句柄int x, y, flag 0;srand((unsigned)time(NULL));//播种随机数种子//通过双重for循环把所有数组归零for (int i 0; i N 2; i) {for (int j 0; j N 2; j) {map[i][j] 0;//把该数组的位置归0}}//布雷循环while (flag 35)//控制总雷数不超过35个{x rand() % 10 1;//随机生成在第几行y rand() % 10 1;//随机生成在第几列if (map[x][y] ! -1) //为了判断所生成的雷有没有重复{map[x][y] -1;//将此数组设为-1-1表示雷flag;//总雷数增加1个}}//布数字for (int i 1; i N; i) //扫描数组10X10显示部分{for (int j 1; j N; j){if (map[i][j] ! -1)//如果这个数组的位置不是-1地雷{for (int m i - 1; m i 1; m) //扫描包含该数字周围的九个格子{for (int n j - 1; n j 1; n){if (map[m][n] -1){map[i][j];//确定除了雷每个格子中间数字也就是周围八个格子的总雷数}}}}}}//判断输赢while (1){DrawGraph();type MouseClick();if (type -1) //判断用户是否点到雷了{DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L很遗憾失败, MB_ICONINFORMATION|MB_OK) IDOK) break;//输出提示框}if (win 0)//判断用户是否赢了 {DrawGraph();if (MessageBox(hWnd, L按下确定重玩, L恭喜成功, MB_ICONINFORMATION| MB_OK) IDOK) break;//输出提示框}}}
}
void DrawGraph()
{int count_num0;//计数器方格数for (int i 1; i N; i){for (int j 1; j N; j) {count_num;//writeLogMsg(DrawGraph当前扫描第【 to_string(count_num) 】map【 to_string(i) 】行第【 to_string(j) 】map[i][j]值为 to_string(map[i][j]));switch (map[i][j]){case 9:putimage((i - 1) * M, (j - 1) * M, image[9]); break;case 10:putimage((i - 1) * M, (j - 1) * M, image[0]); break;case 11:putimage((i - 1) * M, (j - 1) * M, image[1]); break;case 12:putimage((i - 1) * M, (j - 1) * M, image[2]); break;case 13:putimage((i - 1) * M, (j - 1) * M, image[3]); break;case 14:putimage((i - 1) * M, (j - 1) * M, image[4]); break;case 15:putimage((i - 1) * M, (j - 1) * M, image[5]); break;case 16:putimage((i - 1) * M, (j - 1) * M, image[6]); break;case 17:putimage((i - 1) * M, (j - 1) * M, image[7]); break;case 18:putimage((i - 1) * M, (j - 1) * M, image[8]); break;case 29:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 30:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 31:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 32:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 33:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 34:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 35:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 36:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 37:putimage((i - 1) * M, (j - 1) * M, image[10]); break;case 38:putimage((i - 1) * M, (j - 1) * M, image[10]); break;default:putimage((i - 1) * M, (j - 1) * M, image[12]); break;}}}
}
int MouseClick()
{MOUSEMSG msg { 0 };int loadingPlayCout 0;while (1) {msg GetMouseMsg();writeLogMsg(MouseClick循环while开始执行msg.x》【 to_string( msg.x)】msg.y》【 to_string(msg.y)】);switch (msg.uMsg){case WM_LBUTTONDOWN:writeLogMsg(msg.uMsg.WM_LBUTTONDOWN正在点击左键);if (map[msg.x / M 1][msg.y / M 1] 0) {writeLogMsg(map【to_string( msg.x / M) 】【 to_string(msg.y / M) 】的值是to_string(map[msg.x / M][msg.x / M]));writeLogMsg(当前方格周围没有雷);writeLogMsg(开始加载loadingPlay 没有雷更换为无雷的图片递归循环判断);loadingPlay(msg.x / M 1, msg.y / M 1);loadingPlayCout;writeLogMsg(当前loadingPlayCout的值得是 to_string(loadingPlayCout));writeLogMsg(结束加载loadingPlay);}else if (map[msg.x / M 1][msg.y / M 1] 8) {writeLogMsg(当前方格周围有雷);writeLogMsg(map[][]8开始执行);writeLogMsg(map【 to_string(msg.x / M) 】【 to_string(msg.y / M) 】的值是 to_string(map[msg.x / M][msg.x / M]));map[msg.x / M 1][msg.y / M 1] 10;win--;writeLogMsg(当前win的值是to_string(win));writeLogMsg(map[][]8结束执行);}if (map[msg.x / M 1][msg.y / M 1] 9) {writeLogMsg(map[][]等于9);return -1;}break;case WM_RBUTTONDOWN:writeLogMsg(msg.uMsg.WM_LBUTTONDOWN正在点击右键);if (map[msg.x / M 1][msg.y / M 1] 8) {writeLogMsg(map[][]8开始执行);map[msg.x / M 1][msg.y / M 1] 30;}else if (map[msg.x / M 1][msg.y / M 1] 29) {writeLogMsg(map[][]29开始执行);map[msg.x / M 1][msg.y / M 1] - 30;}break;}writeLogMsg(MouseClick循环while结束执行 );return 0;}}
void loadingPlay(int x, int y) {map[x][y] 10;win--;for (int i x - 1; i x 1; i) {for (int j y - 1; j y 1; j) {if (i 0 || i 11 || j 0 || j 11) continue; //防止越界if (map[i][j] 8) {if (map[i][j] 0) {loadingPlay(i, j);}else if (map[i][j] ! -1) {map[i][j] 10;win--;}}}}}void writeLog(int squ[], int n){//获取当前系统时间SYSTEMTIME sys;GetLocalTime(sys);fstream myFile;myFile.open(log.txt, ios::out | ios::binary);if (!myFile) {cout log.txt cant open! endl;abort();}int count n;myFile 累计行数count endl;for (int i 0; i count; i) {cout log.txt 【Write】第 i 行 endl;myFile 【 sys.wYear - sys.wMonth - sys.wDay sys.wHour sys.wMinute sys.wSecond . sys.wMilliseconds 星期 sys.wDayOfWeek 】 \t squ[0] \t squ[1] \t squ[2] \t squ[3] endl;}myFile.close();
}void writeLogMsg(string msg) {//获取当前系统时间SYSTEMTIME sys;GetLocalTime(sys);fstream myFile;myFile.open(log.txt, ios::out | ios::app);if (!myFile) {cout log.txt cant open! endl;abort();}myFile 【 sys.wYear - sys.wMonth - sys.wDay sys.wHour sys.wMinute sys.wSecond . sys.wMilliseconds 星期 sys.wDayOfWeek 】 \t msg endl;myFile.close();/*#includefstream
#includeiostream
using namespace std;
int main()
{fstream f;//追加写入,在原来基础上加了ios::app f.open(data.txt,ios::out|ios::app);//输入你想写入的内容 f今天天气不错endl;f.close();return 0;
}*/}回顾编程过程
今天我们一起探索了奇妙的扫雷游戏。运用到了很多知识点有我们的老朋友递归也有我们的新朋友日志。本篇文章制作不易断更3周都在写这一篇。
本篇文章共20198字真得不值得三连吗