Ruiqi Li
Ruiqi Li

Reputation: 197

Is there an algorithm to dynamical generate a maze, ensuring that there is always more places to go?

Let's suppose we have a maze. You start somewhere in it:

* - * - * 
    |   |
    *-here

Only a small part of the maze is generated (for example, a 10 by 10 square around you). As you move around, more of the maze is generated. Is there an algorithm that ensures that there is always a place for you to go?

For example:

 *-here  * - *
             |
             *

would not work because you have no paths.

I have a 'solution' for it, and that is to generate a finite maze, then force it to be connected to another finite maze, forming a mesh (ensuring that finite mazes are doable is easy).

Edit 1: The maze can't have a deterministic size; Parts of the map will be generated dynamically.

Edit 2: It has to generate the same maze no matter the order which you load it in (Moving up then left should generate the same maze as moving left then up)

My maze does not need to include all places

example image:enter image description here

Upvotes: 5

Views: 1964

Answers (4)

Victor Engel
Victor Engel

Reputation: 2133

Here's a suggestion of something that doesn't entirely meet your objective, but it comes close. Where it's lacking is that you also have to compute a guaranteed solution, which will override what follows. So what follows is deterministic for the rest of the maze.

The type of maze being considered uses a square grid. Each cell is a square. There are 16 types of cells. Think of each wall as a binary digit. If the wall is missing, it's a 1. If it's present, it's a 0. Using a seed calculated from the coordinates of the cell, compute a random number from 0 to 15 and assign it to the cell. Each cell now has deterministically been assigned a random number.

Neighboring cells are possibly incompatible, though. So simply use a rule to tweak the values. For every pair of adjoining cells, take the one with the lower coordinate as the truth (the other coordinate is the same, since we're talking about a square grid). Adjust the wall value of the other one to match.

That creates a maze without a guaranteed path. So simply modify it with the path from the calculated solution. Let's number the edges clockwise from the top, assigning the top to the most significant bit. I'll fill in the space with a perpendicular line to show where a path would be, rather than leaving it blank as in the question.

Example cells:

* - *
|   | 0 cell
* - *

* - *
-   | 1 cell
* - *

* - *
|   | 2 cell
* | *

* - *
-   | 3 cell
* | *

etc.

So now, suppose the cell at (5,4) as a type 6 and its neighbor to the right (6,4) is a type 12:

* - *      * | *
|   -      |   -
* | *      * - *

These conflict with each other. The one on the left wants the path. The one on the right wants a wall. This is resolved by looking at the coordinates. (5,4) < (6,4) so the left one is given precedence. It wants a path, so the other cell is modified by applying a bitwise or with 1:

* - *      * | *
|   -      -   -
* | *      * - *

So the new configuration of the cell to the right is type 13 (12 OR 1).

The two cells are then compared to the precomputed solution path and tweaked, if needed. If the precomputed solution does not pass through either of these cells, we are finished.

Upvotes: 0

user13547267
user13547267

Reputation:

Maybe you can use Wilson's algorithm to solve your problem. This algorithm grows the "maze" (spanning tree) by adding a loop-erased "random walk" from some point outside of the existing maze until the random walk meets the existing maze. So if you want to grow your existing maze, you could add some empty region (only nodes, no edges) to your existing graph, select one vertex from that region and run a random walk until the existing maze is met which will grow your maze.

Upvotes: 0

Matt Timmermans
Matt Timmermans

Reputation: 59174

I like to generate mazes with variants of Kruskal's algorihtm:

http://weblog.jamisbuck.org/2011/1/3/maze-generation-kruskal-s-algorithm

https://mtimmerm.github.io/webStuff/maze.html

One way to think of using Kruskal's algorithm to generate mazes is:

  1. Assign a random weight to every possible wall
  2. Remove every wall if the cells on ether side of it are not connected by removing all walls of lesser weight.

If you divide the world into tiles, then you can turn this into an algorithm that you can evaluate locally as follows:

  1. Assign a random weight to every possible wall. Use a different random number generator for the walls in each tile, and seed it with the tile's coordinates.
  2. Remove every wall if the cells on either side of it are not connected by removing all walls of lesser weight in its tile and adjacent tiles.

This way, to generate any tile of the maze, you only need to consider the weights that would be assigned to walls in the 8 adjacent tiles. The procedure is just like doing the normal Kruskal's to make a 3 tile X 3 tile maze, and then cutting out the middle tile.

When you generate mazes this way, it's guaranteed that there will be a path from every place in the maze to every other place. Unlike "perfect" mazes, however, there may be more than one path between two places that are more than a tile apart. As long as your tiles are sufficiently large, though, there won't be any visible artifacts of the tiling, and it will still be difficult to find your way from one place to another.

Upvotes: 2

Thomas Kammeyer
Thomas Kammeyer

Reputation: 4507

There are many, of varying complexities. A good place to start is the Wikipedia page: https://en.wikipedia.org/wiki/Maze_generation_algorithm.

Often, it'll be easier to generate the whole maze in advance and reveal it bit by bit as it is explored than to incrementally generate the maze during exploration, but take a look at the link and decide what you think.

Also, if the maze doesn't completely fill space, you might look at the way old games like hack, nethack, or rogue generate room layouts on levels. I'm sorry I don't have a reference for how that was done.

Upvotes: 1

Related Questions