我最近偶然发现了2048游戏。通过在四个方向中的任何一个方向上移动类似的平铺,可以合并它们,以生成“更大”的平铺。每次移动后,一个新的平铺显示在随机的空位置,值为2或4。当所有的方块都被填满并且没有可以合并平铺的移动,或者你创建了一个值为2048的平铺时,游戏终止。
首先,我需要遵循一个明确的战略来实现目标。所以,我想为它写一个程序。
我当前的算法:
while (!game_over) {
for each possible move:
count_no_of_merges_for_2-tiles and 4-tiles
choose the move with a large number of merges
}
我所做的是,在任何时候,我都会尝试将值为2和4的平铺合并,也就是说,我尝试尽可能少地使用2和4个平铺。如果我这样做,所有其他平铺都会自动合并,策略似乎很好。
但是,当我实际使用这个算法时,在游戏结束之前,我只得到了大约4000分。AFAIK的最高分数略高于20000分,这比我目前的分数要大得多。有比上述更好的算法吗?
算法
while(!game_over)
{
for each possible move:
evaluate next state
choose the maximum evaluation
}
评价
Evaluation =
128 (Constant)
+ (Number of Spaces x 128)
+ Sum of faces adjacent to a space { (1/face) x 4096 }
+ Sum of other faces { log(face) x 4 }
+ (Number of possible next moves x 256)
+ (Number of aligned values x 2)
评估详细信息
128 (Constant)
这是一个常数,用作基线和其他用途,如测试。
+ (Number of Spaces x 128)
更多的空间使状态更灵活,我们乘以128(这是中值),因为填充了128个面的网格是最佳的不可能状态。
+ Sum of faces adjacent to a space { (1/face) x 4096 }
这里,我们评估有可能合并的面,通过向后评估它们,平铺2的值为2048,而平铺2048的值为2。
+ Sum of other faces { log(face) x 4 }
在这里,我们仍然需要检查堆叠的值,但以一种较小的方式,这不会中断灵活性参数,因此我们得到了[4,44]中的{x的和}。
+ (Number of possible next moves x 256)
如果一个国家对可能的转变有更大的自由度,它就会更灵活。
+ (Number of aligned values x 2)
这是对在该状态内合并的可能性的简化检查,而无需进行前瞻。
注意:常数可以调整。。
我是其他人在本主题中提到的AI程序的作者。您可以查看人工智能的运行情况或读取源代码。
目前,该程序在我的笔记本电脑上的浏览器中运行javascript时,每次移动大约需要100毫秒的思考时间,获得了大约90%的胜率,因此,尽管它还不完美(还!),但它的表现相当不错。
由于游戏是一个离散的状态空间,完美的信息,基于回合的游戏,如国际象棋和跳棋,我使用了已经被证明适用于这些游戏的相同方法,即带有alpha beta修剪的极小极大搜索。由于已经有很多关于该算法的信息,我将只讨论我在静态评估函数中使用的两种主要启发式方法,它们将其他人在这里表达的许多直觉形式化。
单调性
该启发式方法试图确保平铺的值都沿着左/右和上/下方向增加或减少。仅此启发式方法就抓住了许多其他人提到的直觉,即较高价值的瓦片应该聚集在角落中。它通常会防止价值较小的瓦片成为孤立的,并保持棋盘非常有序,较小的瓦片层叠并填充到较大的瓦片中。
这是一个完全单调的网格截图。我通过运行带有eval函数集的算法来实现这一点,从而忽略其他启发式,只考虑单调性。
平滑度
仅上述启发式方法就倾向于创建相邻瓦片值降低的结构,但当然,为了合并,相邻瓦片需要具有相同的值。因此,平滑启发式算法仅测量相邻平铺之间的值差,试图将此计数最小化。
《黑客新闻》的一位评论者用图论的方式对这一想法进行了有趣的形式化。
这是一张完美平滑的网格截图。
自由平铺
最后,由于游戏板太拥挤,选项可能会很快用完,所以免费瓷砖太少会受到惩罚。
就这样!在优化这些标准的同时搜索游戏空间会产生非常好的性能。使用像这样的通用方法而不是显式编码的移动策略的一个优点是,该算法通常可以找到有趣和意外的解决方案。如果你看着它跑,它通常会做出令人惊讶但有效的动作,比如突然切换它所建的墙或角落。
编辑:
这里展示了这种方法的威力。我取消了平铺值的上限(因此它在达到2048之后保持不变),这是八次试验后的最佳结果。
是的,这是4096和2048。=)这意味着它在同一块板上三次实现了令人难以捉摸的2048瓷砖。
这不是对OP问题的直接回答,这是我迄今为止试图解决同一问题的更多东西(实验),并获得了一些结果和一些我想分享的观察结果,我很好奇我们能否从中获得一些进一步的见解。
我刚刚尝试了使用alpha beta修剪的minimax实现,搜索树深度截止值为3和5。我试图解决4x4网格的相同问题,作为edX课程ColumbiaX:CSMM101x人工智能(AI)的项目作业。
我应用了两个启发式评估函数的凸组合(尝试了不同的启发式权重),主要来自直觉和上面讨论的函数:
单调性可用的可用空间
在我的情况下,电脑玩家是完全随机的,但我仍然假设了对抗性设置,并将AI玩家代理实现为最大玩家。
我有4x4网格来玩游戏。
观察结果:
如果我给第一个启发式函数或第二个启发式函数分配了太多权重,那么AI玩家获得的分数都很低。我对启发式函数进行了许多可能的权重分配,并采用了凸组合,但很少有AI玩家能够得分2048。大多数时候,它要么停在1024或512。
我也尝试过拐角启发式,但出于某种原因,它会使结果更糟,凭直觉为什么?
此外,我尝试将搜索深度截止值从3增加到5(我不能再增加了,因为即使在修剪的情况下,搜索该空间也超过了允许的时间),并添加了一个启发式方法,它查看相邻平铺的值,如果它们可以合并,则会给出更多的点,但我仍然无法获得2048。
我认为使用Expectimax而不是minimax会更好,但我仍然希望只使用minimax来解决这个问题,并获得2048或4096等高分。我不确定我是否遗漏了什么。
以下动画显示了AI代理与计算机玩家玩游戏的最后几个步骤:
任何见解都将非常有用,提前感谢。(这是我博客文章的链接:https://sandipanweb.wordpress.com/2017/03/06/using-minimax-with-alpha-beta-pruning-and-heuristic-evaluation-to-solve-2048-game-with-computer/以及youtube视频:https://www.youtube.com/watch?v=VnVFilfZ0r4)
以下动画显示了游戏的最后几个步骤,其中AI玩家代理可以获得2048分,这一次还添加了绝对值启发式:
下图显示了玩家AI代理探索的游戏树,假设计算机是对手,只需一步:
我是一个2048控制器的作者,它的得分比本主题中提到的任何其他程序都要高。github上提供了控制器的有效实现。在单独的回购中,还有用于训练控制器状态评估功能的代码。本文描述了训练方法。
控制器使用expectimax搜索,该搜索具有通过时间差学习(强化学习技术)的变体从零开始学习的状态评估函数(没有人类2048专业知识)。状态值函数使用n元组网络,它基本上是板上观察到的模式的加权线性函数。总共涉及超过10亿重量。
表演
1次移动/秒:609104(平均100局)
10次移动/秒:589355(平均300场)
3局(约1500步/秒):511759(平均1000局)
10次移动/秒的平铺统计如下:
2048: 100%
4096: 100%
8192: 100%
16384: 97%
32768: 64%
32768,16384,8192,4096: 10%
(最后一行表示在板上同时具有给定的瓷砖)。
对于3层:
2048: 100%
4096: 100%
8192: 100%
16384: 96%
32768: 54%
32768,16384,8192,4096: 8%
然而,我从未观察到它获得65536平铺。