How to Build a Spin Wheel That's Actually Fair
Description and use
The developer built WheelySpin, employing crypto.getRandomValues() with rejection sampling and Fisher‑Yates shuffle to eliminate modulo bias. The winner is chosen before animation, ensuring equal odds for all wheel slices, verified by a chi‑square test.
Problem
Spin wheels often appear rigged because of common JavaScript mistakes that introduce bias.
Outcome
The wheel achieves statistically uniform odds, confirmed by chi‑square tests with p‑values around 0.69 for 100,000 spins.
Workflow
- Use crypto.getRandomValues() to generate a 32‑bit integer.
- Apply rejection sampling to remove modulo bias.
- Select winner with randomInt(entries.length).
- Shuffle entries with Fisher‑Yates using randomInt.
- Determine target rotation for the chosen slice.
- Animate wheel to that rotation.
- Run chi‑square test to verify fairness.
Evidence
Math.random() is fine for confetti. It isn't designed for anything where someone might care about the result:
const winner = randomInt(entries.length); // the decision happens here
const limit = RANGE - (RANGE % n);
[20044, 19882, 19929, 20156, 19989] { chi2: 2.27, df: 4, p: 0.69 }
- Record date: 2026-10-17T08:56:05.649Z