C++----扫雷风暴(很差劲)

前言

最近学会了扫雷,今天我用C++给他敲了出来。(新的问题是,他就很差劲

效果图

来来来,上效果图。
效果图1
效果图2
效果图3

源码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
using namespace std;

int board[15][15]; // 雷图: 9 表示 地雷; 0~8 表示周边八格雷数 
int show[15][15]; // 展示状态图: 0 表示 未知; 1 表示 已知; 2 表示 旗子🚩

// 游戏规则展示
void intro()
{
    cout << "===============================================" << endl;
    cout << "     ***欢迎运行扫雷游戏!***" << endl;
    cout << "    【游戏规则如下:】" << endl;
    cout << "    在这个游戏里会有一个 9*9 的网格,网格中埋着 10颗雷" << endl;
    cout << "    游戏目标是找出所有的雷,如果触雷,则游戏失败" << endl;
    cout << "    每次输入要操作的格子 行、列,1表示翻开,2表示标记/取消旗子🚩" << endl;
    cout << "    格子中的数字表示它周围八个格中有几个雷" << endl; 
    cout << "    *第一次翻格子不会是雷" << endl; 
    cout << "    按下 回车键 开始游戏" << endl; 
    cout << "================================================" << endl << endl;
    getchar();
}

// 打印当前棋盘
void drawBoard()
{
    cout << "\033c" << flush;
    // 输出行号
    cout << "     ";
    for (int i = 1; i <= 9; i++) cout << "   " << i;
    cout << "  \n";
    // 输出上边框
    cout << "      ╔";
    for (int i = 1; i <= 8; i++) cout << "═══╤";
    cout << "═══╗\n";
    // 输出中间部分
    for (int i = 1; i <= 9; i++) // 行
    {
        cout << "    " << i << " ║";
        for (int j = 1; j <= 9; j++) // 列
        {
            if (show[i][j] == 0) // 未知
                cout << "\033[47m   \033[0m";
            if (show[i][j] == 1) // 已知
            {
                if (board[i][j] == 9) // 雷
                    cout << "\033[31m ※ \033[0m";
                if (board[i][j] == 0) // 空白
                    cout << "   ";
                if (board[i][j] > 0 && board[i][j] < 9) // 数字
                    cout << " " << board[i][j] << " ";
            }
            if (show[i][j] == 2) // 旗子
            {
                cout << "\033[47m 🚩 \033[0m";
            }
            if (j != 9)
                cout << "│";
            else
                cout << "║";
            cout << "";
        }
        cout << " \n";
        cout << "    ";
        // 输出下边框
        if (i != 9)
        {
            cout << "  ╟";
            for (int i = 1; i <= 8; i++) cout << "───┼";
            cout << "───╢\n";
            
        }
        else
        {
            cout << "  ╚";
            for (int i = 1; i <= 8; i++) cout << "═══╧";
            cout << "═══╝\n";
        }
    }
}

// 标记/取消旗子🚩
void mark(int x, int y)
{
    if (show[x][y] == 1) return;
    if (show[x][y] == 2) show[x][y] = 0;
    else show[x][y] = 2;
}

// 判断是否与已翻开的空白格相邻
bool near(int x, int y)
{
    for (int i = x-1; i <= x+1; i++)
    {
        for (int j = y-1; j <= y+1; j++)
        {
            if (board[i][j] == 0 && show[i][j] == 1)
            {
                return true;
            }
        }
    }
    return false;
}

// 翻开格子
void open(int x, int y)
{
    show[x][y] = 1;
    // 重复 8 次,扫描翻开区域
    for (int t = 1; t <= 8; t++)
    {
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 9; j++)
            {
                if (board[i][j] != 9 && show[i][j] == 0 && near(i, j))
                {
                    show[i][j] = 1;
                }
            }
        }
    }
}

// 初始化雷图
void init(int x, int y)
{
    // 生成 10 个雷
    srand(time(0));
    for (int i = 1; i <= 10; i++)
    {
        int hang, lie;
        while (true)
        {
            hang = rand() % 9 + 1;
            lie = rand() % 9 + 1;
            // 避开初次翻开的格子和雷
            if (board[hang][lie] != 9 && (abs(hang - x) > 1 || abs(lie - y) > 1))
            {
                board[hang][lie] = 9;
                break;
            }
        }
        
    }
    // 生成雷图
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (board[i][j] == 9) continue;
            for (int xx = i-1; xx <= i+1; xx++)
            {
                for (int yy = j-1; yy <= j+1; yy++)
                {
                    if (board[xx][yy] == 9) board[i][j]++;
                }
            }
        }
    }
}

// 扫雷失败,显示所有雷
void gameOver()
{
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (board[i][j] == 9)
            {
                show[i][j] = 1;
            }
        }
    }
    drawBoard();
    cout << "游戏失败!" << endl;
}

// 判断是否获胜
bool gameWin()
{
    int cnt = 0; // 未知 + 旗子 数量
    for (int i = 1; i <= 9; i++)
    {
        for (int j = 1; j <= 9; j++)
        {
            if (show[i][j] == 0 || show[i][j] == 2)
            {
                cnt++;
            }
        }
    }
    return cnt == 10;
}

// 开始游戏
void game() 
{
    bool fst = true; // 初次
    int start = time(0); // 开始时间
    while (true)
    {
        drawBoard();
        int x, y, op;
        cout << "请输入行、列(1 ~ 9),操作(1 表示翻开,2 表示标记/取消旗子🚩) 例: 5 5 1" << endl;
        cin >> x >> y >> op;
        if (x < 1 || x > 9 || y < 1 || y > 9) continue;
        if (op != 1 && op != 2) continue;
        if (op == 1) // 翻开
        {
            if (fst) // 初次翻开
            {
                init(x, y);
                fst = false;
            }
            if (board[x][y] == 9) // 游戏结束
            {
                gameOver();
                return;
            }
            open(x, y);
        }
        if (op == 2) // 标记/取消旗子
        {
            mark(x, y);
        }
        if (gameWin()) // 判断是否获胜
        {
            drawBoard();
            cout << "游戏胜利!" << endl;
            cout << "总用时 " << time(0) - start << " s" << endl;
            return;
        }
    }
}

int main()
{
    intro(); // 游戏介绍
    game(); // 开始游戏
    return 0;
}

不知不觉,代码就敲出来啦。

BUG

如果您使用的是窗户系统,或者某破烂字体,或者某破烂编译器,将会出下下面的效果。
BUG

结束

本期文章就结束啦,代码不难,没看懂的就别看啊
885+1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HellowZheng

老铁,您的打赏是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值