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 实体棋盘→虚拟棋盘映射设计