Soma Zero Tutorials
🔍 搜索功能尚未开启,敬请期待。

2.9 禁手与开局平衡(进阶)

这是一节进阶/选学。我们 v1 一直玩的是 freestyle(无禁手、自由开局),可它有个先天毛病:先手必胜(1.1 讲过,Allis 1994 已证明)。竞技五子棋为了公平,会加两层规则——连珠禁手开局平衡协议。好消息是:它们都只是规则的“加层”,前面那套引擎主体几乎不用改

一、连珠禁手:给强势的黑棋戴镣铐

既然先手(黑)占便宜,那就只限制黑棋。这就是连珠(Renju)禁手——白棋完全不受限,黑棋则有三条禁令,踩中即判负:

  • 双三禁手:一手同时形成两个活三(同时支起两个“下一步成活四”的威胁)。
  • 双四禁手:一手同时形成两个四。
  • 长连禁手:连成六子或更多。对黑棋这不算赢、反而判负(白棋长连则照样算赢)。

对引擎的影响很小、也很局部:这本质上只是给“合法走子”和“胜负判定”多加几条判断。legal_moves() 里把黑棋的禁手点排除(或标记为负),在 winner() 里处理“黑长连判负”即可——搜索、评估、VCF 那一整套原封不动。唯一要当心的是:判定“双三/双四”本身有点绕(要准确识别什么是“活三”、且排除被禁手反制的假威胁),但它复用的还是 2.3 那套棋型识别的功夫。

一个值得知道的事实:即便加了禁手,连珠依然是先手(黑)必胜(Wágner & Virág 2001 已解出)。禁手削弱了黑棋,但不够——所以真正的职业比赛还要再叠下面的开局规则。

二、swap2:不改走法,改“谁拿哪边”

另一条路不去限制走法,而是在开局做文章,核心机制是让摆开局的人不敢摆得太强,因为对手可以挑边

  • swap(交换):甲先摆 3 子(2 黑 1 白)形成一个开局,然后乙选择拿黑还是拿白。甲要是把开局摆得对黑有利,乙就直接拿黑——所以甲被逼着摆一个尽量均衡的开局。
  • swap2:更强的平衡。甲摆 3 子后,乙有三个选择:① 拿黑接着下;② 拿白接着下;③ 再加摆 2 子(第 4、5 手),然后反过来让甲挑黑白。这是正经自由规则比赛(如 Gomocup)的标准协议。

它对引擎的影响也只在开局阶段:多了一个“评估开局、决定挑哪边/要不要加摆”的决策层,而这恰好可以复用引擎已有的局面评估——让引擎给各个选项打分,挑对自己最有利的那个。开局之后,进入正常对弈,搜索那套完全照旧

一句话点透两者的区别:禁手是“限制先手能怎么走”,swap2 是“不让先手优势固定归属某一方”。前者改胜负判定,后者改开局流程,但都没动引擎的搜索内核。

三、小结与下一节

  • 为什么要平衡:freestyle 先手必胜,竞技需要公平。
  • 连珠禁手:只限黑棋(双三/双四/长连判负);引擎只需在 legal_moves/winner 加判断,复用棋型识别;但加禁手后黑棋仍必胜。
  • swap2:靠“摆开局 + 对手挑边”消解固定先手优势;只在开局阶段加一个决策层,复用已有评估。
  • 共同点:都是规则“加层”,搜索内核不动。

规则层补完,本章就剩最后的收口了。下一节 2.10 Capstone,我们把五子棋的 pygame 人机对弈(含威胁/必胜线高亮)、引擎天梯(Elo 评分)和开放信息接口整合起来,给第二章画个圆满的句号。