<!-- title: 让程序学会取舍：国际象棋AI的搜索哲学 -->
<!-- domain: programming -->
<!-- video: https://www.youtube.com/watch?v=U4ogK0MHzUk -->

# 让程序学会取舍：国际象棋AI的搜索哲学

**导语**

如果你问程序员“哪个练手项目最能让人脱胎换骨”，老手们的答案里几乎必有一个：写一个国际象棋引擎。这不是玄学——国际象棋规则封闭、胜负判定精确、棋力可以用Elo分数量化，意味着你写下的每一行代码，效果都能被立刻验证。而Sebastian Lague的《Coding Adventure: Chess》正是这个题材里公认的标杆视频：一位独立开发者，用C#从零开始，一步步把一个只会乱走棋的“傻子”程序，调教成一个能算计十几步之后、下出漂亮杀招的对手。

这个视频最迷人的地方在于，它表面讲的是国际象棋，内核讲的是**“搜索”这个计算机科学的元问题**：当可能的未来多到算不完时，程序如何决定在哪停下、在哪剪掉、在哪押注？这套思维不止用于下棋——路径规划、排班调度、编译器优化、约束求解，底层全是同一套逻辑。视频虽发布于2021年，但至今仍被反复翻出来重看，配套的GitHub仓库也一直在迭代。今天我们就把它拆开揉碎，看看一整套“博弈搜索”的工程哲学，是如何在一个16分钟的视频里讲明白的。

## 视频背景卡片

| 项目 | 内容 |
|------|------|
| 视频标题 | Coding Adventure: Chess |
| 频道 | Sebastian Lague（前Unity技术美术，独立开发者） |
| 时长 | 约16分钟 |
| 播放量 | 数百万级（2021年发布，编程区常青内容，截至撰写时的累计数据以YouTube页面为准） |
| 核心主题 | 从零实现国际象棋引擎：走法生成、评估函数、Alpha-Beta搜索与一系列优化 |

## 核心内容拆解

### 1. 地基工程：先让程序“看得懂”棋盘

【视频内容】Sebastian没有一上来就谈“智能”，而是花了相当篇幅做最枯燥也最关键的事：用数据结构表示棋盘，并写出合法走法生成器——每个棋子能走到哪、哪些走法会让自己王被将、王车易位和吃过路兵这些特例怎么处理。他强调这类代码极易出off-by-one和特例漏洞，所以用了自动化测试来验证：随机生成大量局面，逐层枚举所有走法序列，统计到第N步共有多少条不同路径（即棋界所谓的perft测试），再与标准答案比对，分毫不差才算过关。

【延伸分析】这是全片最容易被忽略、却最值得学的工程习惯：**先验证正确性，再谈性能与智能**。走法生成是引擎的“编译器前端”，它错一个特例，上层搜索再聪明也是在错误的世界里推理。perft的思路本质上是“黄金测试集”（golden test），数据库领域校验SQL解析器、区块链领域校验状态机迁移，用的都是同一招。很多人写项目喜欢直接堆“高级功能”，结果地基错了全盘返工——这一段就是活教材。

### 2. 评估函数：给64个格子上的局面“打分”

【视频内容】搜索到底时，程序需要一个数字来回答“现在这局面到底谁好、好多少”。Sebastian采用经典的PeSTO方案：基础是子力价值（后最贵、兵最便宜），再叠加piece-square tables——每个棋子在每个格子上有不同的附加分，比如冲到底线的兵价值飙升、占中心格的马比缩在角落的马值钱。把两种分数加总，就得到一个能粗判形势的静态评估函数。

【延伸分析】PeSTO并非Sebastian原创，它出自引擎Rofchade的作者Ronald Friederich之手，2020年发布在chessprogramming wiki上，因实现简单、棋力强悍而成为业余引擎的“标配起点”。这背后有个深刻的认知转变：这些位置加分表不是设计师凭空拍脑袋，而多半是从大量高水平对局中**统计拟合**出来的经验值。换句话说，传统引擎虽不走神经网络路线，但它的评估函数里早已藏着“从数据学习”的影子——这是理解后来AlphaZero革命时，一个常被忽略的前史。

### 3. 从Minimax到Negamax：把“我赢=你输”写成一行

【视频内容】有了评估函数，接下来是搜索框架。国际象棋是零和博弈：我的好局面就是你的坏局面。Minimax算法据此展开——轮到我时选分数最高的分支，轮到对手时假设他选对我最不利的分支，逐层交替，形成一棵博弈树。Sebastian随后展示了工程师们惯用的简化：由于双方分数互为相反数，可以把“最大化/最小化”两层统一成一个始终求最大值的函数，即Negamax，代码量近乎减半。

