ABK-GOFAI:一个老派人工智能,用来玩 Abak Evolution Backgammon。
在没有神经网络帮助的情况下,为 Abak 开发人工智能(AI)被证明是一项极具挑战的任务,并且随着时间推移似乎达到了一个上限。不过,开发它的过程非常有趣,而且它至今仍在“easy”、“normal”和“advanced”级别上服役。这篇文章讲的是它如何工作,以及它是如何被做出来的。
阶段 1,GOFAI PHP
Abak 的第一个 AI 版本是用 PHP 编写的,最终因为“out of memory”错误而被认为会拖垮系统,但它为 C++ 版本铺平了道路。对我来说,它是一个原型试验场,用来摸索到底该怎么做一个 AI。第一次我把它挂到 web 服务器上运行时(也就是我真的在和它对战),它用了漫长的 15 秒才选出一步棋。当我看到服务器自己开始走棋时,我兴奋坏了,可能还跳了一小段舞。不太确定。
阶段 2,GOFAI C
于是,这个 AI 的 C/C++ 版本——第一个进入生产环境的版本、我心爱的 GOFAI 引擎——从 PHP 的灰烬中诞生了。它会在纳秒间对成千上万个局面运行 29 个分析算法,过程如下:
- 给定一个棋盘局面和一组骰子。
- 计算状态
- 获取所有可能走法。
- 分析每一种走法并给出分数。
- 选择“最佳”分数。
下面是该过程的示意图。
它由四个主要函数组成:
- Get Actions(计算合法走法):
给定一个棋盘局面和一次掷骰结果,它会计算出所有合法走法。
合法走法的数量可能从 0 到数万不等。
无论我用哪种语言来写这部分,我都采用了一种不必要的递归方式,这让代码极难调试,但它又实在太美了。它有几百行代码,却花了我几周时间写完,之后又花了几周把它翻译成 C。
- Get state(计算棋盘状态):
给定一个棋盘局面,它会计算出一个语义状态,这些状态基本都很好理解:
- Starting
- MiddleGame
- Running without Hope
- Running with Hope
- EndGame
- Entering Home
-
Analyse Movement(为棋盘局面计算分数):
这是迄今为止最庞大的算法。它会分析棋盘的各种特征,每一种都返回一个分数,然后根据之前算出的状态对它们应用权重因子,从而根据不同的游戏阶段,赋予分析中不同方面不同的重要性。
这个 AI 一开始只有 8 个算法,最后增加到了 29 个,随便举几个:
- 列高
- 被击中的风险
- 被困住的风险
- 内盘强度
- 逃脱枢纽
- 中栏棋子数
- 安全棋子
这些算法中很多一开始都非常基础,甚至压根不存在。
随着时间推移,我不断为它们增加功能并微调因子。
-
Select Action(选择“最佳”走法):
如果你只是想选出最高分,这个算法相对简单(Advanced 等级就是这么做的)。
对于 Normal 和 Easy 等级,它会在一组最佳走法中随机选择一步;这个列表的大小(或者说它对较差走法的容忍度)由难度等级决定。
由于使用 C,这个引擎快得惊人,所以我会始终把它作为主要的 get-actions 函数。
阶段 3,GOFAI C 调优
为了调试、排查问题和微调这个引擎,我不得不构建许多工具来监控它的决策过程。与神经网络不同,这里的每个决定都是可审计的,所以至少你还有这一点可依赖。
这个过程很有趣,但也慢得痛苦。我和 CPU 对战了很多次,每当我看到一个糟糕的走法,就会回到这些工具里查看哪里出了问题。有时这会把我带向修复某个算法、调优某个因子,或者干脆构建一个新的分析模型。有时——而这真的很美——它还会让我重新思考自己的 Abak Evolution 策略。
随着时间推移,我得到了一套相当扎实的 AI,但要继续把它打磨得更完美却变得越来越困难。代码行数太多,场景太多,运算规模太大,以至于在代码层面调试成了一项沉重的工作,而手工微调因子也开始不再有效。
阶段 4,绝望
但我还想要更多,因为我自己也玩 Abak,而我需要一个足够强的对手来获得乐趣。那时玩这款游戏的人类并不多(甚至在我写下这些文字的时候也是如此)。
而这种方法有很多缺点:
- 它会根据当前棋盘位置计算一个棋盘状态,并用这个状态来调整所有合法走法的分析算法因子。但某个走法本身其实可能已经改变了状态,而引擎并没有把这一点考虑进去。
- 手动微调因子需要耗费巨量时间。过程当然也挺有趣,但真的太多了。
- 鉴于可能场景的数量如此庞大,状态的计算极其困难。这个算法一直都有缺陷。
- Game Equity 不可能被精确计算,因为这个引擎对每个分析算法都有一套任意的评分系统,最终分数并不反映胜率概率,它只是作为不同棋盘局面之间的相对比较分值。你可以说它只有相对值,而不是绝对值。
阶段 5,觉醒
然后,在 2018 年的某一天,Google 用 AlphaGo 神经网络击败了 GO 冠军,整个世界都沸腾了。同时,各种出色的开源机器学习库也陆续可用,并开始使用家用 GPU 来加速训练过程。
当然,我之前对神经网络已经有一点了解,但我从未真正搭建过,而且老实说,我一直觉得那是超出我能力范围的事情。
所以我根本抵挡不住诱惑,Expert 等级后来就不再运行在 GOFAI 引擎上了,除了 get-actions 这部分。
不过,这个故事就在这里结束。
如果你一直读到了这里,我真的很惊讶。
这段文字由诚实的 Abak Evolution Team 为了 SEO 目的撰写,
也就是 Samy Garib。