Updated: Mar 29, 2026
| 12 min

Is Sweet Bonanza 1000 Rigged? A Statistical Analysis of 60,000 Spins

We analyze 60,000 spins of Sweet Bonanza 1000 using Python, Bootstrap CI, and Hypothesis Testing to see if the 96.53% RTP holds up against extreme volatility.

Cover image for the blog series "Expected Riches and Expensive Lessons"

Introduction

Slot games advertise long-run return-to-player (RTP) percentages, often quoted with mathematical precision, such as 96.53%. Yet many players walk away from sessions feeling that the numbers cannot possibly reflect their experience.

This post applies statistical analysis to over 60,000 spins of Sweet Bonanza 1000 to investigate a simple question: Is the gap between the advertised RTP and real session outcomes a matter of deception or variance?

Rather than relying on anecdotes or forum speculation, we test concrete hypotheses using:

  • Proportion tests on dead spins
  • Conditional probability analysis of multipliers
  • Median-based inference for bonus profitability
  • Contribution analysis of extreme wins
  • Bootstrap confidence intervals for session RTP

The goal is not to prove the game is unfair, nor to defend it, but to quantify how volatility shapes player experience.

If you’ve just had a bad session, the results may surprise you.

How Sweet Bonanza 1000 Works

While visually similar to other Pragmatic “tumble” slots, Sweet Bonanza 1000 is best understood as a cluster-based stochastic process where payout magnitude depends heavily on symbol count and multiplier timing.

Cluster-Based Wins

  • Played on a 6×5 grid
  • A win occurs when 8 or more identical symbols appear
  • Location does not matter, only the number of matching symbols

Unlike line-based games, payout size grows with cluster size, creating nonlinear win scaling.

Cascading Structure

A spin is not a single event but a chain of tumbles:

  1. Winning symbols are removed
  2. New symbols drop
  3. Additional clusters may form

The spin ends only when no further clusters appear.

Statistically, each spin is therefore a sequence of dependent outcomes, not a one-step result.

Multiplier Bombs

During tumbles, multiplier symbols can land:

  • Values range up to 1000×
  • Multiple multipliers in a tumble sum together
  • The multiplier only applies if a cluster win occurs in the same tumble

Bonus Round

  • Triggered by 4+ scatter symbols
  • Award a set number of free spins
  • Retriggers (3+ scatters) extend the sequence
  • Multipliers do not persist between bonus spins; each spin is evaluated independently

Ante Bet (Double Chance)

  • Increases bet by 25%
  • Double chance to win feature (according to the game)

Why This Structure Matters

A simplified representation of a spin outcome is:

Total Win=tumbles(Cluster Valuet×Multipliert)\text{Total Win} = \sum_{tumbles} (\text{Cluster Value}_t \times \text{Multiplier}_t)

This design naturally produces:

  • Many zero-payout spins
  • Occasional large returns driven by rare combinations of large clusters and high multipliers

These properties underpin the statistical hypotheses tested in the following sections.

Data Collection & Model Assumptions

To evaluate the statistical properties of Sweet Bonanza 1000, we treat gameplay as a data-generating process and analyse spin outcomes using standard statistical methods.

Data Source

Spin data was collected from the demo version of Sweet Bonanza 1000 provided by Pragmatic Play.

  • Collection method: Python + browser automation (Selenium-based)
  • Scope: Multiple sessions of 1000 spins
  • Bet size: Constant per session of 0.20 base bet
  • Environment: Demo mode (providers state demo and live operate under the same RNG model)
ColumnDescription
round_idUnique spin identifier
betCost of the spin
winTotal payout
cascade_depthTotal number of cascades during the spin
multiplier_totalSum of multipliers landed
is_anteAnte Bet active
is_bonusSpin belongs to free spins

The Statistical Model

Spins are modelled as realisations of a random process, where each XiX_i is the payout from a single spin:

X1,X2,...,XnX_1,X_2,...,X_n

Assumptions

These are the assumptions that we use when analysing the game:

  • Independence Each spin is treated as independent of previous outcomes and drawn from the same probability distribution. The system holds no memory of past wins or losses, meaning there are no “hot” or “cold” streak mechanics.
  • Stationarity The probability distribution governing spin outcomes is assumed to remain constant during the data collection period. In practical terms, the RTP structure and volatility profile do not change mid-session.
  • High Variance, Slow Convergence Slot payout distributions are known to be heavy-tailed, consisting of many small or zero outcomes and rare extreme wins. As a result, short-term RTP can deviate substantially from theoretical values without implying bias or malfunction.

