一个使用 Go 和 Ebitengine 编写的本地双人中国象棋程序。项目包含完整的棋盘绘制、鼠标落子、基础走法校验、将军、将死和困毙判断,不依赖运行时图片文件。
需要 Go 1.25 或更高版本。go.mod 会优先使用包含最新安全修复的 Go 1.26.5 工具链;启用 Go 默认的工具链自动下载功能即可自动获取。
GO111MODULE=on go run .当前机器若没有把 GO111MODULE 全局设置为 off,也可以直接执行 go run .。项目还提供了常用命令:
make run # 启动游戏
make test # 执行测试
make vuln # 扫描代码实际可达的 Go 漏洞
make check # 测试、静态检查、漏洞扫描并构建到 bin/simplechessVS Code 的 Run SimpleChess 调试配置已经显式启用 Go Modules。
- 点击当前行棋方的一枚棋子进行选择。
- 点击同阵营棋子可切换选择。
- 点击空位或对方棋子尝试落子;非法走法不会改变棋局。
- 将死或困毙后,点击鼠标重新开始。
main.go 程序入口
core/game.go Ebitengine 输入、绘制和 UI 状态
core/rules.go 棋子走法、合法着、将军与终局判断
core/helper.go Position、FEN 解析和棋盘辅助函数
core/assets.go 棋盘、棋子、遮罩和字体的一次性加载缓存
core/define.go 棋子编码及界面常量
core/resource/ 编译进程序的 PNG 字节资源
cmd/file2byteslice/ 跨平台资源转 Go 字节数组工具
棋盘使用长度为 90 的数组按行存储。棋子整数的低三位表示类型,颜色位分别使用 Red=8 和 Black=16。Position 是唯一规则状态,包含棋盘、当前行棋方及 FEN 回合计数。
合法着统一经过以下流程:
生成棋子的伪合法走法 → 在棋盘副本上落子 → 检查己方将帅是否受攻 → 保留合法着
将帅位置从模拟后的棋盘查找,不保存容易失步的位置缓存。将军、将死和困毙也都从当前 Position 计算,不保存跨回合的布尔状态。
项目采用 Pikafish FEN 规范。完整格式包含六个字段:
<棋盘> <行棋方> - - <未吃子步数> <当前回合>
- 棋子使用
k/a/b/c/n/r/p表示将(帅)、士、象(相)、炮、马、车、卒(兵),红方使用大写字母。 w表示红方行棋,b表示黑方行棋;解析时兼容r表示红方,但序列化统一输出w。- 第三、第四字段是从国际象棋 FEN 保留的占位符,在中国象棋中固定为
- -。 - 第五字段记录连续未吃子的着数(ply)。只有吃子会把它清零,兵或卒不吃子移动时同样递增。
- 第六字段是当前回合号,黑方走完后递增。
ParseFEN 同时接受只含棋盘和行棋方的两字段简写,并默认补为 - - 0 1;Position.FEN() 始终生成规范的六字段形式,Position.BasicFEN() 可生成两字段形式。标准初始局面是:
rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
Pikafish 的 moves ... 是 FEN 之外的着法历史扩展,目前不由 ParseFEN 处理。
GO111MODULE=on go test ./... -count=1
GO111MODULE=on go test -race ./core
GO111MODULE=on go vet ./...
GO111MODULE=on go run golang.org/x/vuln/cmd/govulncheck@v1.6.0 ./...测试覆盖:
- Pikafish 两字段/六字段 FEN 的规范化、往返转换和非法输入;
- 车、马、象、士、将、炮、兵的基础几何及棋盘边界;
- 蹩马腿、塞象眼、炮架和过河兵;
- 将帅纵向移动、将帅照面、送将和逃将;
- 将军、将死、困毙及重新开局;
- 初始局面 44 个合法着和所有生成目标的边界性质;
- 内嵌 PNG 的格式及尺寸。
运行时会在启动阶段解码每张图片一次,之后每帧直接复用 *ebiten.Image。core/resource/boardbytes.go 和 piecebytes.go 是生成文件,不应手工编辑。
仓库保留了原有的 Windows 工具 file2byteslice.exe,同时提供了跨平台 Go 版本:
GO111MODULE=on go run ./cmd/file2byteslice \
-package resource \
-output core/resource/boardbytes.go \
Boardbytes=core/resource/board.png每个输入参数使用 Go变量名=文件路径 的形式,可以在同一文件中生成多个资源变量。重新生成包含多张图片的文件时,需要在同一次命令中列出该文件的全部变量。
目前是本地双人对弈,不包含 AI、联网、悔棋、存档和棋盘翻转。基础合法着及困毙规则已经实现;需要依赖历史着法的长将、长捉、重复局面裁定和自然限着和棋尚未实现。