#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>

using namespace std;

enum class CellState { HIDDEN, REVEALED, FLAGGED };

struct Cell {
    bool hasMine;
    int adjacentMines;
    CellState state;
};

class Minesweeper {
private:
    int rows, cols, mines;
    vector<vector<Cell>> board;
    bool gameOver;
    bool win;
    int revealedCells;

    // 设置控制台光标位置
    void setCursorPosition(int x, int y) {
        COORD coord;
        coord.X = x;
        coord.Y = y;
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }

    // 隐藏控制台光标
    void hideCursor() {
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
        cursorInfo.bVisible = false;
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    }

    // 初始化游戏板
    void initializeBoard() {
        board.resize(rows, vector<Cell>(cols));
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                board[i][j] = {false, 0, CellState::HIDDEN};
            }
        }

        // 随机放置地雷
        int minesPlaced = 0;
        while (minesPlaced < mines) {
            int row = rand() % rows;
            int col = rand() % cols;
            if (!board[row][col].hasMine) {
                board[row][col].hasMine = true;
                ++minesPlaced;
            }
        }

        // 计算每个格子周围的地雷数
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                if (!board[i][j].hasMine) {
                    board[i][j].adjacentMines = countAdjacentMines(i, j);
                }
            }
        }

        gameOver = false;
        win = false;
        revealedCells = 0;
    }

    // 计算周围的地雷数
    int countAdjacentMines(int row, int col) {
        int count = 0;
        for (int i = max(0, row - 1); i <= min(rows - 1, row + 1); ++i) {
            for (int j = max(0, col - 1); j <= min(cols - 1, col + 1); ++j) {
                if (i != row || j != col) {
                    if (board[i][j].hasMine) {
                        ++count;
                    }
                }
            }
        }
        return count;
    }

    // 显示游戏板
    void displayBoard(int currentRow, int currentCol) {
        system("cls");
        cout << "超级扫雷游戏" << endl;
        cout << "剩余地雷: " << mines - countFlags() << endl;
        cout << "使用方向键移动,空格揭示,F键标记地雷" << endl;
        cout << endl;

        // 打印列号
        cout << "  ";
        for (int j = 0; j < cols; ++j) {
            cout << j % 10 << " ";
        }
        cout << endl;

        // 打印游戏板
        for (int i = 0; i < rows; ++i) {
            cout << i % 10 << " ";
            for (int j = 0; j < cols; ++j) {
                if (i == currentRow && j == currentCol) {
                    cout << "[";
                } else {
                    cout << " ";
                }

                if (board[i][j].state == CellState::REVEALED) {
                    if (board[i][j].hasMine) {
                        cout << "*";
                    } else if (board[i][j].adjacentMines == 0) {
                        cout << " ";
                    } else {
                        cout << board[i][j].adjacentMines;
                    }
                } else if (board[i][j].state == CellState::FLAGGED) {
                    cout << "F";
                } else {
                    cout << "#";
                }

                if (i == currentRow && j == currentCol) {
                    cout << "]";
                } else {
                    cout << " ";
                }
            }
            cout << endl;
        }
    }

    // 计算已标记的地雷数
    int countFlags() {
        int count = 0;
        for (int i = 0; i < rows; ++i) {
            for (int j = 0; j < cols; ++j) {
                if (board[i][j].state == CellState::FLAGGED) {
                    ++count;
                }
            }
        }
        return count;
    }

    // 递归揭示空白区域
    void revealEmptyCells(int row, int col) {
        if (row < 0 || row >= rows || col < 0 || col >= cols) return;
        if (board[row][col].state != CellState::HIDDEN) return;

        board[row][col].state = CellState::REVEALED;
        ++revealedCells;

        if (board[row][col].adjacentMines == 0) {
            for (int i = max(0, row - 1); i <= min(rows - 1, row + 1); ++i) {
                for (int j = max(0, col - 1); j <= min(cols - 1, col + 1); ++j) {
                    if (i != row || j != col) {
                        revealEmptyCells(i, j);
                    }
                }
            }
        }
    }

    // 检查游戏是否胜利
    bool checkWin() {
        return revealedCells == rows * cols - mines;
    }

