我对这款游戏的人工智能的想法产生了兴趣,它不包含硬编码的智能(即没有启发式、评分功能等)。人工智能应该只“知道”游戏规则,并“弄清楚”游戏玩法。这与大多数AI(如本线程中的AI)形成对比,在这些AI中,游戏玩法基本上是由代表人类对游戏理解的评分函数控制的暴力。
AI算法
我发现了一个简单但令人惊讶的好游戏算法:为了确定给定棋盘的下一步,AI使用随机移动在内存中玩游戏,直到游戏结束。这是在跟踪最终比赛分数的同时进行的几次。然后计算每次开始移动的平均结束得分。平均结束得分最高的起始动作被选为下一个动作。
每次移动仅运行100次(即内存游戏),AI可实现2048次平铺80%的次数和4096次平铺50%的次数。使用10000次运行可获得2048个平铺100%,4096个平铺70%,8192个平铺约1%。
在行动中看到它
最佳成绩如下:
关于这个算法的一个有趣的事实是,尽管随机游戏毫无疑问非常糟糕,但选择最佳(或最不糟糕)的招式会带来非常好的游戏效果:一个典型的人工智能游戏可以达到70000点,并持续3000步,但任何给定位置的记忆中随机游戏在死亡前都会在大约40次额外的招式中平均增加340点。(您可以通过运行AI并打开调试控制台自行查看。)
这张图说明了这一点:蓝线显示了每次移动后的棋盘得分。红线显示了该位置的算法的最佳随机运行结束游戏分数。本质上,红色值是将蓝色值向上拉向它们,因为它们是算法的最佳猜测。有趣的是,在每一点上,红线都比蓝线略高一点,但蓝线仍在不断增加。
我觉得很奇怪的是,算法不需要实际预测好的游戏玩法,就可以选择产生它的动作。
后来搜索发现,这个算法可能被归类为纯蒙特卡罗树搜索算法。
实施和链接
首先,我创建了一个JavaScript版本,可以在这里看到。这个版本可以在适当的时间内运行100次。打开控制台获取更多信息。(来源)
后来,为了玩更多,我使用了@nneonneo高度优化的基础设施,并用C++实现了我的版本。这个版本允许每次移动最多100000次,如果你有耐心的话,甚至可以达到1000000次。提供建筑说明。它在控制台中运行,也有一个遥控器来播放网络版本。(来源)
后果
令人惊讶的是,增加跑步次数并不能显著改善比赛。这一策略似乎有一个限制,即4096个区块和所有较小的区块在80000点左右,非常接近8192个区块。将跑步次数从100次增加到100000次会增加达到这一分数限制(从5%增加到40%)但无法突破的几率。
在关键位置临时增加到1000000次的10000次跑步打破了这一障碍,达到129892分的最高得分和8192分的次数不到1%。
改进
在实现这个算法后,我尝试了许多改进,包括使用最小或最大分数,或最小、最大和平均值的组合。我还尝试了使用深度:我没有尝试每次移动K次,而是尝试了给定长度的每次移动列表(例如“向上、向上、向左”)的K次移动,并选择最佳得分移动列表的第一个移动。
后来我实现了一个得分树,它考虑了在给定的移动列表之后能够进行移动的条件概率。
然而,这些想法都没有比简单的第一个想法显示出任何真正的优势。我将这些想法的代码注释在C++代码中。
我确实添加了一个“深度搜索”机制,当任何一次运行意外达到下一个最高的平铺时,该机制将运行次数临时增加到1000000次。这提供了时间上的改进。
我很想知道是否有人有其他改进想法来保持人工智能的领域独立性。
2048个变体和克隆
为了好玩,我还将AI实现为书签,与游戏的控件挂钩。这使得AI可以与原始游戏及其许多变体一起工作。
这是可能的,因为AI的领域独立性。一些变体非常独特,例如六边形克隆。