扫雷(C++控制台)

代码

先上代码(g++ 8.1.0 -Wall选项通过)

    /*
     * Minesweeper(扫雷) V2.3.0
     * 
     * V2.3.0更新:
     * - 命令 1 如果为已打开的格子,
     *   若周围标记数量足够,
     *   直接打开周围 
     * - 更改了部分Sleep事件时间参数 
     *
     * V2.2.0更新:
     * - 更新了亿堆对话
     * - 增加了配色 
     * 
     * V2.1.0更新:
     * - 当前所在的位置改用颜色突出显示 
     *
     * V2.0.1更新:
     * - 修复了再玩一次的Bug 
     * 
     * V2.0.0更新:
     * - 去除了光标和闪屏
     * - 使用上下左右或WASD控制"当前光标"位置
     * - &表示当前所在的位置
     * - 按下 1 打开, 按下 2 标记
     * Enjoy =) 
     */
    #include <Windows.h>
    #include <iostream>
    #include <iomanip>
    #include <random>
    #include <conio.h>
    #include <cmath>
    #include <set>
    using namespace std;
    const int WAIT_TIME = 1000;
    const int L = 10, W = 10;
    const int X = L + 2, Y = W + 2;
    const int back = 2;
    int nowx = 1, nowy = 1;
    struct Box {
        Box() : youLei(false), leiLiang(0), zhuangTai(0) {};
        bool youLei;
        int leiLiang;
        int zhuangTai;
        void clear(); 
    };
    Box l[X][Y];
    void click(int, int);
    void flag(int, int);
    void open(int,int);
    void outNum(int);
    void outAll();
    void load();
    void aGame();
    int main() {
        HWND hwnd = GetForegroundWindow();
        int cx = GetSystemMetrics(SM_CXSCREEN); 
        int cy = GetSystemMetrics(SM_CYSCREEN); 
        LONG l_WinStyle = GetWindowLong(hwnd,GWL_STYLE); 
        SetWindowLong(hwnd, GWL_STYLE, (l_WinStyle | WS_POPUP | WS_MAXIMIZE) & ~WS_CAPTION & ~WS_THICKFRAME & ~WS_BORDER);
        SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, 0);
        CONSOLE_CURSOR_INFO cursor;
        cursor.bVisible = false;
        cursor.dwSize = sizeof(cursor);
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorInfo(handle,&cursor);
        cout << 
    R"(
        __  ____                                                   
       /  |/  (_)___  ___  ______      _____  ___  ____  ___  _____
      / /|_/ / / __ \/ _ \/ ___/ | /| / / _ \/ _ \/ __ \/ _ \/ ___/
     / /  / / / / / /  __(__  )| |/ |/ /  __/  __/ /_/ /  __/ /    
    /_/  /_/_/_/ /_/\___/____/ |__/|__/\___/\___/ .___/\___/_/     
                                               /_/                 
                                                        by c2021ldw
    )";
        Sleep(500);
        system("cls"); 
        try {
            while (true) {
                aGame();
                cout << "你想再玩一次扫雷吗? 按Y确认, 其他键退出";
                int tmp = getch();
                if (tmp == 'Y' || tmp == 'y')
                    continue;
                return 0;
            }
        }
        catch (...) {
            cerr << "发生了一个错误...";
            Sleep(WAIT_TIME);
            cout << "请联系c2021ldw!!!" << endl;
            Sleep(WAIT_TIME);
            return 0;
        }
        return 0;
    }
    void Box::clear() {
        youLei = false;
        leiLiang = 0;
        zhuangTai = 0;
    }
    ostream& operator<<(ostream& os, Box b) {
        if (b.zhuangTai == 0)
            os << ' ';
        if (b.zhuangTai == 1) {
            if (b.youLei) {
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 240);
                os << '*';
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
            }
            else {
                switch (b.leiLiang) {
                    case 1:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 3);
                        break;
                    case 2:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 10);
                        break;
                    case 3:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
                        break;
                    case 4:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
                        break;
                    case 5:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 12);
                        break;
                    case 6:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6);
                        break;
                    case 7:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 13);
                        break;
                    case 8:
                        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
                        break;
                }
                os << b.leiLiang;
                SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
            }
        }
        if (b.zhuangTai == 2) {
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 8);
            os << '#';
            SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
        }
        return os;
    }
    void click(int x, int y) {
        if (l[x][y].zhuangTai == 0) {
            l[x][y].zhuangTai = 1;
            if (!l[x][y].youLei && l[x][y].leiLiang == 0)
                open(x, y);
            return;
        }
        if (l[x][y].zhuangTai == 1)
            open(x, y);
    }
    void flag(int x, int y) {
        if (l[x][y].zhuangTai == 0)
            l[x][y].zhuangTai = 2;
        else if (l[x][y].zhuangTai == 2)
            l[x][y].zhuangTai = 0;
    }
    void open(int x, int y) {
        if (X < 1 || y < 1 || x > L || y > W)
            return;
        int tmp = 0; 
        for (int i = x - 1; i <= x + 1; ++i) {
            for (int j = y - 1; j <= y + 1; ++j) {
                if (i == x && j == y)
                    continue;
                if(i < 1 || j < 1 || i > L || y > W)
                    continue;
                if(l[i][j].zhuangTai != 2)
                    continue;
                ++tmp;
            }
        }
        if (tmp == l[x][y].leiLiang) {
            for (int i = x - 1; i <= x + 1; ++i) {
                for (int j = y - 1; j <= y + 1; ++j) {
                    if (i == x && j == y)
                        continue;
                    if(i < 1 || j < 1 || i > L || y > W)
                        continue;
                    if(l[i][j].zhuangTai != 0)
                        continue;
                    click(i, j);
                }
            }
        }
    }
    void outNum(int a) {
        int k = a, s = 0;
        while (k != 0) {
            ++s;
            k /= 10;
        }
        cout << a;
        for (int i = 1; i <= back - s + 1; ++i)
            cout << ' ';
    }
    void outAll() {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
        cout << ' ';
        for (int i = 1; i <= back; ++i)
            cout << ' ';
        for (int i = 1; i <= W; ++i)
            outNum(i);
        for (int i = 1; i <= L; ++i) {
            cout << "\n\n";
            outNum(i);
            for (int j = 1; j <= W; ++j) {
                if (i == nowx && j == nowy) {
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 143);
                    if (l[i][j].zhuangTai == 0)
                        cout << ' ';
                    if (l[i][j].zhuangTai == 1) {
                        if (l[i][j].youLei)
                            cout << '*';
                        else
                            cout << l[i][j].leiLiang;
                    }
                    if (l[i][j].zhuangTai == 2)
                        cout << '#';
                    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
                }
                else
                    cout << l[i][j];
                for (int i = 1; i <= back; ++i)
                    cout << ' ';
            }
        }
        cout << endl;
    }
    void load() {
        system("cls");
        for (int i = 0; i < X; ++i) {
            for (int j = 0; j < Y; ++j)
                l[i][j].clear();
        }
        nowx = 1;
        nowy = 1;
        static default_random_engine e(time(NULL));
        static uniform_int_distribution<int> u1{4,L};
        static uniform_int_distribution<int> u2{4,W};
        set<pair<int, int>> lei;
        unsigned set_lei = sqrt(L * W);
        while (lei.size() != set_lei)
            lei.insert(pair<int, int>(u1(e),u2(e)));
        for (set<pair<int, int>>::iterator it = lei.begin(); it != lei.end(); ++it)
            l[it->first][it->second].youLei = true;
        for (int i = 1; i <= L; ++i) {
            for (int j = 1; j <= W; ++j) {
                if (l[i][j].youLei)
                    continue;
                int s = 0;
                for (int m = i - 1; m <= i + 1; ++m) {
                    for (int n = j - 1; n <= j + 1; ++n) {
                        if (l[m][n].youLei)
                            ++s;
                    }
                }
                l[i][j].leiLiang = s;
            }
        }
    }
    bool win() {
        for (int i = 1; i <= L; ++i) {
            for (int j = 1; j <= W; ++j) {
                if (l[i][j].zhuangTai == 1 && l[i][j].youLei)
                    return false;
                if (l[i][j].zhuangTai == 0 && !l[i][j].youLei)
                    return false;
                if (l[i][j].zhuangTai == 2 && !l[i][j].youLei)
                    return false;
            }
        }
        return true;
    }
    bool lose() {
        for (int i = 1; i <= L; ++i) {
            for (int j = 1; j <= W; ++j) {
                if (l[i][j].youLei && l[i][j].zhuangTai == 1)
                    return true;
            }
        }
        return false;
    }
    void aGame() {
        load();
        while (win() == false && lose() == false) {
            HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
            COORD pos;
            pos.X = 0;
            pos.Y = 0;
            SetConsoleCursorPosition(handle,pos);
            outAll();
            int tmp = getch();
            if (tmp == 224) {
                tmp = getch();
                if (tmp == 72)
                    --nowx;
                else if (tmp == 75)
                    --nowy;
                else if (tmp == 80)
                    ++nowx;
                else if (tmp == 77)
                    ++nowy;
                if (nowx < 1)
                    while (++nowx < 1);
                if (nowx > L)
                    while (--nowx > L);
                if (nowy < 1)
                    while (++nowy < 1);
                if (nowy > W)
                    while (--nowy > W);
            }
            else if (tmp == 'W' || tmp == 'w') {
                --nowx;
                if (nowx < 1)
                    while (++nowx < 1);
            }
            else if (tmp == 'A' || tmp == 'a') {
                --nowy;
                if (nowy < 1)
                    while (++nowy < 1);
            }
            else if (tmp == 'S' || tmp == 's') {
                ++nowx;
                if (nowx > L)
                    while (--nowx > L);
            }
            else if (tmp == 'D' || tmp == 'd') {
                ++nowy;
                if (nowy > W)
                    while (--nowy > W);
            }
            else if (tmp == '1')
                click(nowx, nowy);
            else if (tmp == '2')
                flag(nowx, nowy);
            else if (tmp == 3)
                exit(0);
        }
        system("cls");
        if (win())
            cout << "恭喜, 你赢了!!!" << endl;
        else
            cout << "抱歉, 你输了..." << endl;
        Sleep(1000);
        nowx = -1;
        nowy = -1;
        for (int i = 1; i <= L; ++i) {
            for (int j = 1; j <= W; ++j)
                l[i][j].zhuangTai = 1;
        }
        outAll();
    }

玩法

上下左右(WASD)移动当前格
按1点击,2标记

后续更新

参见泉州一中信息学题库的c2021ldw在1000题的提交记录

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值