这是着名游戏2048的简化版本。给定4x4网格,其中一些值选自{0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}
。值0
表示网格中的位置未被占用。如果没有新的图块被引入网格,那么从给定的游戏设置中任何(可能的长度为零)移动序列(向上,向下,向左,向右)可以产生的最大图块是多少?
例如,给定
2 64 4 32
8 16 8 4
4 32 4 0
2 2 0 0
答案是128:
问题可能可以通过那些AI算法(例如minmax)解决,但是,我想这绝对是一种矫枉过正。有没有更简单的算法来解决这个问题?
答案 0 :(得分:1)
在这种情况下,您可以执行的最简单的算法是基于图形的搜索。图的每个节点表示网格的当前状态i。每个节点都有4个子节点,代表状态i + 1,因此每个边代表一个移动(向上,向下,向左,向右)。
因此假设您从给定状态开始,节点1.然后您必须应用4个移动并模拟它们。也就是说,节点1有4个子节点,节点2(左移),节点3(右移)等等。对于每个动作,您都可以模拟该动作的作用。在每个节点中存储当前状态和最大图块的值。
只要没有可能的动作,算法就会结束。因此,寻找所有叶节点的最大值就可以了。
伪代码类似于:
input: current state s_current
output: max tile value M
-----
queue <- s_current
while !queue.empty do
s = queue.pop
for each m in move // move contains the 4 moves.
s' = simulate(s,m)
if s' != 0 //so the move was possible
queue.add(s')
else
mark s' as leaf node
M = max_tile(s')
if M > M_current update M
免责声明:我没有检查pseucode中的错误,可能缺少一些小步骤。
请注意,根据队列数据结构,您实际上是实现了Breath First Search或Depth First Searh,它们是您可以实现的最简单的图形算法。实际上,我在这里看到的最困难的部分是simulate()
函数,它实际上是实现游戏逻辑的函数。我想有更好的算法,但这是最简单的事情(实际上并没有那么糟糕:))