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

2.10 Capstone:五子棋对弈 App 与天梯

第二章的收口。我们把这一章造出的几个引擎——启发式、AlphaZero、混合——装进一个能玩的 pygame 程序,让它们上擂台用 Elo 等级分排个真天梯,并把五子棋的开放信息接口彻底补齐,交付成一项 Anima 能调用的“五子棋技能”。

一、pygame 人机对弈:把威胁画出来

界面骨架直接搬第一章 1.8 那套——它只通过开放信息接口和引擎打交道,所以从井字棋换到五子棋,主要就是把棋盘画成 15×15、把点击映射到交叉点。换哪个引擎当对手,依旧是一行的事。

五子棋这里能做一件井字棋做不到的炫酷事情:因为引擎的 info() 现在能吐出威胁分析和必胜线(2.3、2.5 做的),界面可以把这些信息直接画在棋盘上——给对手的活三标黄、冲四标橙、AI 算到的 VCF 必胜线用箭头连出来。这一下,人机对弈就从“黑盒出招”变成了“能看懂 AI 在想什么”的教学利器:

info = engine.info()
for cell in info["threats"]["open_three"]:   # 活三:标黄
    draw_marker(screen, cell, COLOR_YELLOW)
for cell in info["threats"]["four"]:          # 冲四:标橙
    draw_marker(screen, cell, COLOR_ORANGE)
if info["forced_win"]["exists"]:              # 算到必胜线:画出来
    draw_winning_line(screen, info["forced_win"]["winning_line"])

二、引擎天梯:用 Elo 给棋力打分

到了五子棋,引擎之间真的能分出胜负了(不像井字棋全是和棋),于是 1.8 那座“自动对战擂台”终于能派上真正的用场:让各引擎两两循环赛,再用 Elo 等级分把它们排成一个天梯。

Elo 的核心是一条公式——已知双方分差,预测强者的期望胜率

EA  =  1 / ( 1 + 10(RBRA) / 400 )

这里 RARB 是两个引擎的等级分,EA 是 A 的期望胜率。直觉很好懂:分差每拉开 400 分,强者的期望胜率约为 10 比 1。一盘下完,再按“实际战绩 S(赢=1/和=0.5/输=0)和期望的差”来更新分数:

RA  ←  RA + K · ( SAEA )

赢了比预期多就加分、输了就掉分(K 是步长)。跑完整个循环赛,大致会得到这样一张天梯——它也定量印证了前面几节的论断:

名次引擎大致 Elo一句话
1混合引擎(NN + α-β + VCF)最高大局 + 算杀兼得(2.8)
2纯 AlphaZero大局强,偶尔漏深杀
3经典 α-β + 棋型 + VCF中高扎实,受人类知识限制
4纯启发(无 VCF、浅搜)能赢一般人类
5随机走子垫底陪练

三、开放信息接口:交付一项“五子棋技能”

最后把五子棋的 info() 补齐到“可交付给 Anima”的程度。对照 1.8 定稿的契约,五子棋这章把当初预留的两个字段都兑现了

def info(self):
    return {
        "board": self.board.tolist(),
        "to_move": self.to_move,
        "legal_moves": self.legal_moves(),
        "is_terminal": self.is_terminal(),
        "winner": self.winner(),
        "evaluation": self.evaluate(),                 # 局面分(2.3 / 2.8 的网络)
        "best_move": self.best_move(),                 # 推荐着法
        "threats": self.threat_analysis(),             # ★ 兑现:活三/冲四/活四清单(2.3)
        "forced_win": self.vcf_result(),               # ★ 兑现:N 步必杀线(2.5)
    }

这就是“开放信息接口”这条暗线在五子棋上的完整收获:引擎不再只是“给一步棋”,而是能完整回答“当前谁占优、最佳着法是什么、盘面上有哪些威胁、有没有几步内的必杀”。将来 Anima 把下棋当成一项技能调用时,问一句 info() 就全拿到了——而且这些都是人能看懂的信息,这正是它比纯黑盒模型珍贵的地方。

四、本章小结,与通往第三章

恭喜,你走完了整门课最硬核的一章!回看这条由“局限驱动”的升级链:朴素 α-β 慢到不可用 → 候选生成 + 迭代加深 → 棋型评估 → 走子排序 → 威胁搜索/VCF 算杀 → 置换表提速 → AlphaZero 学出棋感 → 混合引擎集大成。每一步都在回答 2.1 那个问题:树太大,搜不到底,怎么办?

第三章我们转向国际象棋——一个性质截然不同的对手。它没有标准答案(至今未解)、棋子各不相同(不像五子棋的子都一样)。你会看到:前两章的搜索框架大多能原样迁移过去,但要补上一些国象特有的东西(合法走子的复杂规则、静态搜索、NNUE),还会见到一个老朋友——把世界最强的开源引擎 Stockfish 直接当工具用。我们去 3.1 未解游戏带来的范式转变