Limitations

  • Sample size is large for play but small relative to the variance of high-volatility models
  • Data comes from demo mode, assumed but not independently verified to match live settings
  • Bonus identification relies on observed game states rather than internal metadata

Results should therefore be interpreted as statistical characterisations, not definitive proof of underlying parameters.

Dead Spins Don’t Win

Claim: The majority of spins result in no payout (“dead spins”).

Let pp denote the true probability that a spin returns zero winnings.

H0:p(win=0)0.5H1:p(win=0)>0.5H_0: p(\text{win} = 0) \le 0.5 \\ H_1: p(\text{win} = 0) > 0.5

We test whether more than half of all spins are non-paying.

Test: One-sample proportion z-test, with α=0.05\alpha = 0.05

Let:

  • nn = total number of spins
  • xx = number of spins with win=0\text{win} = 0
  • p^=x/n\hat{p} = x/n

Test statistic:

z=p^0.50.5(10.5)nz = \frac{\hat{p} - 0.5}{\sqrt{\frac{0.5(1-0.5)}{n}}}

In Python:

# Z test
n = len(df[~df['is_bonus']])
x = (df['win'] == 0).sum()

p0 = 0.5

phat = x / n

z = (phat - p0) / np.sqrt(p0 * (1 - p0) / n)

p_value = 1 - stats.norm.cdf(z)

# Convidence interval
se = np.sqrt(phat * (1 - phat) / n)
ci_low = phat - 1.96 * se
ci_high = phat + 1.96 * se

Results:

Sample proportion (dead spins): 0.5674
Z-statistic: 33.035
P-value: 0.000000
95% CI for dead spin rate: (0.5635, 0.5714)

Interpretation:

With a p-value effectively equal to zero, we reject the null hypothesis that 50% or fewer spins are non-paying. The data provides overwhelming statistical evidence that the majority of spins in Sweet Bonanza 1000 return zero winnings.

Across more than 61,000 observed spins, the estimated dead spin rate is 56.7%, with a 95% confidence interval of [56.35%, 57.14%]. This narrow interval indicates that the true dead spin probability is very likely well above 50%.

In practical terms, losing spins are not an unlucky streak. They are inevitable.

RTP Is Concentrated in Rare Events

Claim: A small fraction of wins contributes most of the total return.

Let total RTP be defined as the sum of all winning spin outcomes. We examine the share of this total contributed by the largest 10% of winning spins.

H0:Top 10% of wins contribute50% of RTPH1:Top 10% of wins contribute>50% of RTPH_0: \text{Top 10\% of wins contribute} \le 50\% \text{ of RTP} \\ H_1: \text{Top 10\% of wins contribute} > 50\% \text{ of RTP}

Method: Contribution analysis over the empirical win distribution.

All winning spins (win>0\text{win} > 0) were sorted in descending order by payout size. The cumulative share of total RTP contributed by the largest 10% of wins was then computed.

Python:

# Fraction computation
wins = df[df['win'] > 0]['win']

wins_sorted = wins.sort_values(ascending=False)

total_rtp = wins_sorted.sum()

k = int(0.10 * len(wins_sorted))
top_10_rtp = wins_sorted[:k].sum()

share = top_10_rtp / total_rtp

# Plot
cum_wins = np.cumsum(wins_sorted)
cum_share = cum_wins / cum_wins.iloc[-1]

x = np.linspace(0, 1, len(cum_share))

plt.plot(x, cum_share)
plt.axvline(0.1, linestyle='--')
plt.axhline(0.5, linestyle='--')
plt.xlabel("Fraction of winning spins")
plt.ylabel("Fraction of total RTP")
plt.title("RTP Concentration Curve")

Result:

Top 10% win contribution: 73.486%

RTP concentration curve

Interpretation:

RTP in Sweet Bonanza 1000 is not generated by frequent, moderate wins, but by rare, disproportionately large outcomes. As a result, most winning spins contribute little to long-term return, while a small number of extreme events dominate observed RTP.

This structural concentration explains why short sessions often feel unrewarding despite a high advertised RTP: the expected value is locked behind infrequent tail events.

Meaningless Multipliers

Claim: Multiplier symbols frequently appear on spins that do not produce a payout.