【延伸分析】这里藏着整个AI史上最重要的假设之一：**对手理性假设**。Minimax默认“对手会走出对你最狠的那一步”，这让它下得极其稳健，但也偏保守——人类棋手有时会故意下“不合理”的棋引诱对手犯错，Minimax框架天然不吃这套。另外Negamax的价值值得单独强调：它不是炫技，而是“利用问题的对称结构压缩代码”的典范。你在任何领域建模时，如果发现两种case互为镜像，几乎总存在类似Negamax这样的统一写法。

### 4. Alpha-Beta剪枝：不是算得更快，而是少算废话

【视频内容】博弈树的国际象棋分支因子约35，算五层就要枚举五千多万个局面，暴力穷举立刻爆炸。Alpha-Beta剪枝是救星：其直觉是“如果某个分支已经确认比已知的更差选择还差，就不用再往下看了”——就好比你已经找到一份月薪两万的工作，再去面试月薪八千的岗位纯属浪费时间。Sebastian演示了剪枝前后的搜索量对比，效果立竿见影。

【延伸分析】理论上，走法顺序最理想时，Alpha-Beta能把搜索量从O(b^d)压到约O(b^(d/2))——指数上减半，等效于**同样时间多看一倍的深度**，这是质的飞跃。但它有个苛刻前提：越早遇到好走法，剪得越狠。于是“走法排序”成了引擎的第二战场——先试吃子走法（尤其是吃白给子的）、再试被历史证明有效的走法，剪枝效率天差地别。这里有个极普适的元认知：**很多“加速”的本质不是优化计算本身，而是改变尝试顺序**。数据库索引、缓存预取、甚至你早上先做最难的事，都是同一原理。

### 5. 迭代加深与置换表：给搜索装上“记忆”

【视频内容】两个看似不相关的技巧配合起来威力巨大。迭代加深（iterative deepening）是先搜1层、再搜2层、逐层加深，而不是直接硬钻某一层——每层结果可用于指导下一层的走法排序；置换表（transposition table）则解决“同一局面经不同走法顺序反复出现”的浪费：用Zobrist哈希给每个局面生成指纹，查表发现算过就直接复用。

【延伸分析】Zobrist哈希本身是个漂亮的技巧：为每个“棋子×格子”组合预生成随机64位数，局面哈希就是所有占用项的异或值；走一步棋时只需异或进出局的几个项，增量更新几乎零成本。而“迭代加深+用上一层最佳走法排序剪枝”的组合，是典型的**自举（bootstrapping）结构**——浅层的便宜结果成为深层搜索的先验。这个模式在强化学习的课程学习、编译器的多级优化里反复出现：先花小钱得到粗答案，再花大钱精化它，而不是一上来就All in。

### 6. 静态搜索：治好“水平线效应”这个顽疾

【视频内容】哪怕搜索得再深，总要在某一层“截止”。危险在于：如果截止时正处在一串吃子交换的中途，评估函数会严重误判——程序以为自己白赚一个兵，其实下一秒就要被反吃。Sebastian给搜索加装了静态搜索（quiescence search）：到达深度上限后不立即评估，而是继续只搜索吃子走法，直到局面“安静”下来（没有悬而未决的交换）才打分。

【延伸分析】这就是引擎圈说的“水平线效应”（horizon effect）：任何固定深度的搜索，都可能在风暴前夕停船。Quiescence search是工程上非常漂亮的“分层截止”思想：**主搜索管战略深度，末梢搜索管战术清算**，两层职责分明。类似结构无处不在——物理仿真里大步长积分叠加碰撞子步、金融风控里宏观模型叠加压力测试末梢。顺带一提，吃子走法的排序用了MVV-LVA（Most Valuable Victim, Least Valuable Attacker，先吃最贵的子、用最便宜的子去吃）这类手工启发式，再次呼应了上一条：排序质量决定剪枝生死。

### 7. 从“能跑”到“能打”：优化是没有尽头的长尾

【视频内容】视频的后半段是一连串渐进提升：加入killer moves与历史启发进一步优化排序、不断做速度基准测试、让引擎和自己旧版本对打验证棋力增长。Sebastian还把完整代码开源在GitHub仓库Chess-Coding-Adventure上，并在后来用位棋盘（bitboard）重写了V2版本。片尾他与自己的AI对弈、看着它走出配合精妙的杀招，那种“亲手造出一个会算计的东西”的满足感，是整个系列的灵魂。

【延伸分析】开源仓库的迭代史本身就是第二重学习材料：V1到V2从数组棋盘换到bitboard，恰好展示了同一算法在“数据结构升级”后的性能跃迁——算法骨架不变，换表示方式，每秒可搜索的局面数提升数倍。这印证了一个引擎圈的朴素真理：**棋类引擎的竞争，一大半是表示层和速度的竞争**，因为搜索深度每+1，棋力就肉眼可见地上涨。另外值得知道的是，这条技术树的天花板是Stockfish与TCEC冠军赛，业余引擎和它之间仍有鸿沟——但鸿沟不妨碍你在爬坡路上收获全部方法论。

