🛝Toolio
About Contact

🪜 Ladder Game (Amidakuji)

Click Draw ladder and the tool lays out one vertical line per player, then scatters horizontal rungs across a fixed 12 rows using Math.random(). Because every rung only ever swaps two neighboring lines, and no two rungs on the same row are ever allowed to touch, the whole ladder is mathematically guaranteed to match every player to exactly one outcome — nobody doubles up, no matter where the rungs happen to land. Tap a name afterward and the canvas redraws the same ladder with that player's route lit up, so you watch the decision trace out step by step instead of just being handed the answer.

Ladder Game generates a random amidakuji (ghost-leg) lottery ladder in your browser, using JavaScript's Math.random() to place the rungs and the HTML Canvas API to draw and animate each player's path down to a distinct outcome.

Tap a name to trace its path.

Private by design. This tool runs entirely in your browser — nothing you enter is uploaded or stored, and it works offline.

About

The fairness claim here isn't marketing — it falls directly out of how the rungs are placed. Each of the 12 rows is built by walking across every pair of neighboring lines and rolling Math.random() < 0.45 for a rung, but the code explicitly skips a slot if the one to its left just got a rung ("!(i > 0 && row[i-1])"). That single guard means no row can ever contain two overlapping swaps, so every row is, on its own, a clean set of non-overlapping swaps — a permutation of the columns. Stacking twelve of those on top of each other is just composing twelve permutations in a row, and a composition of permutations is always itself a permutation. That's why two players landing on the same outcome is not just unlikely here, it's structurally impossible, regardless of how the random rolls come out.

What that guarantee does not cover is how *evenly* the results spread across all possible pairings. The ladder always uses the same 12 rows no matter how many players you type in — the source has that as a fixed constant, not something that scales with your player count. For the 3-to-10 player range the tool is tuned for, 12 rows of independent 45%-probability rolls give plenty of crossings to feel like a genuine shuffle. Push it to 30 or 50 names, though, and 12 rows simply isn't enough crossings to reach anywhere near all of that many possible pairings with equal odds — people are more likely to land close to the column they started in than a truly uniform shuffle would produce. If you need a fair random match for a big group, a flat randomizer is the better mathematical tool than a ladder capped at a dozen rows.

It's also worth being direct about what Math.random() is and isn't. It's the browser's built-in pseudorandom generator — fast, good enough to decide who does the dishes, and not something a participant can typically influence from outside the page. But it is not cryptographically secure: its internal state is, in principle, predictable if someone can observe enough of its output or knows the engine's algorithm, which is why real-money raffles, licensed lotteries, and anything with legal stakes use crypto.getRandomValues() or an audited, certified RNG instead. This tool doesn't reach for either of those, and it doesn't need to for splitting chores or picking who buys coffee — just don't put actual prize money behind it.

On the interaction side: "Draw ladder" runs the whole rung-placement routine fresh, so every click is an independent draw with no memory of the last one. "Reveal all" skips the tap-one-name-at-a-time reveal and prints every player-to-outcome pairing on the same ladder in one go. There's no built-in save, export, or share button in this build — the ladder exists only as pixels on the canvas element, and reloading the page wipes it along with the two text boxes, which reset back to the sample names and prizes. If you want a record of a result, the only route is your browser or device's native screenshot tool before you navigate away. Everything else about the tool is exactly as advertised: it runs entirely client-side with no network requests once the page has loaded, so nothing you type is ever uploaded, and it keeps working with no connection at all.

How to use

  1. Type each player's name into the Players box, one name per line — the sample names (Amy, Ben, Cara, Dan) just show the format and can be replaced entirely.
  2. Type the matching outcomes into the Outcomes box, one per line — the tool will refuse to draw and show an error if the two lists don't have the same number of lines.
  3. Click "Draw ladder" to run a fresh round of Math.random() calls and reveal a brand-new set of rungs on the canvas — every click is an independent draw.
  4. Tap or click any player's name chip above the ladder to animate their single path in the accent color from top to bottom and reveal their matched outcome underneath.
  5. Click "Reveal all" instead if you'd rather skip the one-at-a-time reveal and see every player-to-outcome pairing printed at once on the same ladder.

FAQ

Does the ladder use a truly random, unpredictable number generator?
It uses the browser's built-in Math.random(), not the cryptographically secure crypto.getRandomValues(). That's completely fine for splitting chores or deciding who buys coffee, but Math.random()'s internal state is, in principle, not immune to prediction if someone can observe enough prior output. Don't use this tool — or any Math.random()-based ladder — to run a raffle involving real money, prizes with legal weight, or any situation where a participant has an incentive to reverse-engineer the draw.
Is the outcome mapping really one-to-one, or could two players end up with the same prize?
One-to-one is guaranteed by construction, not by luck. Every rung only connects two neighboring lines, and the code explicitly refuses to place two overlapping rungs in the same row. That makes each row of the ladder its own small, non-overlapping shuffle, and stacking twelve of those shuffles can never point two starting lines at the same ending line — the assignment is a mathematical bijection no matter how the random rolls land.
Is the ladder still fair once I add a lot of players?
This is the honest limit: the ladder always uses a fixed 12 rows, regardless of player count. With the 3-to-10 players this tool is built for, that's plenty of crossings to feel like a fair shuffle. Enter 30 or 50 names, though, and 12 rows can't produce anywhere near enough crossings to spread outcomes evenly across that many possible pairings — players tend to land closer to their starting position than a truly uniform shuffle would. For a big group, a flat random-assignment tool is the better fit than a ladder capped at 12 rows.
Can I save or share my finished ladder?
Not through the tool itself — there's no built-in save, download, or share button in this build. The ladder exists only as pixels drawn on the canvas element while the page is open. If you want proof of the result (the classic "screenshot to settle the argument"), use your browser's or device's own screenshot function before you refresh the page — reloading resets the canvas and both text boxes back to the sample data.
Does this tool upload anything, and does it work without internet?
No uploads, and yes to offline. Rung placement, canvas drawing, and path tracing all run inside your browser's JavaScript engine with zero network requests, so the tool keeps working after the page has loaded even with no connection at all, and the names and outcomes you type never leave your device.