#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<easyx.h>#include<mmsystem.h>
#pragma comment(lib, "winmm.lib")#define ROW 10 //定义行列的常量
#define COL 10
#define MineNum 10 //雷的数量
#define ImgSize 40 //图片的尺寸//定义图片资源
IMAGE imgs[12];
void loadResource()
{for (int i = 0; i < 12; i++){char imgPath[50] = { 0 };sprintf_s(imgPath, "./images/%d.jpg", i);loadimage(&imgs[i], imgPath, ImgSize, ImgSize);}
}bool isfirst = true; //是不是第一次进来//函数声明
void show(int map[][COL]);
void init(int map[][COL]);
void draw(int map[][COL]);
void mouseMsg(ExMessage* msg, int map[][COL]);
void boomBlank(int map[][COL], int row, int col);
int judge(int map[][COL], int row, int col);
int main()
{//创建窗口initgraph(400, 400/*,EW_SHOWCONSOLE*/);//播放开始音乐mciSendString("open ./images/start.mp3 alias bgm", NULL, 0, NULL);mciSendString("play bgm", NULL, 0, NULL);//扫雷地图int map[ROW][COL] = {0};init(map);//游戏主循环while (true){//处理消息ExMessage msg;while (peekmessage(&msg, EM_MOUSE)){switch (msg.message){case WM_LBUTTONDOWN: //鼠标左键和右键点击case WM_RBUTTONDOWN:mouseMsg(&msg, map);int ret = judge(map,msg.y/ImgSize, msg.x / ImgSize); //点击之后判断if (ret == -1){draw(map);int select = MessageBox(GetHWnd(), "你这么牛,怎么输了呢?敢再来一把吗?", "low B!", MB_OKCANCEL);if (select == IDOK) //再来一把{//重新初始化init(map);}else //退出{exit(0);}}else if(ret == 1){}system("cls");printf("judege:%d\n", ret);show(map);break;}}draw(map); }//show(map);getchar();return 0;
}void show(int map[][COL])
{for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){printf("%2d ", map[i][k]);}printf("\n");}
}
//初始化数据
void init(int map[][COL])
{loadResource();//设置随机数种子srand((unsigned)time(NULL));//把map全部初始化为0memset(map, 0, sizeof(int) * ROW * COL);//随机设置十个雷 用-1表示for (int i = 0; i < MineNum; ){//数组的有效下标 [0,9]int r = rand() % ROW;int c = rand() % COL;if (map[r][c] == 0){map[r][c] = -1;//只有执行了这里的代码,才成功设置了雷 -1i++;}}//把以雷为中心的九宫格数据都+1,雷除外for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){//找到雷,并遍历雷所在的九宫格if (map[i][k] == -1){for (int r = i-1; r <= i+1; r++){for (int c = k-1; c <= k+1; c++){//对周围的数据加1,会有一个bugif ((r >= 0 && r < ROW && c >= 0 && c < COL) && map[r][c] != -1){++map[r][c];}}}}}}//加密格子for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){map[i][k] += 20;}}
}
//绘制
void draw(int map[][COL])
{//贴图,根据map里面的数据,贴对应的图片for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){if (map[i][k]>=0 && map[i][k]<=8) //[0,8]{int index = map[i][k]; //0 1 2 3 4 5 6 7 8putimage(k * ImgSize, i * ImgSize, &imgs[index]); //}else if (map[i][k] == -1){putimage(k * ImgSize, i * ImgSize, &imgs[9]);}else if (map[i][k] >= 19 && map[i][k] <= 28){putimage(k * ImgSize, i * ImgSize, &imgs[10]);}else if(map[i][k] >= 39) //-1 + 20 +20{putimage(k * ImgSize, i * ImgSize, &imgs[11]);}}}
}
//鼠标操作数据
void mouseMsg(ExMessage* msg,int map[][COL])
{//先根据鼠标点击的坐标求出对应的数组的下标int r = msg->y / ImgSize;int c = msg->x / ImgSize;//左键打开格子if (msg->message == WM_LBUTTONDOWN){//什么时候能够打开,没有打开的时候就打开if (map[r][c]>=19 && map[r][c]<=28){//这个函数只能播放wav格式PlaySound("./images/click.wav", NULL, SND_ASYNC | SND_FILENAME);map[r][c] -= 20;boomBlank(map, r, c); //检测一下是不是空白格子,是,炸开isfirst = true;} }//右键标记格子else if (msg->message == WM_RBUTTONDOWN){PlaySound("./images/rightClick.wav", NULL, SND_ASYNC | SND_FILENAME);//是否能够标记:如果没有打开就能标记if (map[r][c] >= 19 && map[r][c] <= 28){map[r][c] += 20;}else if(map[r][c]>=39){map[r][c] -= 20;}}
}
//点击空白格子,连环爆开周围的所有空白格子还有数字 row col 是当前点击的格子
void boomBlank(int map[][COL],int row,int col)
{ //判断row col位置是不是空白格子if (map[row][col] == 0){for (int r = row-1; r <= row+1; r++){for (int c = col-1; c <= col+1; c++){if ((r>=0&&r<ROW&&c>=0&&c<COL) //没越界&& map[r][c]>=19 && map[r][c]<=28) //没有打开{//每一次调用都会播放一下if (isfirst){PlaySound("./images/search.wav", NULL, SND_ASYNC | SND_FILENAME);isfirst = false;}map[r][c] -= 20;boomBlank(map, r, c);}}}}return;
}
//游戏结束条件 输了返回-1 没结束返回0 赢了返回 1
int judge(int map[][COL],int row ,int col)
{//点到了雷,结束 输了if (map[row][col] == -1 || map[row][col] == 19){return -1;}//点完了格子,结束 赢了 点开了100 - 10 = 90 个格子int cnt = 0;for (int i = 0; i < ROW; i++){for (int k = 0; k < COL; k++){//统计打开的格子的数量if (map[i][k] >= 0 && map[i][k] <= 8){++cnt;}}}if (ROW*COL - MineNum == cnt){return 1;}return 0;
}