解决 Uno 时遇到的问题

几个月前开始尝试为乌诺纸牌游戏)编写类似求解器的程序。原因有三:一是儿子当时很喜欢这游戏,想通过学会玩好来给他们留下印象;二是之前在编写纸牌游戏 AI 方面有困难,这次做更认真的尝试;三是这是练习模块化的好方式,开始写游戏逻辑时不知道儿子玩的所有规则。

乌诺是纸牌剔除游戏

游戏开始时玩家每人手持 7 张牌,一张起始牌面朝上在桌上,玩家轮流从自己手中向桌上的牌出牌,只要手中有匹配牌即可,否则要抽一张新牌,先清空手牌的玩家获胜,还有一些特殊牌有改变顺序等效果。

乌诺是糟糕的完全信息游戏

通常乌诺用隐藏牌玩,儿子 4 岁用公开牌,所以程序将其视为完全信息游戏,虽有完美信息但抽牌结果不确定,这虽让编写 AI 容易但导致求解器失败,因为 AI 擅长在公开牌时阻止对手获胜,会故意引入混乱导致很多平局,这使评估 AI 更耗时。

最简单最笨的 AI 获胜

第一个基线 AI 枚举所有可能动作,在预算时间内模拟每个动作结果,最后选胜率最高的动作,乌诺分支因子低,基线 AI 常重复走相同路径,通过均匀分配模拟次数等方法改进但未节省时间,反而基线 AI 能在预算内运行更多模拟,更强。读了蒙特卡洛树搜索(MCTS)基础知识后发现其记账逻辑成本高,不如基线 AI。

非确定性动作影响树搜索

测试基于 MCTS 的 AI 时发现抽牌是非确定性动作很重要,游戏树不能简单将抽牌作为边,也不宜按结果参数化边,最后给抽牌动作蒙上一层面纱,让 MCTS 不能超出,理解用于解决此情况的技术可用于处理隐藏信息,抽牌的非确定性可视为游戏环境用确定性隐藏牌玩。

下一步:隐藏信息和性能

对乌诺了解了一些但还不够,若想进一步可能需要让 AI 处理不完全信息即玩隐藏牌,已开始浏览 Daniel Whitehouse 的博士论文,可能某天会处理,现在知道规则且能编写模块化引擎,可花时间重写以提高运行速度。

阅读 10
0 条评论