# Gallery: Maze Showroom
```elixir
Mix.install([
{:yog_ex, "~> 0.98"},
{:kino_vizjs, "~> 0.8.0"}
])
```
## Introduction
This gallery showcases the diverse textures, biases, and visual styles of all the maze generation algorithms supported by `Yog.Generator.Maze`.
Each section highlights a different generator, offering a clean look at the **Unicode rendering**, a **pathfinding solution** (from the top-left `S` to bottom-right `E`), and the underlying **spanning tree network**.
## Set up
````elixir
defmodule MazeGalleryHelper do
def render_maze_tabs(maze_name, maze) do
# 1. Unicode String
unicode_string = Yog.Render.ASCII.grid_to_string_unicode(maze)
# 2. Solved Maze
graph = Yog.Builder.GridGraph.to_graph(maze)
start_node = Yog.Builder.GridGraph.coord_to_id(maze, 0, 0)
end_node = Yog.Builder.GridGraph.coord_to_id(maze, maze.rows - 1, maze.cols - 1)
solved_string =
case Yog.Pathfinding.Dijkstra.shortest_path(graph, start_node, end_node) do
{:ok, path} ->
occupants =
path.nodes
|> Map.new(fn id -> {id, "•"} end)
|> Map.put(start_node, "S")
|> Map.put(end_node, "E")
Yog.Render.ASCII.grid_to_string_unicode(maze, occupants)
:error ->
"Error: Pathfinding failed."
end
# 3. Graphviz DOT
# Use a smaller version for DOT visualization to keep it readable
small_maze = apply(Yog.Generator.Maze, String.to_atom(Macro.underscore(maze_name)), [6, 6])
dot_source = Yog.Render.DOT.to_dot(Yog.Builder.GridGraph.to_graph(small_maze))
IO.puts("### #{maze_name} Maze (#{maze.rows}x#{maze.cols})")
Kino.Layout.tabs([
"Unicode Layout": Kino.Markdown.new("```\n" <> unicode_string <> "\n```"),
"Solved Path": Kino.Markdown.new("```\n" <> solved_string <> "\n```"),
"Graph Network (6x6)": Kino.VizJS.render(dot_source, height: "800px")
])
end
end
````
## Classic Maze Algorithms
These popular algorithms are frequently used in game design due to their balance of speed and maze complexity.
### Binary Tree
The fastest algorithm. It carves north or east for each cell, resulting in a very strong diagonal bias.
```elixir
maze = Yog.Generator.Maze.binary_tree(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("BinaryTree", maze)
```
### Sidewinder
A row-based generator similar to Binary Tree but with less diagonal bias. It creates distinct vertical corridors.
```elixir
maze = Yog.Generator.Maze.sidewinder(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("Sidewinder", maze)
```
### Recursive Backtracker
A Depth-First Search walk that backtracks when stuck. It creates very winding, challenging paths with long corridors and few branches.
```elixir
maze = Yog.Generator.Maze.recursive_backtracker(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("RecursiveBacktracker", maze)
```
### Hunt and Kill
Similar to Recursive Backtracker but hunts sequentially across the grid for adjacent visited cells when stuck. It produces winding corridors with no recursion stack.
```elixir
maze = Yog.Generator.Maze.hunt_and_kill(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("HuntAndKill", maze)
```
---
## Unbiased Random Spanning Trees
These algorithms generate mathematically unbiased perfect mazes: all possible mazes are equally likely. They have no directional bias.
### Wilson's
Uses loop-erased random walks to build a perfect spanning tree. It creates beautifully balanced mazes with highly organic corridors.
```elixir
maze = Yog.Generator.Maze.wilson(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("Wilson", maze)
```
### Aldous-Broder
Performs a true random walk over the entire grid. It is slower but guarantees completely uniform randomness.
```elixir
maze = Yog.Generator.Maze.aldous_broder(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("AldousBroder", maze)
```
---
## Partition & Tree-based Algorithms
These algorithms treat maze generation as minimum spanning trees or geometric subdivisions.
### Kruskal's
Treats every cell as a separate set and shuffles all potential passages, merging them using a Disjoint Set Union (DSU) until one spanning tree remains.
```elixir
maze = Yog.Generator.Maze.kruskal(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("Kruskal", maze)
```
### Prim's (Simplified)
Starts from a single cell and grows outwards by adding random adjacent frontier cells, producing high branch densities and many short dead ends.
```elixir
maze = Yog.Generator.Maze.prim_simplified(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("PrimSimplified", maze)
```
### Growing Tree
A highly customizable algorithm that can mimic either Prim's (radial) or Recursive Backtracker (winding) depending on how it selects cells from its active list.
```elixir
maze = Yog.Generator.Maze.growing_tree(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("GrowingTree", maze)
```
### Recursive Division
A fractal-like algorithm that divides the chamber with walls, adding a single passage through the wall, and repeating the process recursively.
```elixir
maze = Yog.Generator.Maze.recursive_division(15, 15, seed: 42)
MazeGalleryHelper.render_maze_tabs("RecursiveDivision", maze)
```