我用 Rust 写了 MistyJungle,一个传统的斗兽棋引擎,棋盘为 7×9,这个游戏通常被称为 Jungle 或 Animal Chess。你可以 在 Mistboard 上与 MistyJungle 对局。它使用 alpha-beta 搜索、手工评估函数、重复局面处理,对局版本中没有任何神经网络。

结果很有限,但确实存在。对上我能跑起来的最强开源引擎,200 局中取得 11 胜 2 负 187 和,在一个和棋率很高的游戏里大约相当于 +16 Elo;它的四子残局表现与精确残局库一致,没有任何胜/和/负判断错误。我原本期待能带来提升的两项升级,学习型评估和搜索叶节点的残局库,都没有奏效。真正起作用的是传统搜索。

我做了什么

一个独立的 Rust 引擎,带有精简的 UCI 风格协议,可从命令行使用,也可通过 PyO3 在 Python 中调用。强度由节点预算决定,而不是时钟,所以同一个局面在任何机器上都会返回同样的着法。

整套结构很常规:带迭代加深的 negamax alpha-beta、Zobrist 置换表、对吃子和进兽穴着法的静态搜索延伸,以及配合 PVS 和后期着法削减的杀手着法/历史启发排序,底层是一个手工评估函数,对子力、兽穴竞速、陷阱、河水和机动性进行打分。这些排序与剪枝上的打磨,在固定节点预算下实测值 +49 Elo。

在学习型修正能带来任何增益之前,评估函数必须先做对。斗兽棋以子力为主,但充满尖锐的例外:鼠能克象,落入陷阱的棋子失去等级,一步进兽穴便结束全局。

规格

双方各有八只动物,棋盘为 7×9,走入对方兽穴或吃光对方全部棋子即获胜。规则因地区而异,所以采用哪一套很重要。我使用的是 2026 年 6 月的 Mistboard/维基百科规则,其中狗高于狼(有些资料则相反)。

吃子等级,由强到弱

每种动物可以吃右侧的动物。鼠还能吃象。处于对方陷阱中的棋子等级视为零。

除了按等级吃子之外,三条规则赋予了这个游戏的战术性:

  • 鼠克象,但只在陆地上成立。最弱的棋子能吃掉最强的棋子。不过吃子不能跨越河岸,所以游进水里的鼠除了另一只鼠之外谁都吃不到。
  • 狮和虎可以跳河。只有鼠能进入水中。大猫则整条河一跃而过落到对岸,狮可横跳也可纵跳,虎只能纵跳,除非水中有鼠挡住跳跃路线。
  • 落入陷阱的棋子失去等级。每个兽穴周围的三格是陷阱。站在其中的敌方棋子等级降为零,任何棋子,哪怕是鼠,都能把它吃掉。

完整规则与可对局棋盘:mistboard.com/rules/jungle

结果

在强引擎之间大部分对局都以和棋收场的游戏里,这是一点微弱优势:

测试 结果
开源基准,200 局 11 胜 2 负 187 和,约 +16 Elo
搜索打磨(排序、PVS、LMR) +49 Elo,配对自对弈,p = 0.008
四子残局库校验 779/800 一致,0 处胜和负矛盾
五子与六子 对比 8 倍深度搜索 >99%(代理指标,非证明)
搜索叶节点的残局库 37 胜 40 负 3 和,约 -13 Elo
残差神经评估 最好约 -70 Elo

那 +49 是最难测出来的。两个水平相近的斗兽棋引擎和棋太多,胜率门槛不管用,所以我采用了配对、换边的自对弈(每个开局双方各走一遍,新搜索对旧搜索),并对有胜负的对局做符号检验。

数据

残局与求解现状

小规模残局可以用逆向分析攻克,而且它们是极好的裁判。Van Rijn 和 Vis 于 2013 年在莱顿解出了四子,Bohrweg 在 2016 年推进到七子(按莱顿约定,狗与狼互换)。我的引擎在 800 个局面中的 779 个上与精确四子着法一致,没有出现胜和负矛盾;在五子和六子上与 8 倍深度搜索的吻合率超过 99%。