## 知识结构图

```mermaid
graph TD
    A[国际象棋引擎 = 走法生成 + 搜索 + 评估] --> B[地基：棋盘表示与走法生成]
    A --> C[搜索：博弈树上的取舍]
    A --> D[评估：给局面打分]

    B --> B1[合法走法生成<br/>易位/吃过路兵等特例]
    B --> B2[perft 黄金测试<br/>先正确、再聪明]

    D --> D1[子力价值]
    D --> D2[piece-square tables<br/>PeSTO 位置加分表]

    C --> C1[Negamax<br/>零和对称性统一代码]
    C1 --> C2[Alpha-Beta 剪枝<br/>少算废话 = 深度翻倍]
    C2 --> C3[走法排序<br/>MVV-LVA / killer / history]
    C1 --> C4[迭代加深<br/>浅层结果引导深层]
    C4 --> C5[置换表<br/>Zobrist 哈希记忆]
    C1 --> C6[静态搜索<br/>治水平线效应]

    B2 --> E[可量化验证<br/>与旧版对打 / Elo]
    D2 --> E
    C6 --> E
```

## 实战启示

**如果你想动手写一个**，别直接挑战国际象棋。合理的阶梯是：井字棋（一个下午搞定完整Minimax，直观感受博弈树）→ 五子棋（引入Alpha-Beta和简单的评估函数）→ 再考虑国际象棋或中国象棋。起步评估函数直接抄PeSTO表不丢人，chessprogramming wiki上有完整数值；每改一处就用perft验证走法生成，这条纪律能帮你省下几十个小时的诡异bug排查。

**即使你永远不写引擎**，这个视频的方法论也能平移：第一，“先验证正确性再谈优化”——黄金测试集先行；第二，“加速的本质是排序”——无论你是优化代码、优化检索还是优化自己的日程，先问“我在按什么顺序尝试，能不能把大概率对的放前面”；第三，“分层截止”——任何算不完的问题，都可以拆成主干搜索加末梢清算两层，各自用不同的精度预算。

**对AI时代程序员**，这视频还有一层特殊价值：理解了传统搜索，你才真正理解AlphaZero的革命性在哪——它不是把搜索做得更好，而是用神经网络替换了手工评估函数，再用自我对弈替换了人类统计的位置表。新旧两条技术路线在同一个问题上交汇，看清这条线，你对“学习 vs 推理”的理解会比只会调API的人深一个量级。在AI生成代码越来越廉价的今天，**会设计“如何算、在哪停”的搜索结构，恰恰是机器替代不了的那部分判断力**。

## 延伸学习路径

1. [SebLague/Chess-Coding-Adventure（GitHub开源仓库）](https://github.com/SebLague/Chess-Coding-Adventure) — 视频配套完整源码，V1数组棋盘与V2 bitboard对照阅读，收获翻倍
2. [PeSTO's Evaluation Function（Chess Programming Wiki）](https://www.chessprogramming.org/PeSTO%27s_Evaluation_Function) — 引擎起步标配评估函数的完整数值与出处
3. [Zobrist Hashing（Chess Programming Wiki）](https://www.chessprogramming.org/Zobrist_Hashing) — 置换表背后的增量哈希技巧详解
4. Alpha–beta pruning（Wikipedia） — 剪枝复杂度证明与最优排序下的O(b^(d/2))结论
5. Sebastian Lague的《Coding Adventure》系列其余各集（射线追踪、程序化地形、流体模拟）— 同款“从零实现+可视化”的顶级学习体验

## 一句话总结

这个视频最大的价值，是把“当未来算不完时如何取舍”这件计算机科学最本质的事，装进了一个16分钟、人人能看懂的国际象棋故事里——看完你会明白：所谓智能，很大程度上是搜索的艺术，而搜索的艺术，首先是剪掉的艺术。

## 参考来源

1. [Coding Adventure: Chess — Sebastian Lague](https://www.youtube.com/watch?v=U4ogK0MHzUk) — 本文分析的核心视频
2. [SebLague/Chess-Coding-Adventure](https://github.com/SebLague/Chess-Coding-Adventure) — 视频配套开源实现
3. [PeSTO's Evaluation Function — Chess Programming Wiki](https://www.chessprogramming.org/PeSTO%27s_Evaluation_Function) — 评估函数出处（Rofchade引擎，Ronald Friederich）
4. [Zobrist Hashing — Chess Programming Wiki](https://www.chessprogramming.org/Zobrist_Hashing) — 置换表哈希技术

> 说明：视频发布于2021年，播放量、时长等数据为约数，准确数字以YouTube页面实时显示为准；本文基于视频公开内容框架与配套开源仓库写成，未逐句引用字幕。

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
