帮助使用 Java 解决 D&D 迷宫问题
我一直在阅读 stackoverflow 上发布的其他一些问题,我对搜索算法的数量感到有点不知所措。我不是在寻找代码和更多涉及算法背景的页面,也许还有一些 sudo 代码。我知道有像 A* 这样的算法,但由于缺乏时间,我不知道我是否能够用这个算法完成程序。迷宫是使用服务器程序生成的,解算器连接到服务器以便向更多玩家发送命令。我无权访问服务器程序中的方法。我必须解决一个像 D&D 迷宫一样的迷宫。以下是游戏的基本概述:
经典的 D&D 电脑游戏由一个地牢(迷宫)组成,其中 游戏的目的是穿过地牢,进入 在迷宫的“入口”,在迷宫的“出口”离开。使 事情更具挑战性,地牢的布局未知 先验并且存在障碍(僵尸、焦油坑和门) 必须通过使用以下物体(票价、梯子和钥匙)来克服 一路上发现的。
我注意到许多其他帖子不必担心完成迷宫的障碍,这会是调整算法来补偿障碍的主要问题吗?我想知道像右手定则这样的东西是否可以很好地解决迷宫,如果不是,那么什么是尽可能简单的算法来解决迷宫(因为我必须尽快完成程序)。任何其他链接都会很棒,因为我知道我必须在 Objective-C 中再次完成这个程序,并且当发生这种情况时,我想实现比右手规则更强大的东西。感谢您的任何帮助。
I been reading some of the other questions that have been posted on stackoverflow and I am a little overwhelmed by the number of search algorithms there are. I'm not looking for code and more of a page that goes over background of the algorithm and maybe some sudo code. I know there are algorithms like A* but due to lack of time I don't know if I would be able to complete the program with this algorithm. The maze is generated using a server program and the solver connects to the server in order to send commands to more the player piece. I do not have access to the methods within the server program. I have to solve a maze that has been created to be like a D&D maze. Here is a basic overview of the game:
A classical D&D computer game consists of a dungeon (maze), where the
purpose of the game is to make one's way through the dungeon, entering
at the "entrance" of the maze and exiting at its "exit". To make
things more challenging, the layout of the dungeon is not known a
priori and there are obstacles (zombies, tar-pits, and doors) that
must be overcome by using objects (fares,ladders, and keys) that are
found along the way.
I have notice that many of the other post do not have to worry about obstructions to completing the maze, would this be a major problem to adapt the algorithm to compensate for the obstructions? I was wondering if something like the right hand rule would be fine to solve the maze and if not what would be a algorithm that is as simple as possible to solve the maze(Due to the fact that I have to complete the program soon). Any other links would be great as I know that I have to complete this program again in Objective-C and I would like to implement something more powerful then the right hand rule when this happens. Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于简单的迷宫来说,您基本上沿着一条路径“行走”,直到到达十字路口。那时你记录下所有的选择。然后你选择一个(使用你喜欢的任何启发式,对于你的右手技术,你总是“向右走”)。一旦您记录了选项,您就可以将其填充到堆栈中。然后你继续前进。
当你读到一个死胡同时,你要么“走回去”,或者如果可能的话,简单地弹出堆栈,选择另一个选项并从那里继续。要往回走,您只需将每次移动记录在堆栈上,然后开始展开堆栈,直到到达最后一个交叉点。
你可以简单地继续这样做,注意怪物以及诸如你可以通过的东西,或者你错过的物品,作为“死胡同”。然后,您可以在十字路口记录这些可通行的死胡同,这样,如果您回到十字路口仍在寻找出口,您可以检查您的库存中是否有“钥匙”或“剑”或通过它所需的任何东西。当你回来后,检查未探索路径的选项,以及被你可以打败的东西阻挡的路径。如果你有可以打败怪物的物品,你可以重走那条路,打败怪物然后继续前进。
我不记得这种技术是否适用于有循环的迷宫。因为您应该始终能够判断您以前是否去过某个地点,所以应该在您身后留下一条“面包屑”痕迹或记录您所见过的位置。
它当然不会告诉你最佳路径或最佳得分路径,它只会在你偶然发现它时带你到达出口。
当您发现交叉点时,您还可以将地下城表示为内存中的连通图,图中的每个节点都是交叉点,每个节点之间的路径长度(步数)是图中的转换。您还可以将此图中的障碍物表示为节点。
因此,如果你遇到吸血鬼,它将是大厅尽头没有出口的节点。之后,当你拿到十字架和木桩时,你就会“知道”吸血鬼在哪里,并且能够遍历图表回到吸血鬼(当然假设它没有移动)。
诀窍是真正构建这个图,并使用股票图遍历算法(其中有很多,而且并不那么困难)从一个节点导航到另一个节点。
但对于穿越一个简单的迷宫,堆栈技术非常有效。
附录:
对于简单的迷宫,单个堆栈就足够了。我不知道你的地图是如何布局的,也不知道你是如何导航的,等等。
但你可以做的是每次移动时,只需将移动放在堆栈上即可。然后,当您想要原路返回时,您开始弹出堆栈并朝移动的相反方向前进,直到回到交叉点,然后从那里开始。
这只是对您还不知道其布局的树进行“深度优先”搜索。但同样重要的是,您还可以通过其他方式跟踪您去过的地方。例如,如果您的迷宫表示为大量地板和墙块,则您可以捕获在简单列表中输入的每个地板块的坐标。
这样做的原因是,如果迷宫中有循环,您就不想“向前走”到已经走过的空间。显然你需要在回溯时这样做。但探索的时候,你需要知道你见过什么,没见过什么。如何跟踪取决于地图的数据结构。
考虑这个简单的迷宫:
您可以看到,您只需要在位置 a、b 和 c 处压入堆栈。如果您能够标记您去过的楼层,您的地图在第一个十字路口处可能会如下所示:
并且您的堆栈将如下所示:
7 次向下,一次向左,一次向上。
如果您无法标记地图,您可以改为跟踪坐标。这一切都取决于。
well for simple mazes, you basically "walk" along a path until you get to an intersection. At that point you record all of your options. Then you choose one (using whatever heuristic you like, for you right-hand technique, you'd always "go right"). Once you've recorded the options, you stuff that on to a stack. You then continue forward.
When you read a dead end, you either "walk back", or if possible, simply pop the stack, choose another option and continue from there. To walk back, you simply record each move on the stack as well, and start unwinding the stack until you've reached the last intersection.
You can simply continue to do this, noting monsters and such as either something you can get through, or it you're missing an item, as a "dead end". You can then record these passable dead ends at the intersections so that if you ever come back to the intersection still looking for an exit, you can check your inventory for the "key" or "sword" or whatever you need to pass it. When you've come back, check the options for unexplored paths, and for paths blocked by things you can defeat. If you have the item that can defeat the monster, you can retake that route, defeat the monster and continue on.
I don't recall if this technique will work with mazes that have cycles. It should, since you should always be able to tell if you've visited a spot before, leave a trail of "breadcrumbs" behind you or recording locations you've seen.
It certainly won't tell you the optimal path, or the best scoring path, it will just get you to the exit whenever you bumble upon it.
You can also represent the dungeon as a connected graph in memory as you discover the intersections, with each node in the graph being an intersection, and with the path lengths (the number of steps) it takes between each node being the transitions in the graph. You can also represent obstacles in this graph as nodes.
So if you encounter a Vampire, it'll be a node with no exits at the end of a hall. Later, when you get the crucifix and wooden stake, you'll "know" where the Vampire is, and be able to traverse the graph back to the Vampire (assuming it's not moving, of course).
The trick is really building up this graph as you go and using stock graph traversal algorithms (of which there are many, and they're not that difficult) to navigate from one node to another.
But for traversing a simple maze, the stack technique works very well.
Addenda:
For simple mazes, a single stack should be sufficient. I don't know how your map is laid out or how you navigate it, etc.
But what you can do is every time you move, simply place the move on the stack. Then when you want to backtrack, you start popping the stack and go in the opposite direction of the move until you get back to an intersection, then go from there.
This is simply a "depth first" search of a tree that you don't know the layout of yet. But it's also important that you also keep track of where you been in some other way. For example, if you maze is represented as a large array of floor and wall pieces, you can capture the coordinates of each floor piece you entered on a simple list.
The reason for this is so that if there are cycles in the maze, you don't want to "walk forward" on to spaces that you've already walked on. Obviously you need to do that when backtracking. But when exploring, you need to know what you have and have not seen. How you track that is dependent on how the data structure of your map.
Consider this trivial maze:
You can see that you'll need to push on to the stack only at location a, b, and c. If you're able to mark the floor where you've been, your map might look like this at the first intersection:
And you stack would look like:
For 7 downs, one left, and one up.
If you can't mark the map, you could track the coordinates instead. It all depends.
我个人会尝试使用递归来查找路径。您可以使用 if 语句来处理陷阱,而 not 则可以使用 return 语句来告诉您路径。
这或多或少是伪代码。希望它有帮助!
I personally would try using recursion to find the path. You could have if statements to handle the traps and what not along with return statements to tell you the path.
This is more or less pseudo code. Hope it helps though!