shiffman_pearson_textbook · randomWalkDrunkard
Random Walk / Drunkard's Walk
Many random walkers each start at the canvas center and take a stochastic 2-D step every tick. Four walk variants are supported: 'cardinal' (4 axial directions), 'diagonal' (8 directions including diagonals), 'levy' (Lévy flights — with probability levy_p a long step is drawn from a Pareto power-law tail, otherwise a unit diagonal step — Pearson Generative Art Ch. 3), and 'momentum' (each walker has a velocity that is jittered by Gaussian noise and decays geometrically per tick, mimicking Shiffman's 'A Smoother Perlin Walk' in Ch. 6). Walkers leave low-alpha trails on the canvas. Edges wrap (toroidal) or bounce.
Original: https://en.wikipedia.org/wiki/Random_walk
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
Each walker: pos += step, where step is one of the 4/8 direction vectors scaled by step_len (cardinal/diagonal); or Pareto-tailed (Lévy) at probability levy_p; or vel = vel*decay + N(0, jitter) clipped to step_len (momentum). Periodic boundaries via pos %= dim (torus=True) or velocity reflection at the edges (torus=False). Canvas trail: canvas[p] = (1 - alpha) * canvas[p] + alpha * ink.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 400 | 120–1200 | |
num_walkers | int | 400 | 10–4000 | |
step_len | float | 1 | 0.2–8 | Unit step length (pixels). |
variant | str | diagonal | — | |
levy_p | float | 0.02 | 0–0.2 | Probability of a long Lévy step. |
levy_alpha | float | 1.5 | 0.5–3 | Pareto tail index (smaller = heavier tail). |
momentum_decay | float | 0.92 | 0.5–1 | |
momentum_jitter | float | 1.4 | 0–5 | |
torus | bool | true | — | Wrap edges (true) or bounce (false). |
trail_alpha | float | 0.18 | 0.01–1 | |
bg_color | tuple | 15,18,30 | — | |
ink_color | tuple | 240,220,200 | — | |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/shiffman_pearson_textbook/randomWalkDrunkard/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class RandomWalkDrunkard:
"""Random-walk / drunkard's-walk — Nature of Code Ch. 1 / Generative Art Ch. 3.
Many walkers each start at the canvas center and take a stochastic 2-D
step every tick. Four walk variants are supported:
- ``'cardinal'``: step to one of 4 axial neighbours (N, E, S, W).
- ``'diagonal'``: step to one of 8 neighbours (axial + diagonals).
- ``'levy'``: with probability ``levy_p`` step a long distance L (random
angle, length drawn from a power-law tail), otherwise take a normal
unit step (Lévy flights — Pearson *Generative Art* Ch. 3).
- ``'momentum'``: walker has a velocity vector; on each tick the step is
``v += jitter``, and ``v`` decays geometrically (drunk with inertia —
Shiffman *Nature of Code* Ch. 6 'A Smoother Perlin Walk' variant).
Walkers are kept alive when they leave the canvas (``torus=True``) or
bounce off the edges (``torus=False``). Each walker leaves a low-alpha
trail on the canvas; intensity is incremented each visit so repeatedly
visited pixels burn in.
"""
family: ClassVar[str] = "shiffman_pearson_textbook"
sketch: ClassVar[str] = "randomWalkDrunkard"
def __init__(
self,
dim: int = 400,
num_walkers: int = 400,
step_len: float = 1.0,
variant: str = "diagonal",
levy_p: float = 0.02,
levy_alpha: float = 1.5,
momentum_decay: float = 0.92,
momentum_jitter: float = 1.4,
torus: bool = True,
trail_alpha: float = 0.18,
bg_color: tuple[int, int, int] = (15, 18, 30),
ink_color: tuple[int, int, int] = (240, 220, 200),
seed: int | None = None,
) -> None:
self.dim = dim
self.num_walkers = num_walkers
self.step_len = step_len
self.variant = variant
self.levy_p = levy_p
self.levy_alpha = levy_alpha
self.momentum_decay = momentum_decay
self.momentum_jitter = momentum_jitter
self.torus = torus
self.trail_alpha = trail_alpha
self.bg_color = np.array(bg_color, dtype=np.float32)
self.ink_color = np.array(ink_color, dtype=np.float32)
self._seed = seed Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/shiffman_pearson_textbook/randomWalkDrunkard/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from shiffman · pearson
Genetic Algorithm (Evolve Toward Target String)
shiffman_pearson_textbook · geneticAlgorithmString
A textbook genetic algorithm that evolves a population of binary strings toward a target ASCII string (default 'HELLO WORLD!').
Lindenmayer L-System (Textbook Formulation)
shiffman_pearson_textbook · lindenmayerTextbook
Lindenmayer L-system string rewriting with a 2-D turtle interpreter, the canonical textbook formulation used in both Shiffman's Nature of Code Ch.
Mandelbrot Set (Escape-Time Fractal)
shiffman_pearson_textbook · mandelbrotSet
The Mandelbrot set rendered by escape-time iteration of z = z^2 + c on a window of the complex plane.
Perlin Noise Flow Field
shiffman_pearson_textbook · perlinFlowField
A 2-D scalar field of Perlin gradient noise is sampled on a coarse grid; each cell is assigned a heading theta = 2*pi * n.
Reynolds Boids (Separation / Alignment / Cohesion)
shiffman_pearson_textbook · boidsClassic
Reynolds' classic boids flocking model.
Stochastic Recursive Fractal Tree
shiffman_pearson_textbook · recursiveTree
Stack-based stochastic fractal tree from Shiffman's Nature of Code Ch.