我们Win10/11_x64也有自己的扫雷(bushi
本文最后更新于 103 天前,其中的信息可能已经有所发展或是发生改变。

开发环境

VS2022 and EasyX(图形库)

这里使用VS2022作为IDE 此外需要安装图形库并使用GUI使程序告别漆黑的控制台

附件+可执行文件:扫雷
EasyX:EasyX_2023大暑版
Visual Studio的.sln项目文件:扫雷pro max

运行结果


使用IDA pro作个弊先

作为一名逆向工程爱好者,怎么能不开挂呢嘿嘿

我们用IDA打开之后能直接看见main函数,同时也能够很明显的看到判断胜负的地方

可以很明显看见有一个jnz指令,我们将其改为jz指令之后就可以实现踩到不是雷的地方就能胜利了,这大大提高了我们的胜率

随便踩一个就可以获胜了

此外还有更多的作弊方法,但是我懒得写了,就这样吧

代码实现

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<graphics.h>
#include <windows.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) // 设置入口地址

#define ROW 30  //行 
#define COL 20  //列 
#define NUM 80  //雷 
#define SIZE 20 
//定义宏为了便于更改数据 

int count = 0;      //点开格子的个数
int map[ROW + 2][COL + 2];  //为了防止边界导致出错 外围多加一圈进行分区 分为游戏区和辅助区 
//0                     //其中只打印出游戏区 

IMAGE img[12];  //存放图片 

//初始化函数 
void GameInit()
{
    //随机数种子
    srand(time(NULL));
    //数组的赋初始值0
    int i, j;
    for (i = 0; i < ROW + 2; i++)
    {
        for (j = 0; j < COL + 2; j++)
        {
            map[i][j] = 0;
        }
    }

    //布雷 1表示雷 NUM个雷
    int n = 0;
    while (n < NUM)
    {
        //随机行与列布雷
        int r = rand() % ROW + 1;   //1-ROW
        int c = rand() % COL + 1;   //1-COL
        //随机数加1是为了防止布雷时布到辅助区 
        if (map[r][c] == 0)
        {
            map[r][c] = -1;
            n++;
        }
    }
    //根据雷的分布 填充其他不为雷的数据 
    int a, b, k, l;
    for (a = 1; a <= ROW; a++)
    {
        for (b = 1; b <= COL; b++)   //遍历二维数组 的游戏区 
        {
            if (map[a][b] != -1)    //找到不为雷的格子 
            {
                //遍历该格的九宫格 
                for (k = a - 1; k <= a + 1; k++)
                {
                    for (l = b - 1; l <= b + 1; l++)
                    {
                        if (map[k][l] == -1)
                        {
                            map[a][b]++;
                        }
                    }
                }
            }
        }
    }

    //简单加密作为开局时的覆盖
    for (i = 0; i < ROW + 2; i++)
    {
        for (j = 0; j < COL + 2; j++)
        {
            map[i][j] += 20;
        }
    }
}

//绘制函数 打印二维数组中所有元素 
void Gamedraw()
{
    //打印游戏区 
    int i, j;
    for (i = 1; i <= ROW; i++)
    {
        for (j = 1; j <= COL; j++)       //这里从1开始循环而不是从0开始循环 与i,j使用小于等于 都是为了仅打印出游戏区 
        {
            printf("%2d ", map[i][j]);

            /****************************************************
                元素      图片
                0-8         数字      +20 = 20-28
                -1          img[9]      +20 = 19
                19-28       img[10]
                >30          img[11]
            *****************************************************/

            if (map[i][j] == -1)                        //雷
            {
                putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[9]);
            }
            else 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] > 30)                         //旗帜
            {
                putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[11]);
            }
        }
        printf("\n");
    }
}

void OpenZero(int r, int c)
{
    int m, n;
    //先翻开格子
    map[r][c] -= 20;
    count++;
    //辅助区为0
    for (m = r - 1; m <= r + 1; m++)
    {
        for (n = c - 1; n <= c + 1; n++)     //两个for循环遍历九宫格
        {
            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 Gameplay()
{
    MOUSEMSG msg = { 0 };       //定义一个鼠标
    int r, c;
    while (1)
    {
        msg = GetMouseMsg();

        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;            //>30
            }
            else if (map[r][c] > 30)
            {
                map[r][c] -= 50;
            }
            return map[r][c];
            break;
        }
    }
}

int main()
{
    HWND hwnd = initgraph(ROW * SIZE, COL * SIZE); // 不传入 SHOWCONSOLE 参数,只显示图像窗口,不显示控制台窗口

    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);       //方格 

    /****************************************************
            元素      图片
            0-8         数字      +20 = 20-28
             -1         img[9]      +20 = 19
          19-28         img[10]
            >30          img[11]
    *****************************************************/

    GameInit();

    while (1)
    {
        Gamedraw();
        if (Gameplay() == -1)
        {
            Gamedraw();
            MessageBox(hwnd, L"cai", L"Try again", MB_OK);
            break;
        }

        if (ROW * COL - NUM == count)
        {
            Gamedraw();
            MessageBox(hwnd, L"WIN!!!", L"Ciallo", MB_OK);
            break;
        }
    }
    closegraph();

    return 0;

}

代码解释

我们引入了<graphics.h>头文件,使我们的程序能够使用图片

设置了函数入口点,避免程序单独运行时弹出控制台窗口

使用宏定义以便于修改格子与雷的数量

使用伪随机数使得程序每次运行时生成雷的格子都不同

二维数组布置地图

对数值进行简单的加密使其防止被逆向(没什么用就是了)

通过排雷总数计算胜负

使用递归进行游戏

总结

写着玩的,各位图一乐就行了

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