Buryool 发表于 2021-12-22 11:50:24

扫雷游戏点到雷后如何显示其他所有雷

问题描述:目前的代码已经可以正常运行,但是当点到雷以后不能显示其他所有雷的位置,直接就弹出失败消息框。想要加一个功能(judge()函数中注释掉的那部分,不知道错哪。。),点到雷以后可以先显示其他所有雷的位置,然后再弹出失败消息框。
素材图片音频见附件~解压后将所有素材放到.cpp文件目录下即可~


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include <easyx.h>
#include <graphics.h>//使得
#include <mmsystem.h>//多媒体(本程序是加载音乐)相关头文件
#pragma comment(lib,"winmm.lib")//加载静态库(需要以后补充,目前还不知道。。。)

//#define _CRT_SECURE_NO_WARNINGS//注意这句一定要定义到最上面,否则不能用sprintf()函数
#define ROW 10//定义行、列
#define COL 10
#define numOfBoom 10
#define SIZE 50//图片宽度

int map;//全局变量自动初始化为0
//定义图片数组,保存图片
IMAGE img;

//游戏胜利与否
int flag;

//打印底层数据内核
void show() {

Buryool 发表于 2021-12-22 11:52:20

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//#include <easyx.h>
#include <graphics.h>//使得
#include <mmsystem.h>//多媒体(本程序是加载音乐)相关头文件
#pragma comment(lib,"winmm.lib")//加载静态库(需要以后补充,目前还不知道。。。)

//#define _CRT_SECURE_NO_WARNINGS//注意这句一定要定义到最上面,否则不能用sprintf()函数
#define ROW 10//定义行、列
#define COL 10
#define numOfBoom 10
#define SIZE 50//图片宽度

int map;//全局变量自动初始化为0
//定义图片数组,保存图片
IMAGE img;

//游戏胜利与否
int flag;

//打印底层数据内核
void show() {
        for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                        printf("%2d    ", map);
                }

                putchar('\n');

        }

        putchar('\n');
        putchar('\n');

        //system("cls");//清屏
}

//游戏数据初始化
void gameInit() {
        mciSendString("open ./start.mp3 alias BGM", 0, 0, 0);//背景音乐版(BGM)音效
        mciSendString("play BGM", 0, 0, 0);
       
        //设置随机数种子
        srand((unsigned)time(NULL));

        //初始化数组
        for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                        map = 0;
                }
        }

        //埋雷 -1表示雷
        for (int i = 0; i < numOfBoom;) {
                int r = rand() % 10;//0~9
                int c = rand() % 10;

                if (map == 0) {//还没设置为雷
                        map = -1;
                        i++;//每埋雷一次就加一
                }

                map = -1;
        }

        //把以雷为中心的九宫格数据+1,雷那格除外。
        for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                        //判断是不是雷 -1
                        if (map == -1) {
                                //遍历雷所在的九宫格
                                for (int m = i - 1 ; m <= i + 1; m++) {
                                        for (int n = j - 1; n <= j + 1; n++) {
                                                if ((m >= 0 && m < ROW && n >= 0 && n < COL/*判断是否越界*/) && map != -1/*判断是否是雷*/) {
                                                        map += 1;
                                                }
                                        }
                                }
                        }
                }
        }

        //加载图片
        for (int i = 0; i < 12; i++) {
                char file = "";
                sprintf(file, "./%d.jpg", i);//将对应的字符串打印到字符串数组中
                //loadimage(&img, file);
                loadimage(&img, file, SIZE, SIZE);
        }

        //加密格子
        for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                        map += 20;
                }
        }
       
}

//绘制界面
void gameDraw() {

        cleardevice();
        for (int i = 0; i < ROW; i++) {
                for (int j = 0; j < COL; j++) {
                        if (map == -1) {
                                putimage(j * SIZE, i * SIZE,&img);//绘制雷
                        }
                        else if (map >= 0 && map <= 8) {//把其他数字一起处理0~8
                                putimage(j * SIZE, i * SIZE, &img]);
                        }
                        else if (map >= 19 && map <= 28) {
                                putimage(j * SIZE, i * SIZE, &img);
                        }
                        else if (map > 30) {//标记
                                putimage(j * SIZE, i * SIZE, &img);
                        }
                }
        }
}

