0

I have read about the Depth-First search algorithm to create and solve mazes. However, I have not found anything on creating mazes with fixed entry and exit. On each maze the entry would always be at (0, 1) and the exit at the opposite side on both axis.

During the generation of the maze, every cell should be visited (to generate as many dead-ends as possible) but the the exit should always be at the same point.

The solution path to the resulting mazes would look like this:

enter image description here

Or this:

enter image description here

R01k
  • 735
  • 3
  • 12
  • 26
  • Do you want just one path from start to end, or an actual maze, with many dead-ends? And should the entire grid be covered, or just a part, as in your examples? – tobias_k Sep 02 '16 at 20:49
  • My first thought would be to start with a simple path connecting the entry and the exit and then incrementally deform it until you reach a desired complexity. – Jared Goguen Sep 02 '16 at 20:49
  • I'd suggest starting with an empty maze, and two sets that initially contain only the start and the end respectively. Then repeatedly add connections between one of the sets and the undiscovered region until the entire maze is filled and the start and end regions are connected, similar to [this](http://stackoverflow.com/a/22308159/1639625) – tobias_k Sep 02 '16 at 20:51
  • Just backtrack from the DFS when you reach the exit instead of going deeper? – Stefan Pochmann Sep 02 '16 at 20:52
  • @tobias_k Yes, only one path leading from start to end. In my example I show the solution path without any ramification to dead-ends. – R01k Sep 02 '16 at 20:56
  • 2
    If you want just one wiggly path, try a depth-first search with adding outbound edges in _random_ order, and backtracking as soon as you hit a node that you already visited, until you find the target. – tobias_k Sep 02 '16 at 20:56
  • @JaredGoguen I thought of that, but much easier said than done... for me. – R01k Sep 02 '16 at 20:57
  • @R01k Every segment in the original path can be replaced by one of two "C" shaped paths (same start and end as the segment). Iterate over the segments in your path, check whether each "C" could be added (or if it would collide or go out of bounds), adding them to a list as you go. Then, pick one (or more with care) at random and repeat. – Jared Goguen Sep 02 '16 at 21:02
  • @tobias_k "and backtracking as soon as you hit a node that you already visited, until you find the target." That sounds promising, but I could hit the target before visiting all nodes, which -if too early- could end up in a too simple maze. – R01k Sep 02 '16 at 21:03
  • This question is interesting, but it will probably very soon be closed as "too broad", because it is. To get an actual answer, you should at least provide some kind of "framework" for us to work with, e.g. how your maze is represented. – tobias_k Sep 02 '16 at 21:03
  • Well, "too simple" paths are just part of being random. Or are you looking for a single, dead-end free path covering _every single cell_ in the maze? – tobias_k Sep 02 '16 at 21:04
  • @StefanPochmann That also might result in a too simple maze if I hit the exit too early. – R01k Sep 02 '16 at 21:05
  • @tobias_k Yes, that would be an optimal solution. – R01k Sep 02 '16 at 21:06
  • @R01k Surely you're joking? A single, dead-end free path is optimal? That's the simplest "maze" possible! Then why are you worried about being too simple? You make no sense. – Stefan Pochmann Sep 02 '16 at 21:09
  • @tobias_k "This question is interesting, but it will probably very soon be closed as "too broad..." Ok. I will post another question if needed with more insights on how I'm approaching this. – R01k Sep 02 '16 at 21:09
  • @StefanPochmann Please note that what I showed in the pictures is the solution path without ramifications. Of course that I want dead-ends. That's why the DFS appeals me. – R01k Sep 02 '16 at 21:12
  • @R01k But where are the dead-ends going to be if the dead-end free path is *"covering every single cell in the maze"*? – Stefan Pochmann Sep 02 '16 at 21:14
  • Wait wait wait, now you've lost me. Do you _want_ dead end or not, or do you _first_ want a path and add dead ends later, because you think it's easier that way? In short, do you want a [maze](https://en.wikipedia.org/wiki/Maze) or a [labyrinth](https://en.wikipedia.org/wiki/Labyrinth)? If you need a maze, try the approached in the answer I linked above or in Cody's answer. – tobias_k Sep 02 '16 at 21:15
  • Ok, I edited the details for the question, in short, I do want a maze with dead-ends not a labyrinth. Sorry for any misunderstanding. – R01k Sep 02 '16 at 21:24
  • 1
    @R01k I just saw your edits. While it can be done with DFS I would really encourage you to use BFS and Prim's Algorithm instead, only because I have a tried and true approach for that. See my answer below, and if you are using Windows, play around with my maze generation and editing toolkit linked in my answer. – Cody Sep 02 '16 at 21:25
  • @Cody If DFS is bad for this, then why is it the first method mentioned on the Wikipedia article about this? https://en.wikipedia.org/wiki/Maze_generation_algorithm – Stefan Pochmann Sep 02 '16 at 21:30
  • @StefanPochmann its not that DFS is bad, its that I know for a fact that BFS works really well since I've used it for doing exactly what the OP is trying to do. I know from working out the initial implementation that the Prim's Algorithm approach was a bit simpler. In the end, either DFS or BFS can be used to achieve a similar result. – Cody Sep 02 '16 at 21:32

1 Answers1

1

I've made grid-based mazes before using a breadth-first search, but a similar algorithm can be devised from a depth first one.

First I'd create a graph, where each node in your coordinate graph above links to the node up, down, left, and right of it. For example, node (1, 1) has an edge to (0, 1), (1, 0), (2, 1), and (1, 2). Edge nodes will only have 3 edges, and corner ones will only have 2, since the neighbors in the appropriate directions don't exist. While you are generating these edges, assign each one a random weight. When I implemented it I found that a range of [0, 100) worked well, but you can tweak that. Then finally you can do a Depth First Search from your desired start node to the desired end one, and just trace out the path as you go. If you recurse down an edge that would connect you to a node you've already visited, don't draw the edge there. That'll get you something that looks maze-like.

When I did it, I actually set up the graph in the same way, but instead of DFS I used Prim's Algorithm to calculate the minimum spanning tree of that graph. This gave me something that looked maze-like, touched every node at least once, and contained no cycles. Then I could assign any point I wanted to be the start and end point, and the maze would contain no cycles, and exactly 1 shortest path between any 2 points. I added tools on top of that for editing the maze, removing dead ends, rendering it in 3D, etc, but those are beyond the scope of your question.

If you want to see how I did it, check out my project on GitHub. The "Minotaur" folder contains the executable (a Frankenstein's monster of Python, C++, and C#), and the source is in there too. The maze generation part is in this file.

I know you asked for this in Python but I'm too busy reverse engineer my C++ code right now, I hope you still find this answer helpful.

Edit: I nearly forgot I made a fancy video showing it off, so if you want to see it in action but don't want to compile my source or don't trust my executable, you can view the project on my portfolio.

Cody
  • 2,643
  • 2
  • 10
  • 24
  • As I understand the question, OP does not want a tree, but a single path from start to end, possibly spanning the entire grid. You could generate a tree and then cut away all the dead ends, though... – tobias_k Sep 02 '16 at 21:10
  • In my implementation of not just the graph generation, but the maze editing tools that come with it, it can do that. That required post-processing after the initial tree generation though. I mentioned it and linked to my implementation since he mentions mazes several times in the question, and I'd hardly consider a windy path with no dead ends to be a maze. – Cody Sep 02 '16 at 21:13
  • @tobias_k In fact, I want a labyrinth with dead-ends. – R01k Sep 02 '16 at 21:27
  • @R01k And "a labyrinth with dead-ends" is not a labyrinth but a maze. In this case, I think Prim's algorithm is exactly what you need. – tobias_k Sep 02 '16 at 21:28
  • @Cody I'll see into your suggestions and come back. – R01k Sep 02 '16 at 21:31
  • @tobias_k You're dead right. That's what I meant to type ) – R01k Sep 02 '16 at 21:32