↓ 跳过正文

基于 Codex + Stockfish 的国际象棋学习练习方案

·2491 字·5 分钟
Jimmy
作者
Jimmy
Once in a lifetime, water flowing underground.

(先说一句:这篇是 Codex 帮我写的,我只出了需求和方向——所以下面写"我"的时候是我,真正动手的是它。)

我连初学者都算不上,开局名字记不全,看名局基本就是看热闹。但我是真想学,只是单纯看书和视频太容易走神;有天突发奇想:我天天在用 Codex 干活,那能不能干脆把"学棋"这件事也搬进去?让它当讲解员、让一个真引擎当裁判——它负责讲,Stockfish 负责算。

会这么想,是因为我先拿它聊过棋。它讲得确实好,会说"这步打开了 f 线"“这里的马没有根”,可问题是它讲得越顺我越不敢全信:它偶尔会一本正经地讲一个根本不存在的变化,听起来还特别有道理。我这种水平最怕的就是这种"顺着你说"的讲解,所以想给自己配一个会说"不"的裁判。想做的其实就三件事——等我下完一盘,有人能告诉我哪一步开始不对(要数字,也要另一条走法);看那些名局能点着一步步走,而不是读干巴巴的文字;以及有个不太离谱的对手陪我练,难度别高得让人绝望,最好还有棋钟。

现在这个东西大概长这样:想复盘就点着下完一局,对手是真的 Stockfish,难度可选、带棋钟,下完按一下按钮棋谱就回到对话里,它用深度 16 把每一手重新算一遍再开口。它真抓到过我自己看不出来的东西——我下过一盘(下得挺乱),第 8 手把马跳到 c4,我当时的想法是"这不挺积极",其实正好落在对方 a6 象的斜线上被白吃,评估从 +2.52 直接变成 −4.32,一步从赢棋变输棋。这种话如果只是我自己盯着棋盘,是永远发现不了的。

对弈界面截图:棋盘、棋钟、着法记录与难度设置
对弈盘:真 Stockfish 对手、棋钟、着法记录、难度与引擎开关

想看名局就用回放台,着法列表点哪跳哪,可以自动播放,每走一步评估和讲解跟着变,关键的地方直接画箭头圈出来——比读文字快得多,也更容易记住那个感觉。它给我放了两盘:1750 年 Légal 的陷阱(弃后七手成杀)和 Morphy 的歌剧院之战。

回放界面截图:Légal 陷阱的成杀局面
回放台:Légal 陷阱的成杀局面,带箭头、将军圈选与逐手讲解

它其实是怎么工作的
#

原理一句话就说完:让会讲的负责讲,让会算的负责算,剩下的都是围着这句话搭的脚手架。整条链路它给我画成了图:

原理流程图:从提问到 Codex 调用工具、棋谱与界面、再回到对话
原理流程图:你提问 → Codex 理解并调用工具 → 棋谱/界面/引擎 → 回到你

拆开看是四层在配合。最上面是你和 Codex 的对话,你问人话,它听懂意图、决定该调哪个工具,最后把结果讲成人话——它不做算术,不猜评估,也不靠记忆背棋谱。中间那层是一堆明确的动作:入库一盘棋、读出记录、渲染棋盘、开一局、测难度,这些都被做成了能直接被调用的工具,所以不用每次敲命令。再往下是数据,这里有个我觉得是整个项目最关键的设计:把"引擎生成的"和"人写的"彻底分开——games/ 里是引擎算出来的局面、评估、最佳线,随时可以重算覆盖;notes/ 里是讲解和箭头,重算时一个字都不会丢,因为合并是按「第几着 + 走法」对上的。有这条分界,才能放心地换深度、换引擎重算,而不用担心把之前想明白的东西弄没了。最底下才是引擎,真 Stockfish 在算,顺便还当了裁判:Codex 讲得对不对,拿数字一对就知道。

真正卡住的地方,以及它判断错的三次
#

说实话,大部分功能都挺顺:渲染棋盘、存棋谱、钟表、难度,都是常规活。真正卡了好几天的是把真引擎塞进界面——不是因为这件事复杂,是因为 Codex 在同一个问题上判断错了三次,而且每次都很自信。

第一次它直接下结论说"1.5MB 的引擎塞不进 1MB 的限制里",后来一试,压缩完 320KB、编码后 428KB,能塞,连试都没试就先否了。第二次它拿了个现成的第三方构建,结果一声不吭:读源码才发现,那个胶水开头会把外部传进去的东西丢掉,接着又去按相对路径取一个 .wasm 文件,而界面所在的沙箱出于安全根本不许联网取文件——取不到,还不报错,看起来就是"引擎没反应"。所以只好自己编译:用 Emscripten 加一个"把 wasm 直接内嵌进同一个文件"的选项,产物就一个 JS 文件,运行时不取任何东西,那两个坑自然不存在了。

第三次最尴尬。编译完它还是不吭声,Codex 都已经准备重写整套构建流程了,幸好先做了个对照实验——换到 Node 里用真实时间跑,它立刻说话了。真正的毛病是它没等引擎就绪就发指令;更隐蔽的是下面这层:它的测试工具在骗它。它一直用无头浏览器加虚拟时间做验证,而虚拟时间会卡住异步初始化——它量的根本不是引擎,是它自己的测试环境。这几次能纠正过来,多半是因为我一直在旁边推着它做小实验:它说"塞不进来"我说试一下,它说"引擎坏了"我问"会不会你根本没唤醒它",它判断不出来的时候我们就换个裁判重新量。最后跑起来的写法其实特别朴素:引擎按字节内嵌,不做文本转换(那会把文件弄坏);启动后**等它自己说一声"我准备好了"**再开始用;二十秒没准备好就自动退回自带的轻量对手,保证棋盘永远能下、不会白屏。

我做完之后想明白的三件事
#

把生成物和人写的东西分开,这是整个项目里让我最安心的设计:引擎的数字随时可以变,我写下的理解不能丢。让每个界面都能自证,Codex 写了个很小的检查——渲染完之后在浏览器里数一遍棋子、跟局面的 FEN 对一对,再看看有没有报错,它抓到过好几个盯着代码看半天也发现不了的 bug。还有一条是这次最值钱的:判断不出来的时候,换一个裁判,而不是加大力气。它那三次误判全是靠"做个小实验、拿一个独立证据"纠正的,尤其是当只有 AI 在告诉你"这样不行"的时候,更该怀疑测量方式本身——毕竟它会很自信地说错话,这一点我在让它讲棋的时候早就领教过了。

最后说句实话:我这样的水平,赢棋本来就谈不上,这个工具也不是为了让我赢。它的作用是我终于能看懂一盘棋里到底发生了什么——哪一步开始不对、为什么不对、本来能怎么走。如果你也想要一个(哪怕你跟我一样连初学者都不算),可以让 Codex 从零搭:把目标说清楚、要求每一步都给一个能验证的标准、然后别信它的话,要证据。

相关文章

文库本生成方案

··3002 字·6 分钟
从选书、文本整理到排版、转曲、送印的完整文库本生产流程

文库本的理念

·2939 字·6 分钟
从岩波文库的发刊词说起:文库本是什么,为什么中国一直缺一种“口袋里的教养”,以及我为什么决定自己做一本。