void openNull(int row, int col);//声明一下,以便在下面的mouseControl()中使用
//鼠标操作
int mouseControl() {
        if (MouseHit()) {//判断有没有鼠标消息
                MOUSEMSG msg = GetMouseMsg();//鼠标所在的x,y

                int row = msg.y / SIZE;//把鼠标坐标转换成数组下标
                int col = msg.x / SIZE;
                //对鼠标消息进行分发
                switch (msg.uMsg) {
                case WM_LBUTTONDOWN://鼠标左键点击
                        if (map > 8) {//如果没有打开就打开
                                mciSendString("close click", 0, 0, 0);
                               
                                mciSendString("open ./click.mp3 alias click", 0, 0, 0);//点击版(click)音效
                                mciSendString("play click", 0, 0, 0);
                               
                                map -= 20;//解密
                                //解密各数字及区间代表含义:
                                //1.                  -1:雷0: 空白1~8:数字
                                //2.+=20:(盖起来)19:雷20:空白21~28:数字
                                //3.+=20:            >=30:都是旗子
                                flag++;

                                openNull(row, col);

                               
                        }
                        show();

                        break;
                case WM_RBUTTONDOWN://鼠标右键点击
                        if (map > 8 && map <= 28) {//如果没打开,且未被标记
                                map += 20;
                        }
                        else if (map > 28) {//只有没打开的才可以取消标记和标记
                                map -= 20;
                        }
                        show();

                        break;
                }

                return map;
        }
}

//打开所有以空白为中心的九宫格
void openNull(int row, int col) {
        if (map == 0) {//点击的是空白
                for (int m = row - 1; m <= row + 1; m++) {
                        for (int n = col - 1; n <= col + 1; n++) {
                                if ((m >= 0 && m < ROW && n >= 0 && n < COL) &&
                                        (map == 20 || map != 19/*不为雷(这里个人认为不用前面那个,到时候试试,因为感觉不为雷就包括了是空)*/)&&
                                        map > 8//如果没有越界,并且为空或者数字,并且没有被点开
                                        ) {
                                        map -= 20;

                                        flag++;

                                        openNull(m, n);
                                }
                        }
                }
        }

}

void judge() {
        if (mouseControl() == -1) {
                //结束
               
                ////看到所有炸弹位置
                //cleardevice();
                //for (int i = 0; i < ROW; i++) {
                //        for (int j = 0; j < COL; j++) {
                //                if (map == 19 || map == -1 || map == 39) {
                //                        putimage(j * SIZE, i * SIZE, &img);
                //                        //map = 0;
                //                }
                //        }
                //}

                system("pause");

                int isOK = MessageBox(GetHWnd(), "你输了噢~要不要再来一次?","提示", MB_OKCANCEL);

                if (IDOK == isOK) {
                        gameInit();

                        flag = 0;
                }
                else {
                        exit(-1);
                }
        }
        if (flag == ROW * COL - numOfBoom) {
                int isOK = MessageBox(GetHWnd(), "你赢了!哦吼吼吼吼!!","提示", MB_OKCANCEL);
               
                if (IDOK == isOK) {
                        gameInit();

                        flag = 0;
                }
                else {
                        exit(-1);
                }

                mciSendString("close BGM", 0, 0, 0);
        }

       
}

int main() {
        initgraph(ROW * SIZE, COL * SIZE, SHOWCONSOLE);
       
        gameInit();
       
        BeginBatchDraw();//解决不断刷新时卡屏卡顿问题
        while (1) {
                //show();
                gameDraw();
                FlushBatchDraw();//配合BeginBatchDraw()函数,在画图函数之后调用

                /*mouseControl();*/
                judge();
        }
        EndBatchDraw();//和FlushBatchDraw()函数作用基本一样,但是没有它好用一点。



        getchar();
        return 0;
}

Buryool 发表于 2021-12-22 11:53:15

Buryool 发表于 2021-12-22 11:52


不好意思一开始的代码块没有弄对。。。重新发了一次
页: [1]
查看完整版本: 扫雷游戏点到雷后如何显示其他所有雷