实现功能:
1.左键翻开
2.右键标记
3.选择简单,中等,困难三个难度
4.左右键同时按下,当标记数量相匹配时自动翻开
5.角块不藏雷
6.需要自己配置图片(jpg格式),loadimage函数中有注释
#include#include #include #include #include #include #include #include #include #include #pragma comment(lib,"winmm.lib") #define SIZE 35 int ROW, COL, NUM; //行数 列数 雷数 int count; //已经翻开的个数 int c_mine; //已经标记个数 int map[40][20]; //定义二维数组地图 IMAGE img[20]; //图片 //初始化函数 void GameInit() { srand((unsigned int)time(NULL)); //获得随机种子 for (int i = 0; i < ROW+2; i++) { //初始化地图 for (int j = 0; j < COL+2; j++) { map[i][j] = 0; } } int n = 0; while (n < NUM) { //随机布雷 int r = rand() % ROW+1; int c = rand() % COL+1; if (map[r][c] == 0 ) { //判断是否已经布雷 if ((r == 1 && c == 1) || (r == 1 && c == COL) || (r == ROW && c == 1) || (r == ROW && c == COL)) {//角块不藏雷 continue; } map[r][c] = -1; n++; } } for (int i = 1; i <= ROW; i++) { //填充数字 for (int j = 1; j <= COL; j++) { if (map[i][j] != -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]++; } } } } } } for (int i = 1; i <= ROW; i++) { //加密覆盖空白图片 for (int j = 1; j <= COL; j++) { map[i][j] += 20; } } } //自动翻开零块 void OpenZero(int r,int c) { map[r][c] -= 20; count++; //递归翻开所有非雷块 for (int m = r - 1; m <= r + 1; m++) { for (int n = c - 1; n <= c + 1; n++) { if (m >= 1 && m <= ROW && n >= 1 && n <= COL) { if (map[m][n] >= 19 && map[m][n] <= 28) { if (map[m][n] != 20) { map[m][n] -= 20; count++; } else { //如果是零块继续递归翻开 OpenZero(m, n); } } } } } } //游戏函数 int PlayGame() { MOUSEMSG msg = { 0 }; //定义鼠标对象 int r, c; int m_count = 0; //九宫格内标记的个数 while (1) { msg = GetMouseMsg(); //获取鼠标信息 if (msg.mkLButton && msg.mkRButton) { //当左右键同时按下 r = msg.x / SIZE + 1; c = msg.y / SIZE + 1; if (map[r][c] >= 0 && map[r][c] <= 7) { //计算九宫格标记数量 for (int m = r - 1; m <= r + 1; m++) { for (int n = c - 1; n <= c + 1; n++) { if (map[m][n] >= 69) { m_count++; } } } if (m_count == map[r][c]) { //如果标记数量等于中心数字,自动翻开 for (int m = r - 1; m <= r + 1; m++) { for (int n = c - 1; n <= c + 1; n++) { if (map[m][n] == 20) { //零块调用函递归数 OpenZero(m, n); } else if (map[m][n]>20 && map[m][n]<=28) { //数字块正常翻开 map[m][n] -= 20; count++; } else if (map[m][n] == 19) { //雷块游戏结束 map[m][n] -= 20; return -1; } } } } } } switch (msg.uMsg) { //判断左右键 case WM_LBUTTONDOWN: //左键翻开空白块 r = msg.x / SIZE + 1; c = msg.y / SIZE + 1; if (map[r][c] >= 19 && map[r][c] <= 28) { if (map[r][c] == 20) { OpenZero(r,c); } else { map[r][c] -= 20; count++; } } return(map[r][c]); break; case WM_RBUTTONDOWN: //右键标记 r = msg.x / SIZE + 1; c = msg.y / SIZE + 1; if (map[r][c] >= 19 && map[r][c] <= 28) { //标记 map[r][c] += 50; c_mine++; } else if (map[r][c] > 30) { //取消标记 map[r][c] -= 50; c_mine--; } return(map[r][c]); break; } } } //绘制函数 void GameDraw() { for (int i = 1; i <= ROW; i++) { //遍历 for (int j = 1; j <= COL; j++) { if (map[i][j] >= 0 && map[i][j] <= 8) { //数字 putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[map[i][j]]); } else if (map[i][j] >= 19 && map[i][j] <= 28) { //空白 putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[10]); } else if (map[i][j] >= 69 && map[i][j] <= 78) { //标记 putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[11]); } } } int temp = NUM - c_mine; //展示剩余雷的个数 wchar_t t[3]; _itow_s(temp, t, 10); outtextxy(50, COL * SIZE, L"The number of remaining:"); outtextxy(221, COL * SIZE, t); if (temp < 10) { putimage(230, COL * SIZE, &img[0]); } } //展示结果 void ShowResult() { for (int i = 1; i <= ROW; i++) { //遍历 for (int j = 1; j <= COL; j++) { if (map[i][j] == -1) { //踩到的雷 putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[9]); } if (map[i][j] >= 0 && map[i][j] <= 8) { //数字 putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[map[i][j]]); } else if (map[i][j] == 19) { putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[14]); //未翻开的雷 } else if (map[i][j] == 69) { putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[12]); // 标记正确 } else if (map[i][j] >= 70 && map[i][j] <= 78) { putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[13]); //标记错误 } } } } //绘制主界面 void DrawMenu() { initgraph(400, 300); //绘制界面和加载图片 loadimage(&img[17], L"easy.jpg", 400, 100); loadimage(&img[18], L"mid.jpg", 400, 100); loadimage(&img[19], L"hard.jpg", 400, 100); putimage(0, 0, &img[17]); putimage(0, 100, &img[18]); putimage(0, 200, &img[19]); while (1) { MOUSEMSG msg = { 0 }; int r, c; msg = GetMouseMsg(); if (msg.uMsg == WM_LBUTTONDOWN) { if (msg.x >= 0 && msg.x <= 400) { //简单模式 if (msg.y > 0 && msg.y <= 100) { ROW = COL = 8; NUM = 10; break; } else if (msg.y > 100 && msg.y <= 200) { //中等模式 ROW = COL = 16; NUM = 40; break; } else if (msg.y > 200 && msg.y <= 300) { //困难模式 ROW = 30; COL = 16; NUM = 99; break; } } } } } //加载图片 void LoadImg() { loadimage(&img[0], L"0.jpg", SIZE, SIZE); loadimage(&img[1], L"1.jpg", SIZE, SIZE); loadimage(&img[2], L"2.jpg", SIZE, SIZE); loadimage(&img[3], L"3.jpg", SIZE, SIZE); loadimage(&img[4], L"4.jpg", SIZE, SIZE); loadimage(&img[5], L"5.jpg", SIZE, SIZE); loadimage(&img[6], L"6.jpg", SIZE, SIZE); loadimage(&img[7], L"7.jpg", SIZE, SIZE); loadimage(&img[8], L"8.jpg", SIZE, SIZE); loadimage(&img[9], L"9.jpg", SIZE, SIZE); //点开的雷 loadimage(&img[10], L"10.jpg", SIZE, SIZE); //空 loadimage(&img[11], L"11.jpg", SIZE, SIZE); //标 loadimage(&img[12], L"12.jpg", SIZE, SIZE); //标记正确 loadimage(&img[13], L"13.jpg", SIZE, SIZE); //标记错误 loadimage(&img[14], L"14.jpg", SIZE, SIZE); //未标记的雷 loadimage(&img[15], L"15.jpg", SIZE, SIZE); //失败 } int main() { my_begin:; count = 0; //计数初始化 c_mine = 0; DrawMenu(); LoadImg(); HWND hwnd = initgraph(ROW * SIZE, COL * SIZE+20); //绘制游戏界面 setbkcolor(WHITE); setfillcolor(WHITE); fillrectangle(0,0, ROW * SIZE, COL * SIZE + 20); settextcolor(BLACK); GameInit(); while (1) { GameDraw(); if (PlayGame() == -1) { //失败 ShowResult(); mciSendString(L"open music01.wav alias m01", 0, 0, 0); mciSendString(L"play m01", 0, 0, 0); MessageBox(hwnd, L"WIN!", L"", MB_OK); mciSendString(L"close m01", 0, 0, 0); break; } if (ROW * COL - NUM == count) { //成功 ShowResult(); mciSendString(L"open music02.wav alias m02", NULL, 0, NULL); mciSendString(L"play m02", NULL, 0, NULL); MessageBox(hwnd, L"Lose!", L"", MB_OK); mciSendString(L"close m02", NULL, 0, NULL); break; } } goto my_begin; closegraph(); return 0; }



