所以我相信每个人都听说过伯克利吃豆人人工智能挑战赛。不久前,我创建了一个 2D 平台游戏(不滚动),并认为从这个项目中获得一些灵感但为我的游戏创建一个 AI(而不是 PacMan)会很酷。话虽如此,我发现自己非常卡住。我查看了 PacMan 的几个 GitHub 解决方案以及大量关于在 Python 中实现 MDP / 强化学习的文章。我很难将它们与我的游戏联系起来。
在我的游戏中,我有 10 个关卡。每个关卡都有水果,一旦agent抓到所有水果,完成关卡,下一个关卡开始。这是一个示例阶段:
正如你在这张照片中看到的,我的经纪人是小松鼠,他必须抓住所有的樱桃。在地面上还有他无法行走的尖刺(或者你会失去生命)。您可以通过跳跃来避免尖峰。因此,从技术上讲,跳跃将代理向左或向右移动 2 个空间(取决于他面对的方式)。除此之外,您可以在梯子上左右移动。你不能跳超过 1 格,所以你看到顶部的“2+ 间隔”,你必须爬下梯子四处走动。此外,上图中没有显示,只有在您必须躲避的地板上左右移动的敌人(您可以跳过它们,或者只是避开它们)。它们在网格上进行跟踪,我将在下面讨论。以上就是关于游戏的一些内容,如果您需要更多说明,请随时询问,我可以提供帮助,
在我的代码中,我有一个网格,其中包含地图上的所有空间以及它们是什么(平台、常规点、尖峰、奖励/水果、梯子等)。使用它,我创建了一个动作网格(下面的代码),它基本上将代理可以从每个位置移动的所有点存储在字典中。
for r in range(len(state_grid)):
for c in range(len(state_grid[r])):
if(r == 9 or r == 6 or r == 3 or r == 0):
if (move_grid[r][c] != 6):
actions.update({state_grid[r][c] : 'None'})
else:
actions.update({state_grid[r][c] : [('Down', 'Up')]})
elif move_grid[r][c] == 4 or move_grid[r][c] == 0 or move_grid[r][c] == 2 or move_grid[r][c] == 3 or move_grid[r][c] == 5:
actions.update({state_grid[r][c] : 'None'})
elif move_grid[r][c] == 6:
if move_grid[r+1][c] == 4 or move_grid[r+1][c] == 2 or move_grid[r+1][c] == 3 or move_grid[r+1][c] == 5:
if c > 0 and c < 18:
actions.update({state_grid[r][c] : [('Left', 'Right', 'Up', 'Jump Left', 'Jump Right')]})
elif c == 0:
actions.update({state_grid[r][c] : [('Right', 'Up', 'Jump Right')]})
elif c == 18:
actions.update({state_grid[r][c] : [('Left', 'Up', 'Jump Left')]})
elif move_grid[r+1][c] == 6:
actions.update({state_grid[r][c] : [('Down', 'Up')]})
elif move_grid[r][c] == 1 or move_grid[r][c] == 8 or move_grid[r][c] == 9 or move_grid[r][c] == 10:
if c > 0 and c < 18:
if move_grid[r+1][c] == 6:
actions.update({state_grid[r][c] : [('Down', 'Left', 'Right', 'Jump Left', 'Jump Right')]})
else:
actions.update({state_grid[r][c] : [('Left', 'Right', 'Jump Left', 'Jump Right')]})
elif c == 0:
if move_grid[r+1][c] == 6:
actions.update({state_grid[r][c] : [('Down', 'Right', 'Jump Right')]})
else:
actions.update({state_grid[r][c] : [('Right', 'Jump Right')]})
elif c == 18:
if move_grid[r+1][c] == 6:
actions.update({state_grid[r][c] : [('Down', 'Left', 'Jump Left')]})
else:
actions.update({state_grid[r][c] : [('Left', 'Jump Left')]})
elif move_grid[r][c] == 7:
actions.update({state_grid[r][c] : 'Spike'})
else:
actions.update({state_grid[r][c] : 'WTF'})
在这一点上,我有点停留在如何/需要发送到 MDP 上。我正在使用Berkeley MDP,但我对如何开始参与和实施它感到非常困惑。我有一堆数据点和东西在哪里,只是不确定如何真正让球滚动。
我有一个布尔网格,可以跟踪所有有害物体(尖刺和敌人),并且由于敌人每秒都在移动,因此会不断更新。
我创建了一个奖励网格,设置:
- 尖峰“-5”奖励
- 掉落地图“-5”奖励
- 水果是“5”奖励
- 其他一切都是“-0.2”奖励(因为您想优化步骤,而不是整天都在级别 1)。
在研究解决方案或实施此方法的过程中,我遇到的另一部分问题是,大多数解决方案都是汽车开到某个位置。所以他们只有一个奖励位置,而我的每个阶段有多个水果。是的,我只是超级卡住并对此感到沮丧。想尝试我自己的东西,但如果我不能这样做,我还不如只做吃豆人,因为有几种在线解决方案。感谢您的时间和帮助!
编辑:所以这是我试图做一个示例调用,让移动网格恢复,尽管据我了解(并且很明显)它会在代理执行的每一步之后动态变化,因为敌人会威胁到某些位置和所有位置。
这就是结果,你可以看到它很接近,但显然有点坚持有多个奖励的事实。我觉得我可能很接近,但我不确定。在这一点上,我有点沮丧。