|
1 | | -# write-a-chinesechess-program |
2 | | -中国象棋程序学习笔记(JavaScript版) |
| 1 | +# 第 8 章 — 进一步优化(最终版) |
| 2 | + |
| 3 | +本章目标:接入**开局库**,加入**渴望搜索(Aspiration Window)**等高级优化,完成完整的中国象棋 AI 程序。 |
| 4 | + |
| 5 | +## 本章变更 |
| 6 | + |
| 7 | +| 文件 | 变更说明 | |
| 8 | +|------|----------| |
| 9 | +| `book.js` | 开局库数据(约 300KB,来自 xqbase.com,GPL 协议) | |
| 10 | +| `search.js` | 接入开局库、渴望搜索窗口优化 | |
| 11 | +| `position.js` | 新增 `bookMove()` 方法查询开局库 | |
| 12 | +| `index.html` | 界面完善,支持难度选择 | |
| 13 | + |
| 14 | +## 开局库(Opening Book) |
| 15 | + |
| 16 | +象棋开局变化繁多,AI 在开局阶段计算量极大且容易出错。开局库收录了大量经过验证的标准开局走法,AI 优先从库中查找走法: |
| 17 | + |
| 18 | +```javascript |
| 19 | +// search.js 中优先查询开局库 |
| 20 | +this.mvResult = this.pos.bookMove(); |
| 21 | +if (this.mvResult > 0) { |
| 22 | + // 验证开局库走法不会导致长将或和棋 |
| 23 | + if (!checkRepeatOrMate()) return this.mvResult; |
| 24 | +} |
| 25 | +// 开局库未命中,回退到 Alpha-Beta 搜索 |
| 26 | +``` |
| 27 | + |
| 28 | +开局库数据来自 [xqbase.com](http://www.xqbase.com),包含数千个标准开局变化,覆盖顺炮、当头炮、飞相等主流开局。 |
| 29 | + |
| 30 | +## 渴望搜索(Aspiration Window) |
| 31 | + |
| 32 | +在迭代加深中,利用上一层搜索的结果缩小 Alpha-Beta 的搜索窗口: |
| 33 | + |
| 34 | +```javascript |
| 35 | +// 用上次结果 ±ASPIRATION_WINDOW 作为初始窗口 |
| 36 | +var vlAlpha = vl - ASPIRATION_WINDOW; |
| 37 | +var vlBeta = vl + ASPIRATION_WINDOW; |
| 38 | +vl = this.searchFull(vlAlpha, vlBeta, i); |
| 39 | + |
| 40 | +// 若搜索失败(窗口太窄),用全窗口重搜 |
| 41 | +if (vl <= vlAlpha || vl >= vlBeta) { |
| 42 | + vl = this.searchFull(-MATE_VALUE, MATE_VALUE, i); |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +窗口缩小后,大部分情况下可以产生更多 Beta 截断,节省约 10~15% 的搜索时间。 |
| 47 | + |
| 48 | +## 完整 AI 流程总结 |
| 49 | + |
| 50 | +``` |
| 51 | +searchMain() |
| 52 | + ├── 1. 查询开局库 → bookMove() |
| 53 | + │ ↓ 命中则直接返回 |
| 54 | + ├── 2. 迭代加深(渴望窗口) |
| 55 | + │ for depth = 1 → maxDepth: |
| 56 | + │ searchFull(vlAlpha, vlBeta, depth) |
| 57 | + │ ├── probeHash() ← 查置换表 |
| 58 | + │ ├── Null Move Pruning ← 空步裁剪 |
| 59 | + │ ├── MoveSort() ← 走法排序(置换表→杀手→历史) |
| 60 | + │ ├── makeMove() / undoMakeMove() |
| 61 | + │ ├── searchQuiesc() ← 水平线 → 静态搜索 |
| 62 | + │ └── recordHash() ← 存置换表 |
| 63 | + └── 3. 返回最佳走法 |
| 64 | +``` |
| 65 | + |
| 66 | +## 最终版技术栈一览 |
| 67 | + |
| 68 | +| 技术 | 章节 | 作用 | |
| 69 | +|------|------|------| |
| 70 | +| 虚拟棋盘 + 位操作 | 1 | 快速棋盘表示 | |
| 71 | +| 走法校验 + 生成 | 2 | 合法走法枚举 | |
| 72 | +| Minimax | 4 | 博弈树搜索基础 | |
| 73 | +| Alpha-Beta 剪枝 | 5 | 搜索效率翻倍 | |
| 74 | +| 迭代加深 | 5 | 时间控制 | |
| 75 | +| 历史启发 | 5 | 走法排序优化 | |
| 76 | +| 静态搜索 | 6 | 消除水平线效应 | |
| 77 | +| 重复局面检测 | 6 | 防止长将循环 | |
| 78 | +| 空步裁剪 | 6 | 减少搜索节点 | |
| 79 | +| Zobrist 哈希 | 7 | 局面唯一标识 | |
| 80 | +| 置换表 | 7 | 缓存搜索结果 | |
| 81 | +| 杀手走法启发 | 7 | 提升剪枝率 | |
| 82 | +| 开局库 | 8 | 开局阶段直接查表 | |
| 83 | +| 渴望搜索窗口 | 8 | 迭代加深优化 | |
| 84 | + |
| 85 | +## 运行效果 |
| 86 | +- ✅ 完整可用的象棋 AI 程序 |
| 87 | +- ✅ 开局阶段使用标准开局库 |
| 88 | +- ✅ 搜索深度达 6~8 层(视硬件而定) |
| 89 | +- ✅ 具备一定水平,可与普通棋手对弈 |
| 90 | + |
| 91 | +## 在线体验 |
| 92 | +🎮 [点击这里试玩](https://royhoo.github.io/write-a-chinesechess-program/) |
| 93 | + |
| 94 | +--- |
| 95 | +[← 第 7 章:置换表](http://www.cnblogs.com/royhoo/p/6425858.html) |
0 commit comments