"I lost seven in a row. This game is rigged."
We've seen this complaint. We understand it. Seven consecutive losses feels like more than bad luck — it feels like the game is working against you. And when you're playing on a website you don't control, with a shuffle algorithm you can't inspect, that suspicion is reasonable. You're trusting us to deal fairly, and trust without transparency is just faith.
So let's be transparent. This post explains exactly how we shuffle cards, why we made the choices we did, how you can verify the fairness yourself, and what "rigged" would actually have to mean for the complaint to be true.
Quick Answer
Cards4.net deals are seed-based. A seed is a 63-bit integer; with the same game, variant, and seed, the same initial deal is produced every time. That makes deals reproducible, which is the foundation for our fairness verification page.
For seeded single-player deals, the card engine uses Erlang's :rand module with the :exsplus algorithm. For casual random games, the seed is generated with :crypto.strong_rand_bytes/1. For daily challenges and solvable mode, seeds come from pre-validated libraries of deals where our offline solver found a winning path.
The RNG We Use
A shuffle algorithm needs a source of randomness. In practice, computers don't generate true randomness — they generate pseudorandom numbers using a deterministic algorithm seeded with some initial value. The quality of the randomness depends on two things: the algorithm and the seed.
Cards4.net routes card-engine randomness through a small wrapper module, Cards4.Games.Engine.Rand. Seeded shuffles use Erlang's :rand module with the :exsplus algorithm. The seed is a non-negative 63-bit integer, split into the three integers Erlang expects for seeded random state.
Random seed creation uses :crypto.strong_rand_bytes/1 to produce 63 bits of seed material. From there, the seeded game engine is deterministic: the same seed and variant produce the same deck order.
That deterministic property matters more than the brand name of the random generator. It lets us support replay, daily challenge consistency, solvable seed libraries, and the public fairness verifier.
The shuffle itself is handled by the platform's shuffle implementation after seeding the random state. For our purposes, the important product guarantee is reproducibility: a seed is not a vague label attached after the fact; it is the input used to produce the deal.
Seed format. The app displays seeds as 13-character Crockford Base32 strings on the fairness surface. This keeps the seed compact while avoiding visually ambiguous characters.
Seed Verification
Claiming the shuffle is fair is easy. Making it inspectable is more useful.
Every supported single-player deal can be reconstructed from three pieces of information: the game, the variant, and the seed. The fairness page exposes that reconstruction flow. Paste a seed, choose a game and variant, and the server initializes the same game state from that seed.
The verifier is intentionally read-only and limited to the solitaire games where seed reconstruction is part of the public product: Klondike Turn 1, Klondike Turn 3, FreeCell, and Spider 1-, 2-, and 4-suit.
What verification proves. It proves that a displayed seed maps to a specific deal under the live game engine. It also lets players and developers reproduce daily challenge deals and investigate bug reports without relying on screenshots.
What verification does not claim. Cards4.net does not currently present a cryptographic commit-reveal hash before each game. We should be precise about that. The fairness system is a reproducibility and transparency tool, not a casino-style provably-fair wagering protocol.
The seed library. For daily challenges and solvable mode, we use pre-validated seed libraries. Each library is a flat binary list of seeds for a game and variant. At runtime the app can choose a random seed from that library or derive a deterministic daily seed index from the date.
That approach is deliberately practical: it gives players winnable daily puzzles, makes challenges repeatable, and keeps the deal-generation code small enough to reason about.
Solvable Mode and Trade-offs
Solvable mode is a toggle that draws from a pre-verified seed library when a library exists for the selected game and variant. If no suitable library exists, the app falls back to normal random deal generation rather than pretending a guarantee exists.
The trade-off is worth being explicit about. Solvable mode changes the distribution of deals you receive. Instead of sampling from the full seed space, you're sampling from the subset of checked seeds where the solver found a winning line.
This means solvable mode is not the same as "random." The deals are still random within the winnable subset, but the full distribution of all possible deals is not represented. If you care about experiencing the full range of possible deals — including unwinnable ones — you should turn solvable mode off.
We're transparent about this trade-off because we think players deserve to understand what they're getting. Solvable mode is a kindness, not a deception. It removes the frustration of losing to an unwinnable deal. But it does change the statistical properties of the deals you receive, and you should know that.
Does solvable mode make the game easier? Not in any meaningful sense. A solvable deal is still hard to win. The solver's guarantee that a winning line exists doesn't tell you what that line is. You still have to find it yourself.
The seed library size. Seed libraries are finite checked-in .bin files. The format is simple: one 8-byte unsigned seed per entry. That keeps the runtime code fast and predictable, and it makes library size easy to audit from the repository.
Common Misconceptions
"The game deals me bad cards on purpose."
It doesn't. There is no mechanism that tracks your recent results and adjusts the deal accordingly. The shuffle code doesn't know or care whether you won your last seven games. Each newly generated casual deal starts from a fresh seed, and solvable-mode deals are selected from a seed library rather than from your win/loss history.
The feeling that you're getting bad cards is real, but it's a cognitive bias called the gambler's fallacy in reverse — the expectation that recent bad luck should be "corrected" by future good luck. Randomness doesn't work that way. Seven losses in a row is unlikely but not impossible, and it doesn't make an eighth loss any less likely.
"The site makes money when I lose, so it has an incentive to rig the shuffle."
Cards4.net is ad-free and has no in-app purchases. We don't make money when you lose. There's no financial incentive to rig the shuffle, and the public seed verifier gives players a concrete way to inspect supported solitaire deals.
"The shuffle looks random but the face-down cards are always bad."
In Klondike, the face-down cards are part of the same deck order as the face-up cards. There's no separate algorithm for face-down cards. The deck is generated once from the seed and then dealt; the face-down cards are simply the cards that land in those positions.
"I've seen the same deal twice."
Possible but extremely unlikely. There are 52! possible Klondike deals — roughly 8 × 10^67. The probability of seeing the same deal twice in a lifetime of play is essentially zero. If you think you've seen the same deal twice, you're probably misremembering a similar-looking deal. The opening positions of many Klondike deals look alike because the visible cards are a small fraction of the total.
"Other solitaire sites have better win rates."
Win rates vary by game type, variant, and whether solvable mode is enabled. If another site claims a higher win rate, they might be using solvable mode by default, or they might be using a different game variant, or they might be measuring win rate differently. We publish our win rate statistics openly — you can compare them directly.
FAQ
Q: Can I verify that a specific game was dealt fairly?
Yes, for supported solitaire games. The fairness page lets you enter the game, variant, and seed, then reconstructs the initial deal server-side using the same game engine. This verifies that a seed maps to the deal the app says it maps to.
Q: What would "rigged" actually mean in practice?
In practice it would mean the deal generator was choosing seeds based on who you are, your recent results, or a desired outcome instead of using the normal random seed or seed-library path. The code has no such branch. A deal is created from a seed, and the verifier can reconstruct supported solitaire deals from that seed.
Q: Why use a PRNG at all? Why not true randomness?
Random seed material is used to create the integer seed, but the shuffle itself must be deterministic once the seed is known. That is what makes replay, daily challenges, bug reports, and fairness verification possible. If every card position came directly from non-reproducible hardware randomness, there would be no simple way to reconstruct a deal later.
Q: Does the solvable-mode seed library ever run out?
The library is finite, but it is selected from randomly rather than consumed like a queue. That means it does not "run out" during normal play. New libraries can be regenerated offline with the solver tooling when we want broader coverage for a game or variant.
Q: How do I turn solvable mode on or off?
The solvable mode toggle is in the game settings panel, accessible from the game page. The setting is per-game-type and persists across sessions. Turning it off means you'll receive deals from the full random pool, including unwinnable ones. Turning it on means you'll only receive deals from the pre-verified winnable library.