Go Board 系统架构与功能文档
项目:go-board-cpp
日期:2026-05-14
版本:v1
一、系统总览
一个完整的围棋对弈系统,支持实体棋盘(ESP32-CAM)+ AI 对战 + 打谱 + 棋谱管理。
┌─────────────────────────────────────────────────────────┐
│ go-game.exe │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────────┐ │
│ │ 启动对话框 │ │ 游戏窗口 │ │ AI REST 服务 │ │
│ │ 模式选择 │ │ 虚拟棋盘 │ │ ai_server.py │ │
│ │ 计时设置 │ │ LiveView │ │ (Flask + KataGo) │ │
│ │ 输入方式 │ │ DewarpView│ │ │ │
│ └──────────┘ │ 控制栏 │ └──────────────────────┘ │
│ └───────────┘ │
└─────────────────────────────────────────────────────────┘
二、模块分层架构
src/
├── core/ ← 领域层 (零 UI 依赖)
│ ├── GoBoard 围棋规则引擎 (气/劫/目)
│ ├── GoGame 游戏控制器 (回合/计时/AI/悔棋)
│ ├── GoTimer 日本式读秒计时器
│ ├── GoSound 落子/提子音效
│ └── SgfParser SGF 棋谱解析/保存
│
├── command/ ← 命令模式
│ ├── ICommand 命令接口
│ └── CommandInvoker 调度器 (undo/redo)
│
├── engine/ ← AI 引擎层
│ ├── IGoEngine AI 抽象接口
│ ├── HttpEngine HTTP REST 客户端 (对接 ai_server.py)
│ ├── GtpEngine QProcess GTP 客户端 (备用)
│ └── MockEngine 测试桩 (随机落子)
│
├── detect/ ← 视觉检测层
│ ├── StarPointDetector YOLO ONNX 星位检测
│ ├── StoneDetector FCN 棋子分类 (AI + 阈值双模式)
│ ├── MoveDetector 帧差法落子检测
│ ├── BoardRectifier 单应矩阵 + 透视矫正
│ ├── PersistentCalibrator 标定持久化
│ ├── GoBoardDetector 单应计算 + 网格生成 + 矫正图
│ ├── LiveView 实时相机预览
│ ├── DewarpView 矫正图预览
│ └── MarkWidget 人工星位标记
│
├── capture/ ← 相机采集
│ └── CameraCapture USB + MJPEG 双模式
│
├── net/ ← 网络
│ └── MjpegStream ESP32-CAM MJPEG 流
│
└── ui/ ← 界面组件
├── MainWindow 标定工具主窗口
└── GoBoardWidget 虚拟棋盘控件 (3D棋子 + 动画)
三、视觉系统
3.1 双模型选型
| 星位检测 | 棋子分类 | |
|---|---|---|
| 模型 | YOLOv8-nano | 自定义 FCN |
| 任务 | 目标检测 (在哪) | 网格分类 (是什么) |
| 输入 | 原始帧 640×640 BGR | 矫正图 304×304 RGB |
| 输出 | 9个 bbox | 361字符 (.B.W) |
| 大小 | 12MB | 1.7MB |
| 调用 | 标定时1次 | 每帧确认时1次 |
3.2 标定流程
相机帧 → StarPointDetector (YOLO) → 9星位坐标
→ 空间排序 + 身份匹配 → 4角星位
→ findHomography → 单应矩阵 H
→ PersistentCalibrator 持久化
3.3 棋子检测流程
相机帧 → rectifyFrame(H) → 600×600 矫正图
→ StoneDetector.classify() → 361字符局面
→ diff vs GoGame 权威状态 → 提取落子
→ GoGame.play() → 规则校验 → 虚拟棋盘更新
四、AI 对弈系统
4.1 架构:HTTP REST 模式
go-game.exe ──HTTP──→ ai_server.py (Flask) ──GTP──→ KataGo (OpenCL)
HttpEngine Python 管管道 Intel Arc GPU
为什么不用 QProcess 直连 GTP:管道死锁问题。Python 的 read1() + 线程锁比 Qt 的 waitForReadyRead 更可靠。
4.2 REST API
| 端点 | 方法 | 请求 | 响应 |
|---|---|---|---|
/health |
GET | — | {"status":"ok","engine":"KataGo","version":"1.12.4"} |
/genmove |
POST | {"board":"361chars","color":"B"} |
{"row":3,"col":15,"gtp":"Q16"} |
/shutdown |
POST | — | — |
4.3 增量同步优化
首次调用全量同步(clear_board + 逐子 play),之后每步只发 1 条 play 命令(新增棋子)。提子时回退全量同步。
4.4 IGoEngine 接口
class IGoEngine {
virtual bool initialize() = 0;
virtual std::pair<int,int> generateMove(boardState, color) = 0;
virtual void setLevel(int) = 0;
virtual std::string name() const = 0;
virtual bool isReady() const = 0;
virtual void shutdown() = 0;
};
三个实现:HttpEngine (主力) / GtpEngine (备用) / MockEngine (fallback)
4.5 AI 自动落子
GoGame::play() → 回合切换到 AI → requestAiMove() → 300ms 后异步执行 → engine->generateMove() → GoGame::play(row,col) → aiMoveReady 信号。
五、游戏模式
5.1 启动对话框
┌─ 围棋 — 新局设置 ────────────┐
│ 对局模式 │
│ [👤 人人对弈 ▼] │
│ [🤖 人机(执黑)] │
│ [🤖 人机(执白)] │
│ [📜 打谱] │
│ │
│ 输入方式 │
│ [🖥 屏幕点击 / 📷 实体棋盘] │
│ 相机URL: [...] │
│ │
│ 棋盘: [19×19 ▼] │
│ ⏱ 计时: 30分 + 3次×30秒 │
│ 贴目: [6.5] │
│ │
│ [开始对局] [退出] │
└───────────────────────────────┘
5.2 虚拟棋盘模式
- 直接点击交叉点落子
- 空格键无操作
- AI 回合自动触发,棋盘短暂禁用
5.3 实体棋盘模式
┌─ 实体棋盘 UI ──────────────────────────────────────┐
│ [LiveView 320×240] [DewarpView 280×280] 状态信息 │
│ │
│ ┌───────────────────────────────────────────────┐ │
│ │ ✅ 确认落子 (空格键) │ │
│ └───────────────────────────────────────────────┘ │
│ │
│ [虚拟棋盘 — 显示 GoGame 权威局面] │
└─────────────────────────────────────────────────────┘
确认流程:相机帧 → 矫正 → 检测 → diff → GoGame.play() → 200ms 后虚拟棋盘同步为 GoGame 状态。
5.4 打谱模式
- 加载
.sgf文件 - 导航:
◀◀ 首手 ◀ 上步 ▶ 下步 末手 ▶▶ 跳至 [N] - 空格键 = 前进一手(最常用操作一键完成)
- 棋盘只读显示
- 显示棋手名、结果、当前手数/总手数
六、棋谱系统 (SGF)
6.1 SgfParser
SgfNode (树节点)
├── props: {"B":"dd", "C":"好棋", "PB":"Logic"}
├── multi: {"AB":["dd","pp"]}
├── children[0] = 主线
├── children[1..] = 分支
└── parent → 向上遍历
SgfParser
├── loadFile/loadString → 解析 SGF
├── toString/saveFile → 导出 SGF
└── root() → 根节点
6.2 坐标转换 (SgfUtil)
| 棋盘 | SGF | 含义 |
|---|---|---|
| (3,3) | dd |
左上星位 |
| (15,15) | pp |
右下星位 |
| (9,9) | jj |
天元 |
SGF 列 a-s,行 a-s(a=顶)。
6.3 保存对局
- 随时按
💾 保存→ 弹出名称编辑对话框 - 文件名自动:
黑方_vs_白方_时间戳.sgf - 对局结束(Pass×2/超时/计目)自动弹出保存
- 支持重命名、改路径
七、空格键交互
onSpaceKey() 智能分发:
当前模式?
├── 📜 打谱 → 前进一手 (onKifuNext)
├── 📷 实体 → 确认识别 (onPhysicalConfirm)
└── 🖥 虚拟 → 无操作
八、AI 引擎环境
8.1 组件
| 文件 | 说明 |
|---|---|
engines/katago-opencl/katago.exe |
KataGo v1.12.4 OpenCL |
engines/model.bin.gz |
b18c384nbt-uec (93MB) |
engines/gtp.cfg |
Chinese规则, 100 visits, 4线程 |
scripts/ai_server.py |
Flask REST 服务器 |
8.2 启动方式
# 终端1 — AI 服务
python scripts/ai_server.py \
--katago engines/katago-opencl/katago.exe \
--model engines/model.bin.gz \
--config engines/gtp.cfg
# 终端2 — 游戏
go-game.exe
九、构建系统
go-core.lib ← 领域层 (GoBoard, GoGame, GoTimer, SgfParser, CommandInvoker)
go-engine.lib ← AI 层 (HttpEngine, GtpEngine, MockEngine)
go-game.exe ← 完整对弈 (go_game.cpp + UI + Camera + Detection)
go-board-calib.exe ← 精简标定工具
go-board-calib-demo.exe ← 全功能标定工具
CMake: MSVC 2022 + Qt 6.10.3 + OpenCV 4.12.0 (vcpkg)
十、文档索引
| 文档 | 内容 |
|---|---|
ARCHITECTURE.md |
v3 架构总览 |
calibration-bugfix-postmortem.md |
标定 Bug 修复记录 (4 bugs) |
dual-model-selection.md |
YOLO vs FCN 选型说明 |
gtp-katago-explained.md |
GTP 协议与 KataGo 通俗讲解 |
game-plan.md |
对战 & 打谱开发路线图 |
game-features-v1.md |
游戏功能说明 |
physical-to-virtual-mapping.md |
实体棋盘→虚拟棋盘映射设计 |