In Sweet Bonanza 1000, multipliers only increase winnings if a cluster win occurs in the same tumble. A multiplier that appears without a qualifying win has no economic effect, despite being visually salient.

Let:

  • A = an event that at least one multiplier symbol drops
  • B = an event that the spin produces a non-zero win

We are interested in the conditional probability:

P(B | A)P(\text{B | A})

If multipliers were always meaningful, we expect this probability to be close to 1. Instead, we test whether a multiplier drop is more likely than not to result in a payout.

H0:P(win > 0 | multiplier drop)0.5H1:P(win > 0 | multiplier drop)>0.5H_0: P(\text{win > 0 | multiplier drop}) \le 0.5 \\ H_1: P(\text{win > 0 | multiplier drop}) > 0.5

Test: One-sample proportion z-test, with α=0.05\alpha = 0.05

Let:

  • nn = number of spins with at least one multiplier drop
  • xx = number of those spins that resulted in a payout
  • p^=x/n\hat{p} = x/n

Test statistic:

z=p^0.50.5(10.5)nz = \frac{\hat{p} - 0.5}{\sqrt{\frac{0.5(1-0.5)}{n}}}

In Python:

# Z test
multiplier_spins = df[(df['multiplier_total'] > 0) & (~df['is_bonus'])]

n = len(multiplier_spins)
x = (multiplier_spins['win'] > 0).sum()

p0 = 0.5

phat = x / n

z = (phat - p0) / np.sqrt(p0 * (1 - p0) / n)

p_value = 1 - stats.norm.cdf(z)

# Convidence interval
se = np.sqrt(phat * (1 - phat) / n)
ci_low = phat - 1.96 * se
ci_high = phat + 1.96 * se

Results:

Sample proportion (payout given multiplier): 0.4023
Z-statistic: -1.823
P-value: 0.965817
95% CI for dead multiplier rate: (0.2993, 0.5053)

Interpretation:

The estimated probability that a multiplier drop results in a payout is approximately 40.23%, implying that around 59.8% of multiplier appearances produce no economic effect.

The one-sided proportion test yields a p-value of 0.97, meaning we fail to reject the null hypothesis that a multiplier drop is not more likely than not to result in a payout.

In other words, there is insufficient statistical evidence to conclude that multiplier symbols meaningfully increase the likelihood of winning on a given spin.

This supports the interpretation that multipliers in Sweet Bonanza 1000 function primarily as high-variance amplifiers rather than consistent value-enhancing features: visually impactful, occasionally decisive, but frequently irrelevant.

Median Bonus < Cost of Entry

Claim: The typical bonus round is not profitable.

In the collected dataset, the total payout of a bonus round is recorded in the win field of the final bonus spin (the spin that concludes the bonus). Intermediate free spins report cumulative winnings, with the final bonus spin containing the total bonus return.

Let:

  • XX = total payout of a single bonus round
  • CC = effective cost of entering the bonus round

The cost CC is estimated empirically as the total base-game wager divided by the number of bonus rounds triggered, representing the average spend required to enter a single bonus.

We test whether the typical bonus round returns less than its cost.

H0:Median (X)CH1:Median (X)<CH_0: \text{Median (X)} \ge \text{C} \\ H_1: \text{Median (X)} < \text{C}

Test: One-sample sign test on the median, with α=0.05\alpha = 0.05

Test statistic:

Let Di=XiCD_i = X_i - C denote the difference between the payout of bonus round ii and its cost of entry. Under H0H_0, the probability that a bonus round pays less than its cost is at most 0.5. The test statistic is the number of bonus rounds with Di<0D_i<0, which follows a Binomial distribution, where nn is the number of observed bonus rounds:

NBinomial(n,0.5)N_- \sim \text{Binomial}(n, 0.5)

In Python:

def extract_final_bonus_spins(df: pd.DataFrame) -> pd.DataFrame:
    is_bonus = df['is_bonus']
    bonus_ids = (is_bonus != is_bonus.shift()).cumsum()
    bonus_sessions = df[is_bonus].groupby(bonus_ids)

    return bonus_sessions.tail(1)

bonus = extract_final_bonus_spins(df)

c = df[~df['is_bonus']]['bet'].sum() / len(bonus)

diffs = bonus['win'] - c
neg = (diffs < 0).sum()
n = len(diffs)

p_value = stats.binomtest(neg, n, p=0.5, alternative='greater').pvalue

median_payout = bonus['win'].median()

Results:

Median bonus payout: 10.41
Bonus cost: 91.60
P-value: 0.000000

