#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>

using namespace std;

// 游戏配置(可自定义)
const int ROWS = 9;        // 行数
const int COLS = 9;        // 列数
const int MINE_COUNT = 10; // 地雷数量

// 地图状态枚举
enum CellState {
    HIDDEN = -2,    // 未揭开
    FLAG = -3,      // 标记为地雷
    MINE = -1       // 地雷
};

// 全局变量
int gameMap[ROWS][COLS];    // 真实地图:-1=地雷,0-8=周围地雷数
int showMap[ROWS][COLS];    // 显示地图:-2=隐藏,-3=标记,0-8=显示数字

// 初始化游戏地图
void initMap() {
    // 初始化两个地图
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            gameMap[i][j] = 0;
            showMap[i][j] = HIDDEN;
        }
    }

    // 随机生成地雷
    srand(time(0));
    int minePlaced = 0;
    while (minePlaced < MINE_COUNT) {
        int r = rand() % ROWS;
        int c = rand() % COLS;
        if (gameMap[r][c] != MINE) {
            gameMap[r][c] = MINE;
            minePlaced++;
        }
    }

    // 计算每个位置周围的地雷数
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            if (gameMap[i][j] == MINE) continue;

            int count = 0;
            // 检查周围8个方向
            for (int dr = -1; dr <= 1; dr++) {
                for (int dc = -1; dc <= 1; dc++) {
                    if (dr == 0 && dc == 0) continue; // 跳过自己
                    int nr = i + dr;
                    int nc = j + dc;
                    // 检查边界
                    if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS) {
                        if (gameMap[nr][nc] == MINE) {
                            count++;
                        }
                    }
                }
            }
            gameMap[i][j] = count;
        }
    }
}

// 打印游戏界面
void printMap() {
    system("cls"); // 清屏(Windows),Linux/Mac 用 "clear"
    cout << "======= 扫雷游戏 =======" << endl;
    cout << "操作说明:" << endl;
    cout << "1. 揭开格子:输入 r c (行 列,从0开始)" << endl;
    cout << "2. 标记/取消标记地雷:输入 f r c" << endl;
    cout << "3. 退出游戏:输入 q" << endl;
    cout << "========================" << endl;

    // 打印列号
    cout << "   ";
    for (int j = 0; j < COLS; j++) {
        cout << setw(2) << j;
    }
    cout << endl;

    // 打印行号和地图
    for (int i = 0; i < ROWS; i++) {
        cout << setw(2) << i << " ";
        for (int j = 0; j < COLS; j++) {
            switch (showMap[i][j]) {
                case HIDDEN:
                    cout << "■ "; // 未揭开的格子
                    break;
                case FLAG:
                    cout << "⚑ "; // 标记的地雷
                    break;
                case 0:
                    cout << "  "; // 空白(0个地雷)
                    break;
                default:
                    cout << showMap[i][j] << " "; // 显示数字
                    break;
            }
        }
        cout << endl;
    }
}

// 递归展开空白区域
void expandArea(int r, int c) {
    // 边界检查、已揭开、标记的格子不处理
    if (r < 0 || r >= ROWS || c < 0 || c >= COLS || 
        showMap[r][c] != HIDDEN || showMap[r][c] == FLAG) {
        return;
    }

    // 显示当前格子
    showMap[r][c] = gameMap[r][c];

    // 如果是空白格(0),递归展开周围8个方向
    if (gameMap[r][c] == 0) {
        for (int dr = -1; dr <= 1; dr++) {
            for (int dc = -1; dc <= 1; dc++) {
                if (dr == 0 && dc == 0) continue;
                expandArea(r + dr, c + dc);
            }
        }
    }
}

// 检查游戏是否胜利
bool checkWin() {
    int hiddenCount = 0;
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            // 未揭开的格子数 == 地雷数 则胜利
            if (showMap[i][j] == HIDDEN) {
                hiddenCount++;
            }
        }
    }
    return hiddenCount == MINE_COUNT;
}

// 处理玩家输入
bool handleInput() {
    char cmd;
    cout << "\n请输入操作:";
    cin >> cmd;

    if (cmd == 'q' || cmd == 'Q') {
        cout << "游戏退出!" << endl;
        return false;
    }
    else if (cmd == 'f' || cmd == 'F') {
        // 标记/取消标记地雷
        int r, c;
        cin >> r >> c;
        if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
            cout << "输入坐标超出范围!" << endl;
            system("pause");
            return true;
        }
        if (showMap[r][c] == HIDDEN) {
            showMap[r][c] = FLAG; // 标记
        }
        else if (showMap[r][c] == FLAG) {
            showMap[r][c] = HIDDEN; // 取消标记
        }
        else {
            cout << "已揭开的格子不能标记!" << endl;
            system("pause");
        }
    }
    else if (isdigit(cmd)) {
        // 揭开格子(输入格式:行 列)
        int r = cmd - '0';
        int c;
        cin >> c;

        if (r < 0 || r >= ROWS || c < 0 || c >= COLS) {
            cout << "输入坐标超出范围!" << endl;
            system("pause");
            return true;
        }

        // 踩到地雷
        if (gameMap[r][c] == MINE) {
            // 显示所有地雷
            for (int i = 0; i < ROWS; i++) {
                for (int j = 0; j < COLS; j++) {
                    if (gameMap[i][j] == MINE) {
                        showMap[i][j] = MINE;
                    }
                }
            }
            printMap();
            cout << "游戏结束!你踩到地雷了!" << endl;
            return false;
        }

        // 揭开空白区域
        if (showMap[r][c] == HIDDEN) {
            expandArea(r, c);
        }

        // 检查胜利
        if (checkWin()) {
            printMap();
            cout << "恭喜你!扫雷成功!" << endl;
            return false;
        }
    }
    else {
        cout << "输入格式错误!请重新输入!" << endl;
        system("pause");
    }
    return true;
}

// 主函数
int main() {
    initMap();
    bool isRunning = true;

    while (isRunning) {
        printMap();
        isRunning = handleInput();
    }

    system("pause");
    return 0;
}