Generating (better) random mazes
< change language
In this previous post I shared some code and animations of an algorithm that created random mazes. I shared it with you and I got some feedback on Facebook, saying that even the stupidly large mazes I gave you were really easy to solve (I think this link can show you what I am talking about). So it was about time I got you some new mazes! And this time, I don't think they are as easy to solve as the old ones.
The mazes I am sharing today were created by code found in this GitHub repo. The README will tell you to run the
The way our algorithm works is really simple. It will start a random walk on the top left corner of the window. Whenever the random walk intersects itself (creating a loop), it removes the loop from the walk, and then continues. Whenever the random walk connects back to whatever part of the maze was already built, the random walk becomes a part of the maze itself and a new random walk is started somewhere else. This is a loop-erased random walk, the stepping stone of Wilson's algorithm to generate a random spanning tree of a graph, with a very nice property: it will generate any of the possible spanning trees with equal probability.
Generating any of the spanning trees uniformly means that our maze won't be biased and have only a couple of really long paths, or a bunch of very short paths. And the reason why this algorithm actually has that property is fairly intuitive: just suppose that before running the algorithm, you visit each vertex, and create an infinite random stack of directions; that is, for each vertex $v$ in the graph, you create a random sequence $\{v_i\}_i$, where each $v_i$ was selected randomly and uniformly from the direct neighbours of $v$. After you have done this for every vertex, there is an obvious way to start tracing paths in your graph: just pick a vertex and start following the directions you are given! But the thing is, following those directions might actually make you follow some loops. So before tracing the paths you are presented with, you remove all the loops that you can find on top of all the stacks you created... when that has been done, following the directions that are on top of the stacks will give you a uniformly generated random tree. Of course that to run our algorithm, we don't generate the infinite stacks in advance, we just generate the elements that are needed on-the-fly.
This algorithm creates really balanced mazes... As an example, take this maze:
Now imagine that on the top left corner I will pour a bucket of a special paint: one that gradually changes colour as it travels. The resulting (coloured) maze looks like this:
(please bear in mind that the colours used cycle back to the beginning, so it creates a continuous and infinite degradee)
Also notice that this algorithm can be painfully slow to watch, specially when it has just started. I would strongly recommend against changing the configuration
That is it! You have a small animation of the algorithm on the beginning of the post and a massive maze down there! Let me know if you manage to find your way from the top left corner to the bottom right corner! (the black and white version of that maze is here)
I would also recommend checking this link, as it has some nice animations.
The mazes I am sharing today were created by code found in this GitHub repo. The README will tell you to run the
wilson_generator.py
file. You can also download the (windows) executable that is zipped inside the wilsonExe
rar. (please notice that in both cases, you can use the wilsonconfig.ini
file to change the size of the maze)The way our algorithm works is really simple. It will start a random walk on the top left corner of the window. Whenever the random walk intersects itself (creating a loop), it removes the loop from the walk, and then continues. Whenever the random walk connects back to whatever part of the maze was already built, the random walk becomes a part of the maze itself and a new random walk is started somewhere else. This is a loop-erased random walk, the stepping stone of Wilson's algorithm to generate a random spanning tree of a graph, with a very nice property: it will generate any of the possible spanning trees with equal probability.
Generating any of the spanning trees uniformly means that our maze won't be biased and have only a couple of really long paths, or a bunch of very short paths. And the reason why this algorithm actually has that property is fairly intuitive: just suppose that before running the algorithm, you visit each vertex, and create an infinite random stack of directions; that is, for each vertex $v$ in the graph, you create a random sequence $\{v_i\}_i$, where each $v_i$ was selected randomly and uniformly from the direct neighbours of $v$. After you have done this for every vertex, there is an obvious way to start tracing paths in your graph: just pick a vertex and start following the directions you are given! But the thing is, following those directions might actually make you follow some loops. So before tracing the paths you are presented with, you remove all the loops that you can find on top of all the stacks you created... when that has been done, following the directions that are on top of the stacks will give you a uniformly generated random tree. Of course that to run our algorithm, we don't generate the infinite stacks in advance, we just generate the elements that are needed on-the-fly.
This algorithm creates really balanced mazes... As an example, take this maze:
Now imagine that on the top left corner I will pour a bucket of a special paint: one that gradually changes colour as it travels. The resulting (coloured) maze looks like this:
(please bear in mind that the colours used cycle back to the beginning, so it creates a continuous and infinite degradee)
Also notice that this algorithm can be painfully slow to watch, specially when it has just started. I would strongly recommend against changing the configuration
save_frames = False
to True
, as that will slow down the algorithm for a bit... but if you must do that, point the screenshot_bin
to some existing folder, so that the thousands of frames get dumped there.That is it! You have a small animation of the algorithm on the beginning of the post and a massive maze down there! Let me know if you manage to find your way from the top left corner to the bottom right corner! (the black and white version of that maze is here)
I would also recommend checking this link, as it has some nice animations.
$600 \times 450$ maze
- RGS