那份七子数据库就是前沿,而越过它的障碍是存储,而不是求解技术。棋盘才是问题所在:63 格对翻棋斗兽棋的 16 格,所以每增加一个棋子就有约 60 个空格可站,而不是十几个,各层的规模增长速度约快五倍。翻棋斗兽棋的五子在我的笔记本上占 2.8 GB;斗兽棋的五子大约要 7 TB。八子及以上,也就是开局子力的一半,作为数据库是遥不可及的,而完整十六子游戏也没有人给出正向证明。斗兽棋已解到七子,七子以上仍然开放,而且很可能长期如此。

在搜索叶节点加载残局库对棋力也毫无帮助(约 -13 Elo):在能装下的规模上搜索本来就能找到答案,而真正能帮上忙的规模又装不下。翻棋斗兽棋那边的一个教训是,同样的实验最初也读作零效果,后来发现掩盖了一个 bug:那些表只存胜/和/负,不含距离,而只有胜和负信息的叶节点会让引擎在已经赢定的残局里无限拖延而不收官,因为每个获胜着法评价都一样。把将死距离加进表里之后,那边的收官问题就解决了。我这边斗兽棋的叶节点探测同样只有胜和负信息,所以那 -13 里可能有一部分是同一个效应,而不是残局库在叶节点毫无用处。未做验证;不管怎样,发布的传统引擎都不带这个探测。

学习型评估

卡住的是数据,不是架构。一个残差网络(手工分数加上有界修正)随着我不断修正标签,从 -470 Elo 爬到约 -70 Elo,但始终没能超过手工评估。而标签最弱的地方,恰恰是网络最需要帮助的地方:和棋居多的自对弈对子力变化的覆盖不足,精确残局库标签只覆盖小规模残局,而搜索分数标签基本上只教会网络模仿它本来就有的搜索。

AlphaZero

仍是未完成的工作。我没有跑完整的斗兽棋 AZ 攀升。相邻的 Banqi AZ 降风险实验没通过门槛,但那是另一个游戏,并不能否定 AZ 在斗兽棋上的可行性;斗兽棋其实是更友好的土壤:确定性、完全信息,没有随机节点的揭示。我把它搁下了,因为最便宜的那一级是负收益,而传统引擎已经打赢了基准。

对局示例

比赛大多是和棋,但有胜负的对局显示了优势的形态:先是兽穴压力,其次才是子力。这些回放从接近转化的阶段开始,想看开局请向左拖动。用 Tab 切到棋盘,再用左右方向键逐着浏览。

MistyJungle(黑方)建立子力优势,最后以狮进入红方兽穴收局:

另一盘黑胜,一次更短的挤压,在陷阱周围的交换之后,最后一个棋子抵达 d1:

一盘红胜说明为什么不能只数子力:MistyJungle 丢失子力,却赢下了兽穴竞速:

保存下来的最长胜局,红方磨了 283 着才抵达兽穴:

引擎自我对弈,每着 8M 节点,各约五秒:一场漫长的均势搏杀,红方守着一子优势撑了四十回合,随后转化,把狮走进黑方兽穴:

更富戏剧性的一盘,同样是 8M 节点的自我对弈:红方让黑方保留象、狮、虎,子力落后十六分,却仍然获胜,靠的是在子力优势发挥作用之前把鼠冲进兽穴。这最清楚地表明了引擎真正在优化什么:

结论

MistyJungle 是一个传统搜索引擎,对我能跑起来的最强开源引擎有一点可测量的微弱优势。真正提升棋力的工作并不光鲜:规则正确、固定预算测量、换边测试、搜索打磨和残局验证。残局库很会当裁判,但在叶节点没有帮助;神经网络的第一级输给了手工评估;而真正的 AlphaZero 攀升仍是未完成的工作。

资源: