# minesweeper **Repository Path**: laizx/minesweeper ## Basic Information - **Project Name**: minesweeper - **Description**: 用QT实现的扫雷游戏,大家可以拿去作为初学QT的例子! - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-09 - **Last Updated**: 2026-09-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 扫雷游戏 (Minesweeper) 一个使用 Qt5 开发的经典扫雷游戏,支持自定义棋盘大小、地雷数量、撤销功能、音效等特性。 主要借助 [TRAE](https://www.trae.cn/) 进行开发。 ## 项目概述 这是一个基于 Qt5 框架的跨平台扫雷游戏,实现了经典扫雷游戏的核心功能,包括左右键双击自动翻开、安全格自动标记等高级特性。 ## 系统架构 ### 整体架构图 ``` main.cpp (程序入口点) ─────────────────────────────────────────────────────────────── │ ▼ MainWindow ┌──────────────────────────────────────────────────────────┐ │ UI │ │ ┌───────────┐ ┌────────────┐ ┌──────────┐ ┌───────────┐ │ │ │mineDisplay│ │timerDisplay│ │newGameBtn│ │settingsBtn│ │ │ └───────────┘ └────────────┘ └──────────┘ └───────────┘ │ └──────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────┐ │ GameBoard │ │ ┌─────────────────────────────────────────────────────┐│ │ │ MineCell[][] ││ │ │ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ││ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │ │ ├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤ ││ │ │ │ │ │ │ │ │ │ │ │ │ │ ││ │ │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ ││ │ └─────────────────────────────────────────────────────┘│ └─────────────────────────────────────────────────────────┘ ─────────────────────────────────────────────────────────────── │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ SoundManager │ │ SettingsDialog │ │ MineHitDialog │ │ (音效管理) │ │ (设置对话框) │ │ (触雷对话框) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ ``` ### 模块层次结构
Presentation Layer (表示层/UI层)
MainWindow
- UI布局管理
- 计时器管理
- 窗口拖拽
SettingsDialog
- 游戏设置界面
- 参数调节器
- 音量控制
MineHitDialog
- 触雷/胜利弹窗
- 重试逻辑
Business Layer (业务逻辑层)
GameBoard (游戏核心)
- 棋盘状态管理 (Ready/Playing/Won/Lost)
- 地雷生成与布局
- 格子展开逻辑 (递归展开/数字显示)
- 胜负判定
- 撤销/重试功能
- 自动标记 (autoMarkMines)
- 整行整列标记检测 (checkLineComplete)
Entity Layer (实体层)
MineCell (格子)
- 格子状态 (Hidden/Revealed/Flagged/Question)
- 地雷标记
- 相邻地雷数
- 显示更新
- 鼠标事件处理
Support Layer (支撑层)
SoundManager
- 音效播放
- 音量控制
- 静音管理
## 模块详细说明 ### 1. MainWindow (主窗口) **职责:** - 管理游戏主界面的整体布局 - 控制计时器(开始、暂停、重置) - 管理工具栏按钮(新建游戏、设置、关于、退出) - 处理窗口拖拽移动 - 加载和保存游戏配置 **主要组件:** - `mineDisplay`: 剩余地雷数量显示(LCD数码管) - `timerDisplay`: 游戏时间显示 - `newGameBtn`: 新游戏按钮 - `settingsBtn`: 设置按钮 - `gameTimer`: 游戏计时器 **关键方法:** - `loadSettings()`: 从 INI 文件加载配置 - `saveSettings()`: 保存配置到 INI 文件 - `updateWindowSize()`: 根据棋盘大小更新窗口尺寸 - `startTimer()/pauseTimer()/resetTimer()`: 计时器控制 ### 2. GameBoard (游戏棋盘) **职责:** - 管理棋盘的创建、初始化和重置 - 处理格子点击事件(单击、双击) - 实现地雷随机生成 - 计算每个格子的相邻地雷数 - 实现递归展开空白格 - 判断游戏胜负 - 管理撤销和重试功能 - 实现自动标记和整行整列检测 **状态机:** ``` Ready ──点击──> Playing ──胜利──> Won │ └──触雷──> Lost ──重试──> Ready ``` **关键数据结构:** - `cells[row][col]`: 二维格子数组 - `historyStack`: 操作历史栈(用于撤销) - `retryStates`: 重试状态栈 **关键方法:** - `initBoard()`: 初始化棋盘 - `placeMines()`: 随机放置地雷 - `revealCell()`: 翻开格子 - `revealAllMines()`: 显示所有地雷 - `checkWin()`: 检查胜利条件 - `undo()`: 撤销操作 - `autoMarkMines()`: 自动标记确定的地雷 - `checkLineComplete()`: 检查整行/整列标记 ### 3. MineCell (格子) **职责:** - 管理单个格子的状态和显示 - 处理鼠标事件(左键、右键、双键) - 发送格子交互信号 **状态枚举:** - `Hidden`: 未翻开(默认状态) - `Revealed`: 已翻开 - `Flagged`: 已标记为地雷 - `Question`: 标记为问号 **关键方法:** - `reveal()`: 翻开格子 - `toggleFlag()`: 循环切换标记状态 - `revealWrongFlag()`: 显示错误标记 - `updateDisplay()`: 更新格子显示 **信号:** - `cellClicked(row, col)`: 左键点击 - `cellRightClicked(row, col)`: 右键点击 - `cellDoubleClicked(row, col)`: 双键同时按下 - `cellDoubleClickedReleased(row, col)`: 双键同时释放 ### 4. SettingsDialog (设置对话框) **职责:** - 提供游戏参数设置界面 - 调节行数、列数、地雷密度 - 控制音量 - 显示最佳记录 **可调参数:** - `rows`: 棋盘行数(5-30) - `cols`: 棋盘列数(5-50) - `mineDensity`: 地雷密度(百分比) - `maxUndoCount`: 最大撤销次数(0-3) - `volume`: 音量(0-100) ### 5. SoundManager (音效管理) **职责:** - 管理所有游戏音效 - 控制音量和静音 **音效类型:** - `Click`: 单击音效 - `DoubleClick`: 双击音效 - `GameOver`: 失败音效 - `Victory`: 胜利音效 ### 6. MineHitDialog (触雷对话框) **职责:** - 游戏结束时显示弹窗 - 提供结束游戏或重试选项 **模式:** - `GameOver`: 游戏失败模式 - `Victory`: 游戏胜利模式 ## 文件结构 ``` minesweeper/ ├── main.cpp # 程序入口 ├── MainWindow.h/cpp # 主窗口 ├── GameBoard.h/cpp # 游戏棋盘核心 ├── MineCell.h/cpp # 单个格子 ├── SettingsDialog.h/cpp # 设置对话框 ├── SoundManager.h/cpp # 音效管理 ├── MineHitDialog.h/cpp # 触雷对话框 ├── resources.qrc # Qt资源文件 └── images/ # 图片资源 ├── mine.png # 地雷图标 ├── flag.png # 旗帜图标 └── question.png # 问号图标 ``` ## 编程规范 ### 命名规范 1. **类名**: PascalCase - `MainWindow`, `GameBoard`, `MineCell` 2. **方法名**: camelCase - `setBoardSize()`, `handleCellClick()`, `updateDisplay()` 3. **成员变量**: m 前缀 + camelCase - `mSoundManager`, `mVolume`, `boardRows` 4. **私有成员变量**: 可选使用 `m` 或直接 camelCase - `cellRow`, `cellCol`, `boardFlaggedCount` 5. **枚举值**: PascalCase - `GameStatus::Playing`, `CellState::Revealed` 6. **常量**: k_ 前缀 或 全大写 - `cellSize = 35` 或 `const int kDefaultCellSize = 35` ### Qt 信号槽规范 1. **信号声明**: 使用 `signals:` 块 2. **槽函数声明**: 使用 `private slots:` 或 `public slots:` 块 3. **信号连接**: 推荐使用新语法 `connect(sender, &Sender::signal, receiver, &Receiver::slot)` 4. **Lambda 使用**: 简单的槽函数可使用 lambda 表达式 ### 代码格式 1. **缩进**: 4空格 2. **大括号**: K&R 风格 ```cpp if (condition) { // code } ``` 3. **头文件保护**: `#ifndef NAME_H` / `#define NAME_H` / `#endif` 4. **包含顺序**: 本类头文件 → Qt 系统头文件 → 其他头文件 ### 注释规范 1. **文件头注释**: 描述文件功能 2. **类注释**: 描述类的作用 3. **方法注释**: 描述方法功能和参数 4. **行内注释**: 解释关键代码逻辑 5. **中文注释**: 优先使用中文 ### 内存管理 1. **父子对象关系**: 使用 Qt 的父子对象机制进行自动内存管理 2. **动态分配**: 使用 `new` 创建后设置合适的父对象 3. **避免内存泄漏**: 确保所有动态分配的对象在合适时机被删除 ### 配置管理 1. **配置文件格式**: INI 格式 2. **存储位置**: 程序所在目录 3. **配置内容**: 行数、列数、地雷数、撤销次数、音量等 ## 信号流向 ### 左键点击流程 ``` 用户点击格子 ↓ MineCell::mousePressEvent() ↓ MineCell::handleClick() ↓ emit cellClicked(row, col) 信号 ↓ GameBoard::handleCellClick(row, col) ↓ 游戏逻辑处理 ↓ emit mineCountChanged(count) 信号 ``` ### 右键点击流程 ``` 用户右键点击格子 ↓ MineCell::handleRightClick() ↓ emit cellRightClicked(row, col) 信号 ↓ GameBoard::handleCellRightClick(row, col) ↓ toggleFlag() → 状态切换 (Hidden→Flagged→Question→Hidden) ↓ emit mineCountChanged(count) 信号 ``` ### 计时器流程 ``` 游戏开始 (首次点击) ↓ MainWindow::onGameStatusChanged(Playing) ↓ startTimer() ↓ gameTimer timeout ↓ onTimerTimeout() ↓ elapsedSeconds++ ↓ 更新 timerDisplay ``` ## 配置说明 ### INI 文件格式 ```ini [Game] rows=20 # 棋盘行数 cols=30 # 棋盘列数 mineCount=150 # 地雷数量 maxUndoCount=3 # 最大撤销次数 volume=80 # 音量 (0-100) ``` ## 编译要求 - Qt5 开发库 - C++11 或更高标准 - 支持 Windows、Linux、macOS ## 许可 MIT License