扫雷游戏基础玩法实现
#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 IMGW 40 #define MineNum 10 void initMap(int map[ROW][COL]); //初始化地图 void drawMap(int map[ROW][COL], IMAGE img[]); //地图贴图 void mouseEvent(int map[ROW][COL]); //鼠标点击操作(左键打开,右键标记) void openNull(int map[ROW][COL], int row, int col); //递归打开空白格 void judge_1(int map[ROW][COL], int row, int col); //若点到雷,则遍历数组,显示所有雷 void judge_2(int map[ROW][COL], int row, int col); //判定标记的格子是否为雷,并返回胜利条件 bool isOver = false; //结束标记 bool victory = false; //胜利标记 int main() { initgraph(COL * IMGW, ROW * IMGW); mciSendString(_T("open ./images/start.mp3 alias bgm"), NULL, 0, NULL); mciSendString(_T("play bgm"), NULL, 0, NULL); srand((unsigned)time(NULL)); //随机数种子 int map[ROW][COL] = {0}; //定义游戏地图 initMap(map); //初始化地图 IMAGE img[12]; //定义图片数组 for (int i = 0; i < 12; i++) //加载图片 { char fileName[50] = {0}; sprintf_s(fileName, "./images/%d.jpg", i); loadimage(img + i, _T(fileName), IMGW, IMGW); } while (true) { mouseEvent(map); drawMap(map, img); if (isOver) { int ret = MessageBox(GetHWnd(), _T("铁Five"), _T("shit"), MB_OKCANCEL); if (ret == IDOK) { initMap(map); isOver = false; } else if (ret == IDCANCEL) { exit(0); } } else if (victory) { int ret = MessageBox(GetHWnd(), _T("恭喜你,铁five!"), _T("Congratulations!"), MB_OKCANCEL); if (ret == IDOK) { initMap(map); victory = false; } else if (ret == IDCANCEL) { exit(0); } } } return 0; } void initMap(int map[ROW][COL]) { memset(map, 0, ROW * COL * sizeof(int)); for (int i = 0; i < MineNum;) //地图里埋10个雷,用-1表示 { int r = rand() % ROW; //控制随机数在[0,9) int c = rand() % COL; if (map[r][c] == 0) { map[r][c] = -1; i++; //成功设置不重复的雷,计数才增加 } } for (int i = 0; i < ROW; i++) //雷所在的九宫格所有数值+1,雷除外 { 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++) { if ((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 drawMap(int map[ROW][COL], IMAGE img[]) { for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { if (map[i][k] >= 0 && map[i][k] <= 8) //空白格子和数字 { putimage(k * IMGW, i * IMGW, img + map[i][k]); } else if (map[i][k] == -1) { putimage(k * IMGW, i * IMGW, img + 9); } else if (map[i][k] >= 19 && map[i][k] <= 28) { putimage(k * IMGW, i * IMGW, img + 10); } else if (map[i][k] > 28) { putimage(k * IMGW, i * IMGW, img + 11); } } } } void mouseEvent(int map[ROW][COL]) { ExMessage msg; //定义消息结构体(鼠标消息,按键消息,字符消息) if (peekmessage(&msg, EM_MOUSE)) { int r = msg.y / IMGW; int c = msg.x / IMGW; if (msg.message == WM_LBUTTONDOWN) { if (map[r][c] >= 19 && map[r][c] <= 28) { PlaySound(_T("./images/click.wav"), NULL, SND_ASYNC | SND_FILENAME); map[r][c] -= 20; openNull(map, r, c); judge_1(map, r, c); } } else if (msg.message == WM_RBUTTONDOWN) { PlaySound(_T("./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] <= 48) { map[r][c] -= 20; } judge_2(map, r, c); // showMap(map); } } } void openNull(int map[ROW][COL], int row, int col) { if (map[row][col] == 0) { for (int i = row - 1; i <= row + 1; i++) { for (int k = col - 1; k <= col + 1; k++) { if ((i >= 0 && i < ROW && k >= 0 && k < COL) && map[i][k] >= 19 && map[i][k] <= 28) { map[i][k] -= 20; openNull(map, i, k); } } } } } void judge_1(int map[ROW][COL], int row, int col) { if (map[row][col] == -1) { for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { if (map[i][k] == 19) { map[i][k] -= 20; } } } isOver = true; } } void judge_2(int map[ROW][COL], int row, int col) { int cnt = 0; for (int i = 0; i < ROW; i++) { for (int k = 0; k < COL; k++) { if (map[i][k] == 39) { cnt++; } } } if (cnt >= MineNum) { victory = true; } }