赞
踩
菜鸡献丑~
从数学的思想来看:
扫雷可以划分为几个阶段:
①、建立一个N×N的矩阵bool型矩阵W,其中W(m,n)=1代表(m,n)处有雷。随机在N²个位置中选取M个位置将W置1(M为雷的数量)。
②、定义一个N×N的矩阵bool型矩阵O,其中O(m,n)=1代表(m,n)还没有被翻开。
③、计算周围雷的数目,将得到的数据存储在矩阵A中(矩阵A为int型,A的值为0-8)。
④、选取(m,n)点为所开始点。如果O(m,n)=0,表示已经翻开了,不能重复翻开。如果O(m,n)=1,若(m,n)处W(m,n)=1,则选中了雷,游戏结束,直接到步骤⑥。如果O(m,n)=1且A(m,n)!=0,则把O(m,n)置为0,同时把W(m,n)在该处显示出来。如果O(m,n)=1且A(m,n)=0,表明此处是空白,周围没有雷,则要通过遍历周围的坐标处是否有数字,通过遍历实现点击一下有一大片空白的生成,同时把已经翻开的位置处的O矩阵置为0。
⑤、循环步骤④,直到游戏结束。游戏结束的条件为以下任一:选取的(m,n)处有雷;把所有的没有雷的位置都翻开(矩阵O求和==M);
⑥、游戏结束。
以下为程序实现的某些截图。
此外还针对于图像化的显示做了部分优化,同时加入了开始场景和背景音乐以及特殊场景的音效控制等适配。
附上头文件代码
#include <time.h> #include <string> #ifndef MATRIX_H #define MATRIX_H #define NUM 10//定义N×N个格子 #define numBOOM 12//定义numBOOM为雷的总数 template<typename T> class matrix { public: matrix(int num); void init(T w); void _rand(); void show(); T get(int x, int y) { return mat[x][y]; } void set(int x, int y, T z) { mat[x][y] = z; } private: int _num; T mat[NUM][NUM]; }; template<typename T> matrix<typename T>::matrix(int num) { _num = num; } template<typename T> void matrix<typename T>::init(T w) { for (int i1 = 0; i1 < NUM; i1++) { for (int i2 = 0; i2 < NUM; i2++) { mat[i1][i2] = w; } } } template<typename T> void matrix<typename T>::_rand() { int m, n; srand(int(time(0))); for (int i = 0; i < numBOOM;)//雷的总数为numBOOM; { m = rand() % NUM; n = rand() % NUM; if (!mat[m][n]) { mat[m][n] = 1; i++; } } } template<typename T> void matrix<typename T>::show() { for (int i = 0; i < NUM; i++) { for (int j = 0; j < NUM; j++) { } } } #endif
附上主程序代码
#include <iostream> #include <stdlib.h> #include <cstdlib> #include "matrix.h" #include <graphics.h> #include "stdio.h" #include <windows.h> #include <mmsystem.h> #pragma comment (lib, "winmm.lib") #define SIZE 40//定义单张图片的大小 using namespace std; IMAGE image[16]; MOUSEMSG msg; //void init(); //void show(bool S[NUM][NUM]); //void INIT(); int sum(matrix<bool> &mat_O); int loop(int m, int n, matrix<bool> &mat_W, matrix<bool> &mat_O, matrix<int> &mat_A, matrix<char> &mat_S); void loop2(int m, int n, matrix<bool> &mat_W, matrix<bool> &mat_O, matrix<int> &mat_A, matrix<char> &mat_S); //void boom(); //bool W[NUM][NUM] = { 0 };//=1表示(m,n)处有雷;=0表示(m,n)处无雷; //bool O[NUM][NUM] = { 1 };//=1表示(m,n)处未翻开;=0表示(m,n)处已经翻开; //int A[NUM][NUM];//(m,n)周围雷的个数(0-8); //bool _W[NUM + 2][NUM + 2];//W[][]周围加上一圈的0; //int _A[NUM + 2][NUM + 2];//_W[][]的周围雷的个数; //char S[NUM][NUM];//显示,用“*”或者A(m,n)显示; void main() { //PlaySound(L"music.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); //mciSendString(L"open qiyueshang.wav alias aa", NULL, 0, NULL);//alias后面为设备名称, //mciSendString(L"play aa wait", NULL, 0, NULL);//wait表示播放完毕之后才返回,最好加上去{该语句会一直执行,不会执行后面的代码,故不用} //mciSendString(L"close aa", NULL, 0, NULL); //system("mode con cols=34 lines=20");//改变窗口宽高 //system("color 5E");//改变窗口文字颜色 initgraph(NUM*SIZE, (NUM+1)*SIZE); loadimage(&image[0], L"image\\0.jpg", SIZE, SIZE);//此处用来读取文件所在的位置时候只能用\\,不能用其他的; loadimage(&image[1], L"image\\1.jpg", SIZE, SIZE); loadimage(&image[2], L"image\\2.jpg", SIZE, SIZE); loadimage(&image[3], L"image\\3.jpg", SIZE, SIZE); loadimage(&image[4], L"image\\4.jpg", SIZE, SIZE); loadimage(&image[5], L"image\\5.jpg", SIZE, SIZE); loadimage(&image[6], L"image\\6.jpg", SIZE, SIZE); loadimage(&image[7], L"image\\7.jpg", SIZE, SIZE); loadimage(&image[8], L"image\\8.jpg", SIZE, SIZE); loadimage(&image[9], L"image\\init.jpg", SIZE, SIZE); loadimage(&image[10], L"image\\lei.jpg", SIZE, SIZE); loadimage(&image[11], L"image\\tag.jpg", SIZE, SIZE); loadimage(&image[12], L"image\\success2.jpg", SIZE*NUM*5/5, SIZE*NUM*5/5);//牛逼图片 loadimage(&image[13], L"image\\failure.jpg", SIZE*NUM*5/5, SIZE*NUM*5/5);//垃圾图片 loadimage(&image[14], L"image\\start.jpg", SIZE*NUM, SIZE*(NUM+1));//开始图片 loadimage(&image[15], L"image\\head.jpg", SIZE*NUM, SIZE);//head文件,用以展示 putimage(0, 0,&image[14]); int flag_start = 1; while (flag_start) { int X, Y; msg = GetMouseMsg(); X = msg.x / SIZE; Y = msg.y / SIZE; switch (msg.uMsg) { case WM_LBUTTONDOWN: if (X >= (NUM *4/ 10) && X <= (NUM *6/ 10) && Y >= NUM* 8 / 10 && Y <= NUM*9 / 10) { flag_start = 0; } } } PlaySound(L"music.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//进入开始界面后开始播放音乐 putimage(0, 0, &image[15]); for (int i = 0; i < NUM; i++)//初始化界面 { for (int j = 1; j < NUM+1; j++) { putimage(SIZE * i, SIZE * j, &image[9]); } } //_getch(); //return 0; //Sleep(5000); matrix<bool> mat_F(NUM);//Flag矩阵 mat_F.init(0); matrix<bool> mat_W(NUM);//W[][]矩阵 mat_W.init(0); mat_W._rand(); //mat_W.show();//输出炸弹矩阵(); matrix<bool> mat_O(NUM);//O[][]矩阵 mat_O.init(1); //mat_O.show(); matrix<char> mat_S(NUM);//S[][]矩阵 mat_S.init('*'); //mat_S.show(); matrix<int> mat_A(NUM);//A[][]矩阵 //mat_O.show(); int _W[NUM + 2][NUM + 2];//扩展后的W[12][12] int _A[NUM + 2][NUM + 2]; for (int i1 = 0; i1 < NUM + 2; i1++) { for (int i2 = 0; i2 < NUM + 2; i2++) { _W[i1][i2] = 0; } } for (int i1 = 1; i1 < NUM + 1; i1++) { for (int i2 = 1; i2 < NUM + 1; i2++) { _W[i1][i2] = mat_W.get(i1 - 1, i2 - 1); } } for (int i1 = 1; i1 < NUM + 1; i1++) { for (int i2 = 1; i2 < NUM + 1; i2++) { _A[i1][i2] = _W[i1 - 1][i2 - 1] + _W[i1 - 1][i2] + _W[i1 - 1][i2 + 1] + _W[i1][i2 - 1] + _W[i1][i2 + 1] + _W[i1 + 1][i2 - 1] + _W[i1 + 1][i2] + _W[i1 + 1][i2 + 1]; mat_A.set(i1 - 1, i2 - 1, _A[i1][i2]); } } //int m, n; int X = 0, Y = 0; int sum = 100; while (sum != numBOOM) { while (MouseHit()) { msg = GetMouseMsg(); X = msg.x / SIZE; Y = msg.y / SIZE - 1; if (X >= 0 && Y >= 0) { switch (msg.uMsg) { case WM_LBUTTONDOWN: //X = msg.x / 50; //Y = msg.y / 50; sum = loop(X, Y, mat_W, mat_O, mat_A, mat_S); if (sum == -1) { //cout << "完蛋玩意儿,BOOM!!!" << endl; for (int i1 = 0; i1 < NUM; i1++)//循环输出雷的位置 { for (int i2 = 0; i2 < NUM; i2++) { if (mat_W.get(i1, i2)) { putimage(i1 * SIZE, (i2+1) * SIZE, &image[10]); } } } PlaySound(L"boom.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//播放炸弹被翻开的音效 Sleep(2000);//2000ms时间展示雷的位置 PlaySound(NULL, NULL, SND_FILENAME);//停止播放背景音乐 putimage(NUM*SIZE * 0 / 10, SIZE, &image[13]);//输出垃圾图片 PlaySound(L"heihei.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//输出白痴笑声 Sleep(3000);//延时3000ms关闭 PlaySound(NULL, NULL, SND_FILENAME); system("pause"); } continue; case WM_RBUTTONDOWN: if (mat_O.get(X, Y)) { if (!mat_F.get(X, Y)) { putimage(X * SIZE, (Y+1) * SIZE, &image[11]); mat_F.set(X, Y, 1); } else { putimage(X * SIZE, (Y+1) * SIZE, &image[9]); mat_F.set(X, Y, 0); } } } } } } if (sum == numBOOM) { Sleep(1000); putimage(NUM*SIZE*0/10,SIZE,&image[12]);//牛逼,输出牛逼图片 PlaySound(L"applause.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); Sleep(4000); PlaySound(NULL, NULL, SND_FILENAME); system("pause"); } } int loop(int m, int n, matrix<bool> &mat_W, matrix<bool> &mat_O, matrix<int> &mat_A, matrix<char> &mat_S) { int flag = 0;//作为选中炸弹的标志; if (!mat_O.get(m, n))//如果翻开的话重新选择,没翻开的话进入判断 { //cout << "请重新选择:" << endl; return 0; } else { if (mat_W.get(m, n))//有雷的话就爆炸 { //boom(); //cout << "恭喜您,您选中了炸弹!!" << endl; putimage(SIZE*m, SIZE*(n + 1), &image[10]); return -1; } else if (mat_A.get(m, n))//如果(m,n)处有数字,周围有雷 { mat_O.set(m, n, 0); int temp = mat_A.get(m, n); putimage(SIZE * m, SIZE * (n + 1), &image[temp]); //mat_S.set(m, n, temp + '0'); //mat_S.show(); } else//(m,n)处为空白,即mat_A(m,n)=0; { putimage(SIZE*m, SIZE * (n + 1), &image[0]); loop2(m, n, mat_W, mat_O, mat_A, mat_S); //mat_S.show(); } } //cout << "-------------------------------" << endl; //cout << "①②③④⑤⑥⑦⑧⑨⑩" << endl; //cout << "end" << endl; //mat_S.show(); return sum(mat_O); } void loop2(int m, int n, matrix<bool> &mat_W, matrix<bool> &mat_O, matrix<int> &mat_A, matrix<char> &mat_S) { int temp = mat_A.get(m, n); //mat_S.set(m, n, temp + '0'); mat_O.set(m, n, 0); if (m > 0 && mat_O.get(m - 1, n)) { if (mat_A.get(m - 1, n)) { putimage(SIZE * (m - 1), SIZE * (n + 1), &image[mat_A.get(m - 1, n)]); mat_S.set(m - 1, n, mat_A.get(m - 1, n) + '0'); mat_O.set(m - 1, n, 0); } else { putimage(SIZE * (m - 1), SIZE * (n + 1), &image[0]); loop2(m - 1, n, mat_W, mat_O, mat_A, mat_S); } } if (m < (NUM -1) && mat_O.get(m + 1, n)) { if (mat_A.get(m + 1, n)) { putimage(SIZE * (m + 1), SIZE * (n + 1), &image[mat_A.get(m + 1, n)]); mat_S.set(m + 1, n, mat_A.get(m + 1, n) + '0'); mat_O.set(m + 1, n, 0); } else { putimage(SIZE * (m + 1), SIZE * (n + 1), &image[0]); loop2(m + 1, n, mat_W, mat_O, mat_A, mat_S); } } if (n > 0 && mat_O.get(m, n - 1)) { if (mat_A.get(m, n - 1)) { putimage(SIZE * m, SIZE * n, &image[mat_A.get(m, n - 1)]); mat_S.set(m, n - 1, mat_A.get(m, n - 1) + '0'); mat_O.set(m, n - 1, 0); } else { putimage(SIZE * m, SIZE * n , &image[0]); loop2(m, n - 1, mat_W, mat_O, mat_A, mat_S); } } if (n < (NUM - 1) && mat_O.get(m, n + 1)) { if (mat_A.get(m, n + 1)) { putimage(SIZE * m, SIZE * (n + 2), &image[mat_A.get(m, n + 1)]); mat_S.set(m, n + 1, mat_A.get(m, n + 1) + '0'); mat_O.set(m, n + 1, 0); } else { putimage(SIZE * m, SIZE * (n + 2), &image[0]); loop2(m, n + 1, mat_W, mat_O, mat_A, mat_S); } } } int sum(matrix<bool> &mat_O) { int sum = 0; for (int i = 0; i < NUM; i++) { for (int j = 0; j < NUM; j++) { sum += mat_O.get(i, j); } } return sum; }
由于时间仓促,部分代码没有注释,可以按照最前面的思路去推一遍,对自己的帮助会很大,如有不太懂的代码可以自行百度,或者回复,我会给你解答。
源代码去我上传的资源里面找。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。