mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-06-28 16:35:55 +08:00
214acaf0fe
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
9.0 KiB
9.0 KiB
Gobang v2.0 — Rust 重写设计规格
概述
将 Gobang(五子棋)从 C + IUP + CMake 全面迁移到 Rust + Tauri + React + TypeScript, 参考 PathEditor 项目的 workspace 架构、工具链约定和开源规范。
技术栈
| 层 | 技术 |
|---|---|
| 核心引擎 | Rust (edition 2021, stable-x86_64-pc-windows-gnu) |
| 桌面框架 | Tauri 2.x |
| 前端 | React 19 + TypeScript strict + Vite |
| 网络 | renet(Rust 原生 ENet 协议实现) |
| 状态管理 | Zustand |
| 国际化 | i18next (zh-CN / en) |
| 包管理 | npm(前端)+ Cargo(Rust) |
Crate 结构
Gobang/
├── core/ # Rust 库 crate(纯逻辑,零 Tauri 依赖)
│ └── src/
│ ├── board.rs # 棋盘状态、落子验证、胜负判定
│ ├── rules.rs # 禁手规则
│ ├── ai/ # 传统算法 AI
│ │ ├── mod.rs
│ │ ├── evaluate.rs # 棋形评分
│ │ └── search.rs # Alpha-Beta 搜索
│ ├── network.rs # renet 网络对战
│ ├── record.rs # 棋谱记录与回放 (JSON)
│ ├── llm.rs # 大模型 API 客户端
│ └── lib.rs
├── gui/ # Tauri 桌面应用(薄层)
│ └── src/
│ ├── commands.rs # #[tauri::command] → core API
│ ├── lib.rs
│ └── main.rs
├── src/ # React 前端 (TypeScript strict)
│ ├── core/ # 前端纯逻辑(坐标转换、棋型常量)
│ ├── components/
│ │ ├── board/ # Canvas 棋盘渲染
│ │ ├── menu/ # 主菜单、设置
│ │ ├── game/ # 对局 UI
│ │ └── replay/ # 棋谱回放
│ ├── hooks/ # useGame, useTimer, useAI
│ ├── store/ # Zustand 状态管理
│ └── i18n/ # 中/英
├── Cargo.toml # workspace 根
├── rust-toolchain.toml # stable-x86_64-pc-windows-gnu
├── package.json
├── LICENSE # MIT
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── SECURITY.md
└── README.md
功能清单
v1.0 全部功能保留,Rust 重写:
| 模块 | 功能 | 实现位置 |
|---|---|---|
| 本地双人 | 同机两人轮流落子 | core/board.rs |
| 传统 AI | 5 级难度、禁手规则、Alpha-Beta 搜索 | core/ai/ |
| LLM AI | 大模型 API 接入对战 | core/llm.rs |
| 网络对战 | renet P2P 联机 | core/network.rs |
| 棋谱回放 | 对局记录 (JSON) 与复盘 | core/record.rs |
| 计时器 | 每回合限时(可选) | gui + frontend |
| 悔棋 | 撤销指定步数 | core/board.rs |
core crate 设计
board.rs — 棋盘引擎
不可变风格核心抽象。每次落子返回新棋盘,通过 Cow 优化内存:
pub struct Board {
size: usize,
cells: [[CellState; MAX_SIZE]; MAX_SIZE],
}
pub enum CellState { Empty, Black, White }
impl Board {
pub fn place(&self, pos: Position, color: Color) -> Result<Board, MoveError>;
pub fn check_win(&self, pos: Position) -> bool;
pub fn is_forbidden(&self, pos: Position) -> bool;
pub fn get_candidate_moves(&self) -> Vec<Position>;
}
MoveError枚举:OutOfBounds,Occupied,ForbiddenMove,GameOverplace()不修改 self,返回新 Board 或错误- 胜负判断:四方向连续扫描(复用 v1 的 DirInfo 思路,改为 Rust 迭代器)
- 禁手检测:长连、双三、双四检查
ai/ 模块 — 传统 AI
Trait 抽象,支持 AI 引擎切换:
pub trait AiEngine: Send + Sync {
fn best_move(&self, board: &Board, color: Color) -> Option<Position>;
}
pub struct AlphaBetaAi {
depth: usize,
defense_coefficient: f64,
}
evaluate.rs:棋形打分(连五、活四、冲四、活三、眠三、活二)search.rs:Alpha-Beta 剪枝 + 迭代加深 + 启发式落子排序- 难度 1-5 通过 depth 参数控制
network.rs — renet 网络对战
pub enum GameMessage {
Move { pos: Position, turn: u32 },
Undo { steps: u32 },
Resign,
Chat(String),
}
pub struct NetworkSession {
// renet client/server handle
}
- 服务端创建房间,客户端加入
- 可靠 UDP 传输,和原 ENet 行为一致
- 掉线检测 + 重连
record.rs — 棋谱 (JSON)
{
"version": "2.0",
"date": "2026-05-30",
"board_size": 15,
"players": { "black": "Human", "white": "AI-Lv3" },
"moves": [{"x": 7, "y": 7, "color": "Black"}, ...],
"result": "Black Win"
}
- 序列化/反序列化用
serde+serde_json - 回放:按步加载 move 历史,前端逐帧展示
llm.rs — 大模型 AI
- HTTP 客户端(
reqwest)调用 OpenAI 兼容 API - 将棋盘状态序列化为 prompt,解析模型回复的坐标
- 实现
AiEnginetrait,可替换 AlphaBetaAi
gui crate — Tauri 命令层
薄层,每个 #[tauri::command] 一行调用 core:
#[tauri::command]
fn place_piece(state: State<AppState>, x: usize, y: usize) -> Result<MoveResult, String> {
let mut game = state.game.lock().map_err(|e| e.to_string())?;
game.place(x, y).map_err(|e| e.to_string())
}
全局状态管理:
struct AppState {
game: Mutex<Game>,
}
enum GameMode {
Local,
VsAi(Box<dyn AiEngine>),
Online(NetworkSession),
Replay(ReplayState),
}
IPC 命令清单:
| Command | 参数 | 返回值 | 功能 |
|---|---|---|---|
new_game |
mode, board_size, config |
Result<(), String> |
开始新局 |
place_piece |
x, y |
Result<MoveResult, String> |
落子 |
undo |
steps |
Result<(), String> |
悔棋 |
get_board |
— | Board |
获取棋盘状态 |
ai_move |
— | Result<Position, String> |
请求 AI 走棋 |
connect_game |
ip, port |
Result<(), String> |
网络连接 |
send_message |
msg |
Result<(), String> |
网络消息 |
save_record |
path |
Result<(), String> |
保存棋谱 |
load_record |
path |
Result<RecordData, String> |
加载棋谱 |
get_game_config |
— | GameConfig |
读取设置 |
前端设计
组件树
App
├── MainMenu
│ ├── LocalGameSetup # 本地双人
│ ├── AiGameSetup # 难度、先手、禁手开关
│ ├── OnlineSetup # IP:端口 / 创建房间
│ └── LoadReplay # 加载棋谱文件
├── GameView
│ ├── BoardCanvas # Canvas 棋盘 + 点击落子
│ ├── GameInfo # 当前玩家、AI 思考中、胜负提示
│ ├── TimerDisplay # 倒计时(可选)
│ └── GameControls # 悔棋、认输、保存
└── ReplayView
├── BoardCanvas # 只读棋盘
├── StepSlider # 步数滑条
└── ReplayControls # 播放/暂停/快进
数据流
用户点击棋盘 → BoardCanvas.onClick
→ store.placePiece(x, y)
→ invoke('place_piece', {x, y}) # Tauri IPC
→ gui/commands.rs → core::Board::place()
→ store 更新 board / currentColor
→ React 重渲染 BoardCanvas
Canvas 渲染要点
useRef<HTMLCanvasElement>+requestAnimationFrame- 棋盘线、棋子(渐变填充仿木纹风格)、最后一手高亮标记
- 坐标纯函数:
boardToCanvas(pos, cellSize, padding) → {x, y} - 支持窗口 resize 自适应棋盘大小
状态管理 (Zustand)
interface GameStore {
mode: GameMode;
board: CellState[][];
currentColor: Color;
moves: Move[];
gameStatus: 'waiting' | 'playing' | 'ai_thinking' | 'game_over';
winner: Color | null;
// actions
startGame: (config: GameConfig) => Promise<void>;
placePiece: (x: number, y: number) => Promise<void>;
undo: () => Promise<void>;
loadReplay: (path: string) => Promise<void>;
}
错误处理策略
| 层 | 策略 |
|---|---|
| core | Result<T, MoveError> / Result<T, GameError>,中文错误消息 |
| gui | Result<T, String>,to_string() 转换,Tauri 自动序列化 |
| 前端 | .catch() 显示错误 toast,isSaving 防并发点击 |
构建与测试
# 开发模式
npm install
npx tauri dev
# Rust 检查
cargo check
cargo clippy -- -D warnings
cargo fmt --check
# 测试
cargo test # Rust 单元测试
npm test # 前端单元测试 (Vitest)
# 生产构建
npx tauri build
测试覆盖率目标:80%+
与 PathEditor 一致的设计决策
- 工具链:
stable-x86_64-pc-windows-gnu - Workspace:
resolver = "2", edition 2021 - 前端:TypeScript strict, Vitest, i18next
- 开源文件:LICENSE (MIT), CHANGELOG.md, CODE_OF_CONDUCT.md, CONTRIBUTING.md, SECURITY.md
- 提交格式:约定式提交(
feat:,fix:,refactor:等) - 版本管理:
Cargo.tomlworkspace.package.version +package.jsonversion 集中管理