Three things the lab teaches
1. The house charges a little on every bet
Roulette pays as if it had 36 pockets, but it has 37: the zero. That difference means that, on average, the house keeps about 3 cents of every euro that is bet. It sounds small, but it is charged on every spin, win or lose. So what you lose in the long run does not depend on luck but on how much money goes across the table. The more you play, the more you pay. In the first chart you can see it in the dashed line that keeps going down.
Technical Expected loss = edge × total wagered
Each bet is a random variable X with expectation E[X] = −h·s, where s is the stake and h the house edge. In European roulette, betting on red: E = (18/37)·s − (19/37)·s = −s/37, so h = 1/37 ≈ 2.70%. By linearity of expectation, after n bets the expected loss is h·Σsi, whatever the order or size of the bets.
The “Average loss” tile compares the simulated mean with that theoretical value: they match up to sampling error, which shrinks as 1/√N with the number of players N.
2. Winning one day is not being ahead
In the short run luck matters far more than the house edge, which is why there are always people who win. They are the ones we hear about, the ones posting screenshots. But look at everyone at once and most are losing, and the longer the session, the fewer remain ahead. With “high-volatility” slots it is even clearer: almost everyone loses quickly while a few take huge prizes. Those few prizes make the average look less bad than it is for the typical person.
Technical Variance, median and mean
The standard deviation of the outcome grows like √n while the expected loss grows like n, so the probability of being ahead tends to zero. With highly skewed prize distributions (high volatility) the mean sits far above the median: the percentile bands tell the story better than the mean, which is sensitive to a few extreme values.
Slots are modelled as a discrete paytable scaled to an exact 96% RTP; the high-volatility version puts part of the return into 500× and 5,000× prizes with very low probabilities.
3. No system beats the house
The Martingale means doubling your bet every time you lose, so the next win recovers everything. It works many times in a row, which is why it is so tempting, until a bad streak comes along and the bet you need is more than you have or than the table allows. Then you lose everything at once. You can see it in the chart: many lines creep up and a few collapse. No system changes the underlying fact: every spin is independent of the last and the house charges on all of them.
Technical Gambler’s ruin and why systems fail
If you start with a units, bet one unit with win probability p (q = 1 − p) and stop when you reach b, the probability of going broke first is:
P(ruin) = ((q/p)^a − (q/p)^b) / (1 − (q/p)^b)With €20 at European roulette and a target of €40, that is almost 75%. The project’s tests check that the simulation reproduces this exact value. Progression systems (Martingale, D’Alembert) cannot change the expectation, by the optional stopping theorem: with negative-expectation bets and finite limits (bankroll and table maximum), any betting rule is still a supermartingale. They only reshape the outcome: many small wins in exchange for rare, large losses.
Technical How it is built
Each game is a discrete prize distribution (what each euro pays back and with what probability). The simulation uses a seeded pseudo-random generator (mulberry32), so every result is reproducible, and runs in a Web Worker so the page stays responsive. For each player we record when they go broke or walk away; from that we estimate the Kaplan–Meier survival curve, treating players who stop after reaching their target as censored. The code is in src/lib, with Vitest tests. More in Methods.