Interpretation:

The median bonus payout in the sample is 10.41, while the estimated cost of entering a bonus round is 91.60. The sign test yields a p-value effectively equal to zero, indicating that the observed number of bonus rounds paying less than their entry cost is far greater than would be expected if the true median payout were at least equal to the cost.

We therefore reject H0H_0 at the 5% significance level and conclude that the typical bonus round is unprofitable. While rare, high-paying bonuses contribute disproportionately to the game’s overall RTP, the median bonus experience results in a substantial net loss relative to the amount wagered to trigger it.

This highlights the distinction between expected return and typical outcome: although the bonus feature is a major driver of RTP, it is economically unfavourable for the majority of bonus rounds.

RTP Deviations Are Statistically Plausible

Claim: A session RTP of X% is consistent with a 96.53% true RTP.

Slot outcomes exhibit extreme variance and heavy tails. As a result, short- and medium-length sessions can deviate substantially from the long-run RTP without implying any structural bias. To quantify this variability, we use bootstrap confidence intervals for session RTP.

Let:

  • WiW_i = total win on spin ii
  • BiB_i = bet amount on spin ii
  • RR = iWiiBi\frac{\sum_i W_i}{\sum_i B_i} = observed session RTP

Test: Bootstrap confidence intervals.

Rather than relying on parametric assumptions, we estimate the sampling distribution of RTP using bootstrap resampling:

  1. Resample spins with replacement from the observed session
  2. Compute RTP for each resampled dataset
  3. Repeat this process NN times (e.g. N=10,000N = 10,000)
  4. Construct a percentile-based confidence interval for RTP

This approach captures the true variance structure induced by:

  • Highly skewed payouts
  • Rare extreme wins
  • Non-normal outcome distributions

In Python:

def bootstrap_rtp(df, n_simulations=10_000):
    rtps = []
    for _ in range(n_simulations):
        sample = df.sample(frac=1, replace=True)
        rtp = sample['win'].sum() / sample['bet'].sum() * 100
        rtps.append(rtp)
    return np.array(rtps)

session_df = pd.concat([df[~df['is_bonus']], extract_final_bonus_spins(df)])

boot_rtps = bootstrap_rtp(session_df)

ci_low, ci_high = np.percentile(boot_rtps, [2.5, 97.5])
observed_rtp = session_df['win'].sum() / session_df['bet'].sum() * 100

Results:

Observed session RTP: 108.81
95% bootstrap CI for RTP: (93.99, 130.76)

Interpretation:

The observed session RTP is 108.81%, exceeding the advertised long-run RTP of 96.53%. However, the 95% bootstrap confidence interval for session RTP is:

(93.99,130.76)(93.99, 130.76)

Because 96.53% lies within this interval, the observed session outcome is statistically consistent with the true RTP. There is no evidence that the session deviates meaningfully from the game’s theoretical return.

Notably, the confidence interval is wide, spanning nearly 37 percentage points. This reflects the extreme variance of the payout distribution: rare large wins substantially influence short- and medium-length sessions. Even thousands of spins may not produce tight convergence to the long-run RTP.

Final Conclusion

Across the analyses, a consistent pattern emerges:

  1. Most spins do not pay.

    A statistically significant majority of spins return zero.

  2. RTP is concentrated in rare events.

    A small fraction of wins contributes a disproportionate share of total return.

  3. Multipliers frequently have no effect.

    A substantial portion of multiplier drops occur on non-paying spins.

  4. The median bonus round is unprofitable.

    While rare bonuses can be large, the typical bonus pays far less than its effective cost of entry.

  5. Session RTP deviations are statistically plausible.

    Even a session returning 108% is fully consistent with a true RTP of 96.53%, given the extreme variance of the payout distribution.

In high-volatility slot games, the mean is driven by rare, outsized outcomes. The median outcome, what most players actually experience, is far lower. Short and medium-length sessions can deviate dramatically from the theoretical RTP without any structural bias or manipulation.

In other words:

  • The math is real.
  • The volatility is enormous.
  • And the typical experience is not the average.

Understanding that distinction is essential, whether you’re a player interpreting your session or a data scientist modelling stochastic systems with heavy-tailed behaviour.

Disclaimer: This series is for educational and mathematical purposes only. It is not financial advice. The only winning move is to understand the math and play for entertainment, not profit.

Series: Expected Riches and Expensive Lessons

2 Chapters