帮助使用Java解决D& D迷宫

时间:2011-09-24 21:17:32

标签: java algorithm solver maze

我一直在阅读已经发布在stackoverflow上的其他一些问题,而且我对搜索算法的数量有点不知所措。我不是在寻找代码和更多的页面,它超越了算法的背景,也许还有一些sudo代码。我知道有像A *这样的算法,但由于时间不足,我不知道我是否能用这个算法完成程序。迷宫是使用服务器程序生成的,并且解算器连接到服务器以便向更多玩家块发送命令。我无法访问服务器程序中的方法。我必须解决一个迷宫,它被创造成像D& D迷宫。以下是游戏的基本概述:

  经典的D& D计算机游戏由一个地牢(迷宫)组成,其中   游戏的目的是通过地牢进入,进入   在迷宫的“入口”,在“出口”离开。要做   事情更具挑战性,地牢的布局不为人知   先天和有障碍(僵尸,焦油和门)   必须通过使用对象(票价,梯子和钥匙)来克服   一路上找到了。

我注意到很多其他帖子都不用担心完成迷宫的障碍,这是一个主要的问题,以适应算法来弥补障碍?我想知道像右手规则这样的东西是否可以解决迷宫问题,如果不是,那么解算迷宫的算法会尽可能简单(因为我必须尽快完成程序)。任何其他链接都会很棒,因为我知道我必须在Objective-C中再次完成这个程序,并且我希望在发生这种情况时实现比右手规则更强大的功能。谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

对于简单的迷宫,你基本上沿着一条小路“走”,直到你到达一个十字路口。此时,您将记录所有选项。然后你选择一个(使用你喜欢的任何启发式,对于你的右手技术,你总是“向右”)。一旦你记录了这些选项,就可以将它们写入堆栈。然后你继续前进。

当你读到一个死胡同时,你要么“向后走”,要么只要弹出堆栈,选择另一个选项并从那里继续。要走回去,你只需在堆栈上记录每一步,然后开始展开堆栈,直到你到达最后一个交叉路口。

你可以继续这样做,注意怪物,比如你可以通过的东西,或者你错过了一个项目,作为“死胡同”。然后,您可以在交叉路口记录这些可通过的死角,这样,如果您回到仍在寻找出口的交叉路口,您可以检查您的库存中的“钥匙”或“剑”或您需要传递的任何东西。当你回来时,检查未探测路径的选项,以及被你可以击败的东西阻挡的路径。如果你有能够击败怪物的物品,你可以重新夺回那条路线,击败怪物并继续。

我不记得这种技术是否适用于具有周期的迷宫。它应该是,因为你应该总是能够告诉你以前是否曾经去过一个地方,在你身后留下一条“面包屑”或记录你所见过的地点。

它肯定不会告诉你最佳路径,或者最好的得分路径,只要你笨拙就会让你到达出口。

当您发现交叉点时,您也可以将地牢表示为内存中的连接图,其中图中的每个节点都是交叉点,并且每个节点之间的路径长度(步数)是转换在图中。您还可以将此图中的障碍物表示为节点。

所以如果你遇到一个吸血鬼,它将是一个在大厅尽头没有出口的节点。之后,当你得到十字架和木桩时,你会“知道”吸血鬼在哪里,并且能够将图形传回吸血鬼(当然,假设它没有移动)。

诀窍在于你正在构建这个图表并使用股票图遍历算法(其中有许多,并且它们并不那么困难)从一个节点导航到另一个节点。

但是对于遍历一个简单的迷宫,堆栈技术非常有效。

补遗:

对于简单的迷宫,单个堆栈就足够了。我不知道你的地图是如何布局的,或者你如何导航它等等。

但是你可以做的就是每次移动时,只需将移动放在堆叠上即可。然后当你想要回溯时,你开始弹出堆栈并沿着移动的相反方向前进,直到你回到交叉路口,然后从那里开始。

这只是一个树的“深度优先”搜索,你不知道它的布局。但同样重要的是,您还要以其他方式跟踪您的位置。例如,如果您将迷宫表示为大量的地板和墙块,则可以在简单列表中捕获您输入的每个地板块的坐标。

这样做的原因是,如果迷宫中有循环,你不想“向前走”到你已经走过的空间。显然你需要在回溯时这样做。但是在探索时,你需要知道自己拥有和未曾见过的东西。跟踪方式取决于地图的数据结构。

考虑这个微不足道的迷宫:

# ########
# ########
# # #    #
# # #### #
# #a    b#
# # #### #
#   #    #
##### ####
#    c   #
# ########

你可以看到你只需要在a,b和c位置推进堆栈。如果你能够在你去过的地方做标记,那么你的地图在第一个十字路口可能会是这样的:

#.########
#.########
#.# #    #
#.# #### #
#.#a    b#
#.#.#### #
#. .#    #
##### ####
#    c   #
# ########

你堆叠看起来像:

{d,d,d,d,d,d,d,l,u}

7次下降,一次离开,一次上升。

如果您无法标记地图,则可以改为跟踪坐标。这一切都取决于。

答案 1 :(得分:0)

我个人会尝试使用递归来查找路径。您可以使用if语句来处理陷阱,而不是使用return语句来告诉您路径。

  public static int recursion(int x, int y) {
    if (location == end) {
      return 0; //found the end
    }
    if (deadEnd) {
      //backtrack
    }
    if (trapName) {
      //put whatever you need to do to get around it
    }
    if (x+1 <= edge) {
      recursion(x+1,y); //Moves right
    }
  }

这或多或少是伪代码。希望它有所帮助!