# 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