有人用SQL做3D渲染,有人拿它跑细胞自动机,这些都已经不太让人意外了。但有一天我突然冒出一个更经典的想法:能不能用纯粹的关系代数,在分析型数据库里写出一个真正能下棋的国际象棋引擎?
答案是可以。整件事——生成走法、验证合法性、局面打分,再到把最优策略一层层“冒”上来——全部能塞进一个 WITH RECURSIVE 查询里。一个巨大的递归 CTE 就扛起了整个引擎。
![]()
递归 CTE 其实完全有办法处理极小化极大树搜索,就像编程语言里递归实现 minimax 一样。把棋盘状态自顶向下展开,再自底向上聚合,DuckDB 就能原生跑完一套基于 minimax 的走法搜索。展开阶段从根节点出发,通过走法生成不断生出深度更深的状态;回传阶段则利用 CASE 在轮到白方时取子节点最大分,轮到黑方时取最小分,逐层上卷,最终在深度为零的根节点选出得分。
简化后的结构看起来清晰,实际生产查询把所有走法生成和各类检查展开后,差不多有 570 行 SQL。这个查询真的能下出合法且合理的棋,完完全全在一个数据库事务里运转。
但这里藏着一个巨大的坑。递归 CTE 本质上是广度优先搜索,每一层深度里所有的棋盘状态都得同时留在内存里。因为这种跨行全局执行的方式,想在查询中途引入经典的 Alpha-Beta 剪枝阈值几乎不可能。一旦尝试搜索超过 3 层(一个半回合),组合爆炸立刻接管,查询会瞬间吞光所有内存。
为了不让引擎还没下几步就因为内存溢出崩掉,我不得不从“一个大查询打天下”的思路里退出来,转向一种叫“批量主变例搜索”的混合架构。相关的细节,才刚刚开始。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.