Skip to content
← 返回项目

概念 · 导师经历

学习者会做什么

一条每节课都以“做出一样东西”收尾的学习路径,外加一节可以直接运行的课:一个井字棋程序,学会分辨哪些走法根本不用看。

计划中 · 本页为概念演示

在下方运行 ↓

这是一个概念演示,不是真实课程的记录。页面不涉及任何学员、课程或机构。学习路径、课程内容、代码以及演示里的每一个棋局,都是为本页从零写的。

想法

在辅导和教学里,真正让人记住的很少是讲解本身,而是学习者亲手做出来、跑通了的那个小东西。到了那一步,概念才不再只是文字。

真实课程的笔记属于参与其中的人,不适合放到公开页面上。所以这一页把这种做法从零重写了一遍:一条简短的学习路径,写明每节课讲什么、学习者会做出什么,再加一节可以在浏览器里直接运行的课。

学习路径

每节课只讲一个概念,做一样小东西,再用一个检验确认它能用。下面这条示例路径讲的是博弈搜索,是为本页写的。

  1. 第 1 节:把游戏看成一棵树

    讲什么
    局面、走法和轮次,以及为什么每一盘井字棋都是同一棵树上的一条路径。
    做出什么
    一个列出所有合法走法的函数,以及一个统计所有可能对局的计数器。
    怎么检验
    数出来应该正好是 255,168 盘。
  2. 第 2 节:极小化极大(minimax)

    讲什么
    给结束的对局打分,再把最好的分数沿着树往上传:X 取最大,O 取最小。
    做出什么
    一个下井字棋永远不会输的程序。
    怎么检验
    从空棋盘开始让它自己跟自己下,结果永远是平局。
  3. 第 3 节:alpha-beta 剪枝

    讲什么
    alpha 和 beta 两个界限,让搜索跳过那些不可能改变结果的分支。
    做出什么
    同一个程序,加上一个记录访问了多少局面的计数器。
    怎么检验
    它得出的结果和 minimax 一样,访问的局面却少得多。
    在下方运行 ↓
  4. 第 4 节:走法排序

    讲什么
    为什么先试强的走法,剪枝就能剪得更多。
    做出什么
    一种先中心、再四角、最后四边的搜索顺序。
    怎么检验
    对比改顺序前后的计数,结果保持不变。
  5. 第 5 节:当树大到搜不完

    讲什么
    深度限制和局面评分规则,用在四子棋这类搜不到终局的游戏上。
    做出什么
    一个搜到固定深度就停下、用一条简单规则给局面打分的程序。
    怎么检验
    让它和随机落子的对手下,统计胜负。
  6. 第 6 节:讲给别人听

    讲什么
    用平实的话写清楚自己做了什么,并为容易出错的部分写测试。
    做出什么
    一份简短的 README,以及几个检查胜负判断的测试。
    怎么检验
    一个没接触过的人能自己跑起来,也看得懂。

运行这节课:先 minimax,再 alpha-beta

概念演示,并非真实系统。棋局都是虚构的,没有任何内容来自真实的课程或学员。

选一个起始局面,或者自己走几步,然后比较两种搜索。双方都走最佳时,两者算出的结局永远一致,但 alpha-beta 访问的局面更少。下面逐行列出了它在哪里省得最多。

  1. 01

    Minimax

    把每一步都试到终局。结束的对局按结果打分:X 赢记 +1,O 赢记 −1,平局记 0。X 取最高分,O 取最低分,分数沿着树一层层往上传。

  2. 02

    Alpha-beta

    往下搜索时带上两个数。alpha 是 X 已经稳拿的最好分数,beta 是 O 已经稳拿的最好分数。一旦 alpha 追上 beta,这个分支里剩下的走法都改变不了结果,搜索就在这里停下。

  3. 03

    顺序

    先试强的走法,剪枝就剪得最多。切换搜索顺序,看看 alpha-beta 的计数怎么变,而结局保持不变。

