An engineer ships a sliding-tile puzzle on Friday. Tuesday, the support inbox has 14 tickets that all say some version of: “I've been trying for 40 minutes and this puzzle is impossible.” The engineer opens the devtools, reloads the page, and starts playing. They can't solve it either. Not in 10 minutes. Reload — a new scramble, also unsolvable. Reload again — solvable this time. Reload — unsolvable. Half the time, something is deeply wrong.
The scramble is just shuffle([1,2,3,4,5,6,7,8,0]) — uniform random permutation. Tap “reroll” below enough times and you'll feel what the engineer felt: some boards snap into goal in a dozen moves; others bounce off every legal slide you try. There's no warning, no indicator. The widget is silently half-broken.
// The flat version every first-pass ships.// No adjacency; no parity check. Just shuffle and hope.function SquareGameBroken() { const [tiles, setTiles] = useState(() => shuffle([1,2,3,4,5,6,7,8,0])); const onTileClick = (idx) => { // Lets you swap ANY tile with ANY other — not a real puzzle. const next = [...tiles]; const emptyIdx = tiles.indexOf(0); [next[idx], next[emptyIdx]] = [next[emptyIdx], next[idx]]; setTiles(next); }; return ( <div className="grid grid-cols-3"> {tiles.map((t, i) => ( <button key={i} onClick={() => onTileClick(i)}> {t === 0 ? '' : t} </button> ))} </div> );}// What breaks:// 1. Any tile is "swappable" — no adjacency constraint. Click the// top-left while empty is bottom-right and they teleport. That's// not a sliding puzzle.// 2. The scramble is uniform-random. Half of 9! permutations are// unreachable from goal. The user grinds 40 minutes on a board// that physically CANNOT reach goal and quits.// 3. No win detection. The user solves it (if lucky) and nothing// happens — no confetti, no plaque, no "you win".Tap “Reroll scramble” a few times. Try to eyeball: can I see a few moves toward goal? Some you can; some you can't. When you've felt the pattern, advance to the question.