public:
    Minesweeper(int r, int c, int m) : rows(r), cols(c), mines(m) {
        srand(time(nullptr));
        initializeBoard();
        hideCursor();
    }

    // 开始游戏
    void play() {
        int currentRow = 0;
        int currentCol = 0;

        while (!gameOver && !win) {
            displayBoard(currentRow, currentCol);

            int key = _getch();

            // 处理方向键
            if (key == 0 || key == 224) {
                int direction = _getch();
                switch (direction) {
                    case 72: // 上
                        currentRow = max(0, currentRow - 1);
                        break;
                    case 80: // 下
                        currentRow = min(rows - 1, currentRow + 1);
                        break;
                    case 75: // 左
                        currentCol = max(0, currentCol - 1);
                        break;
                    case 77: // 右
                        currentCol = min(cols - 1, currentCol + 1);
                        break;
                }
            }
            // 处理空格(揭示)
            else if (key == 32) {
                if (board[currentRow][currentCol].state == CellState::HIDDEN) {
                    if (board[currentRow][currentCol].hasMine) {
                        gameOver = true;
                        // 显示所有地雷
                        for (int i = 0; i < rows; ++i) {
                            for (int j = 0; j < cols; ++j) {
                                if (board[i][j].hasMine) {
                                    board[i][j].state = CellState::REVEALED;
                                }
                            }
                        }
                    } else {
                        revealEmptyCells(currentRow, currentCol);
                        win = checkWin();
                    }
                }
            }
            // 处理F键(标记地雷)
            else if (key == 'f' || key == 'F') {
                if (board[currentRow][currentCol].state == CellState::HIDDEN) {
                    board[currentRow][currentCol].state = CellState::FLAGGED;
                } else if (board[currentRow][currentCol].state == CellState::FLAGGED) {
                    board[currentRow][currentCol].state = CellState::HIDDEN;
                }
            }
        }

        displayBoard(currentRow, currentCol);

        if (gameOver) {
            cout << "游戏结束!踩到地雷了!" << endl;
        } else if (win) {
            cout << "恭喜你,胜利了!" << endl;
        }
    }
};

int main() {
    int rows, cols, mines;
    cout << "欢迎来到超级扫雷游戏!" << endl;
    cout << "请输入游戏难度:" << endl;
    cout << "1. 初级 (9x9, 10个地雷)" << endl;
    cout << "2. 中级 (16x16, 40个地雷)" << endl;
    cout << "3. 高级 (16x30, 99个地雷)" << endl;
    cout << "4. 自定义" << endl;
    int choice;
    cin >> choice;

    switch (choice) {
        case 1:
            rows = 9;
            cols = 9;
            mines = 10;
            break;
        case 2:
            rows = 16;
            cols = 16;
            mines = 40;
            break;
        case 3:
            rows = 16;
            cols = 30;
            mines = 99;
            break;
        case 4:
            cout << "请输入行数: ";
            cin >> rows;
            cout << "请输入列数: ";
            cin >> cols;
            cout << "请输入地雷数: ";
            cin >> mines;
            if (mines >= rows * cols) {
                cout << "地雷数不能大于等于格子总数!" << endl;
                return 1;
            }
            break;
        default:
            cout << "无效选择,使用默认难度(初级)" << endl;
            rows = 9;
            cols = 9;
            mines = 10;
    }

    Minesweeper game(rows, cols, mines);
    game.play();

    return 0;
}    

//扫雷进阶版gzjun原版代码

0 条评论

目前还没有评论...

信息

ID
116
时间
1000ms
内存
256MiB
难度
8
标签
递交数
56
已通过
9
上传者