合成棋局 · 从零编写 · 在你的浏览器里运行

轮到 O

选一个空格落下一步。方向键在格子之间移动,回车键或空格键落子。

最佳走法

起始局面

X 开局下在中心。轮到 O,有八个格子可选。

搜索顺序

按 1 到 9 的顺序,从左到右、从上到下。

从当前局面出发访问的局面数

Minimax
55,505
Alpha-beta
2,316
少看了
96%
剪掉的分支
1,014

最佳走法左上。双方都走最佳时,结果是平局。

逐步来看

每一行是当前局面下的一种走法,按搜索顺序排列,并注明双方都走最佳时的结局。上面的条是 minimax,下面的条是 alpha-beta,用的是同一个比例尺。

  1. 左上平局

    Minimax6,812
    Alpha-beta703

    目前最好的一步

  2. 上中X 胜

    Minimax7,064
    Alpha-beta166

    不可能比左上更好,alpha-beta 一确认就停下了。

  3. 右上平局

    Minimax6,812
    Alpha-beta254

    不可能比左上更好,alpha-beta 一确认就停下了。

  4. 左中X 胜

    Minimax7,064
    Alpha-beta106

    不可能比左上更好,alpha-beta 一确认就停下了。

  5. 右中X 胜

    Minimax7,064
    Alpha-beta174

    不可能比左上更好,alpha-beta 一确认就停下了。

  6. 左下平局

    Minimax6,812
    Alpha-beta282

    不可能比左上更好,alpha-beta 一确认就停下了。

  7. 下中X 胜

    Minimax7,064
    Alpha-beta311

    不可能比左上更好,alpha-beta 一确认就停下了。

  8. 右下平局

    Minimax6,812
    Alpha-beta319

    不可能比左上更好,alpha-beta 一确认就停下了。

轮到 O。最佳走法:左上,双方都走最佳时结果是平局。minimax 访问了 55,505 个局面,alpha-beta 访问了 2,316 个,少了 96%。

代码

function minimax(board, player, order, stats) {  stats.nodes += 1;  const score = finalScore(board);  if (score !== null) return score;  let best = player === "X" ? -Infinity : Infinity;  for (const cell of order) {    if (board[cell]) continue;    board[cell] = player;    const value = minimax(board, other(player), order, stats);    board[cell] = null;    best = player === "X" ? Math.max(best, value) : Math.min(best, value);  }  return best;}

标记的行是 alpha-beta 与 minimax 不同的地方。

怎么做的

角色
导师兼作者
导师经历
2024 – 2025
数据
合成棋局
运行
在浏览器里
  • JavaScript
  • React
  • Next.js
  • Tailwind CSS

搜索引擎是纯 JavaScript 写的,不依赖任何库。它在你的浏览器里运行,不保存也不发送任何数据。

两个搜索函数就是代码面板里的那两个。唯一多出来的是一个计数器,每访问一个局面就加一,页面上的数字都来自它。页面从同一个局面出发,逐个走法分别运行两种搜索,所以每一行都能显示那一步花了多少。

棋盘是九个原生按钮。方向键可以在格子之间移动,每次变化后屏幕阅读器会读出结果。页面上没有自动播放的动画,开启“减少动态效果”后用起来也完全一样。

我的角色

我做导师,也教课。这张卡片会用来整理这些经历里的概念和小项目。本页的所有内容,从学习路径到搜索代码,都是我自己写的。

每节课上,我会尽量找到那个能打通下一步的概念,再帮学习者做出一个足够小的东西,在下课前完成并检验。

接下来

这一页目前还只是计划。完整的学习路径会一节一节地写出来,上面的每个例子都会从零重写,或者使用合成数据。真实课程里的内容,以及参与者的任何信息,都不会公开。

概念页。课程和其中的每个棋局都是合成的,为本页从零编写。

返回项目