Closed econrad003 closed 4 years ago
In addition, the following tools may be useful in creating directed mazes:
Caution here: we don't want to run this twice on an edge.
Not sure how useful these would be in practice... But note that the above algorithms suggest that joins have a practical use.
I am currently working on this in the context of rectangular grids. At the moment, I have:
The layout class doesn't handle one-way tunnels yet, so it is not yet suitable for use with weave mazes. The binary tree algorithm is complete. The demonstration script is in line with what I've done so far. Some samples follow.
a 3 by 5 directed binary tree maze: (The links in the NE corner were turned into two-way links for demonstration purposes. The algorithm only produces one-way links. Note that coloring is supported.)
Another 3x5 demo, with inset walls and passages. In this case we have two directed binary trees superimposed on one another, one leading towards the root in the NE corner, and the other leading away from the root cell:
A larger demo, also inset, also two superimposed directed binary tree mazes, one directed towards the NE corner, the other away.
Before I release the code, I'd like to (1) handle one-way tunnels in weave mazes and (2) one-way stairwells ("escalators"?) in multilevel mazes; (3) more algorithms and, of course, (4) a reasonable complement of demonstrations.
Sidewinder is now complete -- at least it works correctly with forward east and up north. I've replaced the thick lines with thinner lines in the layout. (It's one extra line of code in the demo, but I think it looks better on the dense image.) Note the characteristic top row. This is actually two passes of E/N sidewinder, one with arcs directed towards the NE corner, and the other directed away. Each cell should have a minimum of two arcs, one directed into the cell, and the other directed out. If a passage has no arrow, it indicates that it is bidirectional, i.e. both an in-passage and an out-passage. Note also that the top row is connected by bidirectional passages. A typical puzzle might be: start in the SW corner, work your way through the maze to a cell in the top row where some object has been place and find your way to the exit in the SE corner. There is also the Theseus puzzle: start in the SW corner, find your way to the Minotaur somewhere in the north row, slay the Minotaur, and trace your way back to the SW corner to Ariadne (who is later abandoned on a deserted island somewhere in the Mediterranean, but that's another story.)
Oops! I see that there are no arrows into the north row, Well still some work to do...
A second look finds that there is indeed one arrow into the top row from the row below. It is about eight columns of the way across (or about one fourth of the way) from the left.. But there is still a bug. Note that the maze is disconnected even if we ignore the arrows. Also, there are some interesting artifacts of the bug (or bugs) in the second row,
The bug turned out to be quite simple. When closing out the runs, I failed to reset the list of cells in the run to the empty list. The result was that some of the links that were created were to cells that weren't actually in the run. In all but the top row, the more cells that were processed, the more likely that northward links were not valid. The correction was one line of code:
In method close_out_run(self), replace the line
return None
with the lineself.fwdrun = []
Of course finding the error was harder than fixing it.
Here is a 5 by 5 directed sidewinder maze with arrows directed towards terminus:
And here is a full-sized one with arrows directed away:
Recursive Backtracker (or depth-first seach) is now complete. During the course of debugging, I investigated weave mazes. There are some complications related to tunnelling, specifically in (but not limited to) the can_tunnel methods. So I've decided not deal with weave mazes for the time being. Perhaps they will be a later enhancement. In any case, here is a recursive backtracker run. The terminus is displayed in orange. The maze is produced with two runs, the first with arrows leading to the terminus (treating it as the sink) and the second with arrows leading away from the terminus (now treating it as the source). There should be at least one directed path between any pair of vertices. There are directed circuits in the maze, and there may be more than one simple directed path between some pairs of vertices. (These are features, not bugs.)
With the implementation of directed Aldous/Broder, this issue is now closed, See the README (or CHANGELOG) for information on the September 29 update.
I think the following algorithms can be used for two pass creation of directed mazes:
Given vertices (i.e. cells) u and v, to find a directed path from u to v, let P be the pass 1 directed path from u to the NE corner, and let Q be the pass 2 directed path from the NE corner to v. Then P+Q is a directed path from u to v.
The result is that from any vertex v there are directed paths both to and from the start vertex s. So start vertex s is like the NE corner in Binary Tree.
Other growing tree algorithms should work in the same fashion.