art.generative
L-systems, fractals, the Mandelbrot set, cellular automata, mazes, starfields
Example results generated on 2026-10-08. Ones using
now,todayor randomness will differ when you run them: press Run on any example to run it in your browser, after editing it if you like.
Functions
| function | description |
|---|---|
lsystem(axiom: str, rules: map, angle: num, n: int, width?: int) | rewrite axiom n times with rules (one character → its replacement), then draw it with a turtle in braille, width characters wide (default 60). F and G draw a step, f steps without drawing, + and - turn by angle degrees, | turns around, [ and ] save and restore position; other characters do nothing. Starts facing up |
fractal(name?: str, n?: int, width?: int) | a named L-system fractal: “dragon”, “koch”, “hilbert”, “sierpinski”, “levy”, “gosper”, “tree”, “fern” or “bush”; n is the depth, width as in lsystem. No name lists them |
rule(n: int, width?: int, steps?: int) | an elementary cellular automaton, 0-255, grown from one cell for steps rows (default width / 2) on a wrapping row of width cells (default 64); two rows per line |
spiral(size?: int) | an Ulam spiral: 1, 2, 3… wound out from the center with the primes as dots, which line up on diagonals; size characters wide (default 40) |
starfield(width: int, height: int, seed?: int) | a random night sky; the same seed gives the same sky |
mandelbrot(width?: int, height?: int) | the Mandelbrot set in ASCII, default 72×24 |
life(start: str, steps?: int) | run Conway’s Game of Life for steps (default 1) and draw the live cells; start is rows of # and . or one of “glider”, “blinker”, “pulsar”, “r_pentomino” |
maze(width?: int, height?: int) | a random perfect maze (one path between any two cells), default 20×10 cells |
lsystem
lsystem(axiom: str, rules: map, angle: num, n: int, width?: int): rewrite axiom n times with rules (one character → its replacement), then draw it with a turtle in braille, width characters wide (default 60). F and G draw a step, f steps without drawing, + and - turn by angle degrees, | turns around, [ and ] save and restore position; other characters do nothing. Starts facing up
lsystem("F", {F: "F+F-F-F+F"}, 90, 3, 30)
# → ⡤⠇
# → ⣀⡏⣏⡇
# → ⢀⣀⣖⡃
# → ⢀⣰⠚ ⠓⣗⣆⣖⡆
# → ⢰⢺⢲ ⡖⡗⡗⡆
# → ⢠⠼⠉⠈⠉ ⠉⠁⠉⠁
# → ⡤⠏⠹⠽
# → ⣏⡁
# → ⠓⣆⣰⣲
# → ⠘⢲⣀⢀⣀ ⣀⡀⣀⡀
# → ⠸⢼⠼ ⠧⡧⡧⠇
# → ⠈⠹⢤ ⡤⡯⠏⠯⠇
# → ⠈⠉⠯⡅
# → ⠉⣇⣏⡇
# → ⠓⡆
See also: fractal
fractal
fractal(name?: str, n?: int, width?: int): a named L-system fractal: “dragon”, “koch”, “hilbert”, “sierpinski”, “levy”, “gosper”, “tree”, “fern” or “bush”; n is the depth, width as in lsystem. No name lists them
fractal("koch", 3, 30)
# → ⡀⠠⡴⢧⠄⢀
# → ⠐⡞⠑⠚ ⠓⠊⢓⡆
# → ⣀⣠⣀ ⢈⣙⠄ ⠠⣋⡁ ⣀⣠⣀
# → ⣀⡴⣀⡕ ⢪⣀⢦⣀⠇ ⠐⣅⡴⣀⡕ ⢪⣀⢦⣀
# → ⠯⡄ ⢠⠽
# → ⢖⠋ ⠙⡲
# → ⠓⠲⠒⡢ ⢔⠒⠖⠚
# → ⣉⡧ ⠰⣉
# → ⡤⠴⠤⠕ ⠪⠤⠦⢤
# → ⠮⣄ ⣠⠵
# → ⣖⠃ ⠘⣲
# → ⠉⠳⠉⡣ ⢜⠉⠞⠉⡆ ⠠⡋⠳⠉⡣ ⢜⠉⠞⠉
# → ⠉⠙⠉ ⢈⣩⠂ ⠐⣍⡁ ⠉⠙⠉
# → ⠠⢧⡠⢤ ⡤⢄⡬⠇
# → ⠁⠐⠳⡞⠂⠈
fractal()
# → ["dragon", "koch", "hilbert", "sierpinski", "levy", "gosper", "tree", "fern", "bush"]
rule
rule(n: int, width?: int, steps?: int): an elementary cellular automaton, 0-255, grown from one cell for steps rows (default width / 2) on a wrapping row of width cells (default 64); two rows per line
rule(30, 32)
# → ▄█▄
# → ▄█▀▄▄█▄
# → ▄█▀▄▄█▄ ▄█▄
# → ▄█▀▄▄█▄ ▄█▄▄█▄
# → ▄█▀▄▄█▄ ▄█▀▀▄ ▄█▄
# → ▄█▀▄▄█▄ ▄█ █▀▀▀ █▀▄▄█▄
# → ▄█▀▄▄█▄ ▄█▀▀▄▄█▀▄▄█▀ █▄ ▄█▄
# → ▄█▀▄▄█▄ ▄█ █▀▀▄ ▄█▄▄█▀▀▄▄█▄▄█▄
rule(90, 32, 16)
# → ▄▀▄
# → ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄
spiral
spiral(size?: int): an Ulam spiral: 1, 2, 3… wound out from the center with the primes as dots, which line up on diagonals; size characters wide (default 40)
spiral(20)
# → ⢀⠄⠁⢐⢄⠄⠐ ⠔⠑⠄⠕ ⢁ ⠁⢐
# → ⢀⠄ ⢀⠁⢁ ⠁⠔⠁⢔⢐ ⠐⢄⠁⠄⠄⠁
# → ⠐⠑⢄⠁⢁⠄ ⠕⠁⢀ ⢅⢀⠐⢅⢐⢀ ⠐⠐
# → ⢀⠁⢁⠐⢀ ⢑⢀⠐⢑⠄⠄ ⢀⠅⢁⢄⠑⠄⠄
# → ⠐⠄⠄⠄⠔⠄⠔⠔⢄⢁⢕⠐⠑ ⠄⠐⢐⠐
# → ⢀⠐⢀⢀ ⢑⢔⠑⢌⠁⢁⢁⠁⢀⠁⢁⢁
# → ⢀⢅ ⢁ ⢅⠄⠑ ⠄⠁⢄ ⠕⠁⢀⠁⠄⢄
# → ⠅⢄⠄⢅ ⠐⠑ ⠕⢅⢀⠐⠄⠐ ⠄⠔
# → ⠑⠐⠁⠁⢀⠐⢅⠄ ⢅⠔⠁⢁ ⠐⠄ ⢐⢅
# → ⢐ ⢐⢀⠁⢁⠐ ⢁ ⠐ ⢐⠄ ⠑⠄
See also: is_prime
starfield
starfield(width: int, height: int, seed?: int): a random night sky; the same seed gives the same sky
starfield(30, 4, 7)
# → .
# → · ·
# → · · + +
# → . ·
See also: negative
mandelbrot
mandelbrot(width?: int, height?: int): the Mandelbrot set in ASCII, default 72×24
mandelbrot(40, 12)
# →
# → ...:
# → ...:@@@..
# → ..#+=@@@@@@@:#:.
# → .........#@@@@@@@@@@@@-.
# → ..:@@@@@:@@@@@@@@@@@@@@@-
# → @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@-..
# → ..:@@@@@:@@@@@@@@@@@@@@@-
# → .........#@@@@@@@@@@@@-.
# → ..#+=@@@@@@@:#:.
# → ...:@@@..
# → ...:
See also: life
life
life(start: str, steps?: int): run Conway’s Game of Life for steps (default 1) and draw the live cells; start is rows of # and . or one of “glider”, “blinker”, “pulsar”, “r_pentomino”
life("blinker")
# → #
# → #
# → #
life("glider", 4)
# → .#.
# → ..#
# → ###
See also: maze
maze
maze(width?: int, height?: int): a random perfect maze (one path between any two cells), default 20×10 cells
maze(6, 3)
# → ██ ██████████████████████
# → ██ ██ ██ ██
# → ██ ██ ██████ ██ ██ ██
# → ██ ██ ██ ██ ██
# → ██████████ ██████ ██ ██
# → ██ ██ ██
# → ██████████████████████ ██
See also: life
More examples
grow things
# a dragon curve
fractal("dragon", 8, 30)
# → ⣀⣸⣉⡇ ⢀⣸⣉⡇
# → ⠓⢺⠒⡆⡖⢺⢺⠒⡆⡖⠂
# → ⠸⠭⡧⠏⠹⢤ ⢠⢤ ⠯⢽⠭⡯⡅⠈⠉ ⠉⠯⠅
# → ⣖⣲⣰⣒⡃ ⠐⠚ ⣖⣺⣚ ⣀⣖⣚ ⠓⠃ ⣆⡖⠂
# → ⠸⢼⠤⠇ ⡤⢼⢼⠤⡧⡧⢼⠤⡄
# → ⣀⣀⢘⣒⣆⣖⣲ ⣀⣰⣲ ⣓⣺⣺⣒⣗⣗⣺⠒⣗⡆
# → ⠧⢼⢼⠤⡧⡧⢤⢠⠤⡧⢼⢤ ⡤⡧⢼⢼⠤⡧⡧⢤
# → ⠈⠉ ⠉⠁⠈⢹⣉⣏⣹⣹⣉⡁⠉⠉⠈⠉⣏⣏⣹⣉⣇⡀
# → ⡖⢲⢰⠒⡗⠚⠘⠒⠃ ⢰⢲ ⡖⡗⠚ ⠓⠃
# → ⠉⠹⠽⠉⠯⠽ ⠈⠹⠭⠏⠯⠽
# a tree in a box
fractal("tree", 6, 24).boxed("round")
# → ╭───────────────────╮
# → │ ⢀⡀⠐⢾ ⡯⠂ ⠐⠪⡇⡹⠒ ⣀ │
# → │ ⣀⠓⣇ ⢹ ⢹⠁ ⢀⠗⢃ │
# → │ ⠞⠉⠉⠑⠤⣸ ⢸⡠⠔⠉⠉⠱ │
# → │ ⠘⢆ ⢀⠎ │
# → │ ⠈⢢ ⣠⠃ │
# → │ ⢳⠃ │
# → │ ⢸ │
# → │ ⢸ │
# → │ ⢸ │
# → │ ⢸ │
# → │ ⢸ │
# → │ ⢸ │
# → ╰───────────────────╯
# Sierpinski, two ways
rule(90, 32, 16).beside(fractal("sierpinski", 4, 16), 4)
# → ▄▀▄ ⣰⣇
# → ▄▀▄ ▄▀▄ ⣼⣷⣾⣧
# → ▄▀▄ ▄▀▄ ⢀⡾⢿⡄⢠⡿⢷⡀
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ⢠⣞⠛⠚⠛⠛⠓⠛⣳⡄
# → ▄▀▄ ▄▀▄ ⣠⣿⣻⣦ ⣴⣟⣿⣄
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ⣰⣯⡉⠉⣹⣧⡀⢀⣼⣏⠉⢉⣽⣆
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ⠼⠷⠼⠷⠼⠷⠼⠷⠾⠧⠾⠧⠾⠧⠾⠧
# → ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄ ▄▀▄
# invent a plant
lsystem("X", {X: "F[-X][X]F[-X]+FX", F: "FF"}, 25, 4, 30)
# → ⣀⡀⠐⣄⡀ ⠈⢧ ⡄
# → ⠈⠉⠙⠳⡀ ⠈⢷⡇ ⠒⡄⢀
# → ⠈⠲⣄⢻⢆⣜ ⠸⣸
# → ⠹⣿⠎ ⡟ ⢰
# → ⡀⠹⣀ ⠢⡌⣇ ⢠⣏⡄
# → ⠉⠓⢵⣇ ⠠⡸⣿⣜⠟⡉
# → ⢻ ⣷⣿⡿⠊⢱
# → ⠈⢣ ⣬⡿⡇ ⢠⣏⡀
# → ⢣⡇⣧⣏⣼⡟⠋
# → ⢸⡝⢺⣵⣿⠖⠁
# → ⢸⢠⠋
# → ⢸⠃
# → ⢸
# → ⢸
# → ⢸
# the Mandelbrot set
mandelbrot()
# →
# → .-.
# → .......
# → ...-=:...
# → .....:@@@@@:..
# → .........:@@@@+:.........
# → ....:@@:%@@@@@@@@@@@@@:.:::#.
# → .....*.#@@@@@@@@@@@@@@@@@@@@@:..
# → ................-@@@@@@@@@@@@@@@@@@@@@@@=...
# → ....:@-.:@::...:=@@@@@@@@@@@@@@@@@@@@@@@@@-..
# → ...:.-@@@@@@@@=:-@@@@@@@@@@@@@@@@@@@@@@@@@@@-.
# → ........#=:+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.
# → @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+:...
# → ........#=:+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.
# → ...:.-@@@@@@@@=:-@@@@@@@@@@@@@@@@@@@@@@@@@@@-.
# → ....:@-.:@::...:=@@@@@@@@@@@@@@@@@@@@@@@@@-..
# → ................-@@@@@@@@@@@@@@@@@@@@@@@=...
# → .....*.#@@@@@@@@@@@@@@@@@@@@@:..
# → ....:@@:%@@@@@@@@@@@@@:.:::#.
# → .........:@@@@+:.........
# → .....:@@@@@:..
# → ...-=:...
# → .......
# → .-.
# a glider, 8 steps on
life("glider", 8)
# → .#.
# → ..#
# → ###
# draw your own
life(".#.\n.#.\n.#.", 1)
# → "###"
# a maze
maze(12, 6)
# → ██ ██████████████████████████████████████████████
# → ██ ██ ██ ██
# → ██████████ ██████ ██████████████ ██ ██████ ██
# → ██ ██ ██ ██ ██ ██ ██ ██
# → ██ ██ ██████ ██ ██ ██████ ██ ██████ ██ ██
# → ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
# → ██ ██ ██████ ██████ ██ ██ ██████ ██████ ██
# → ██ ██ ██ ██ ██ ██ ██ ██
# → ██ ██████ ██████ ██ ██ ██████████████████ ██
# → ██ ██ ██ ██ ██ ██ ██ ██
# → ██ ██ ██████ ██████████ ██ ██ ██ ██████ ██
# → ██ ██ ██ ██ ██
# → ██████████████████████████████████████████████ ██