A solitaire deal needs to be unpredictable when you start it and repeatable when you want to examine it later. Those requirements fit together if the shuffle begins with a seed: a number that determines how the deck is arranged.

Cards4.net uses this approach for its solitaire games. The seed lets us recreate a deal for a replay, a daily challenge, or a bug report. What varies between modes is how we choose that number, and that choice matters when describing a deal as random or solvable.

From a number to a deck

Our shared card engine passes the seed to Erlang's exsplus pseudorandom generator, then calls Elixir's Enum.shuffle to reorder the cards. The generator produces a repeatable sequence of values, which is why the same input can give us the same shuffled deck.

To recreate a starting position, we also need the game and its variant. Klondike, FreeCell, and Spider lay out their cards differently, and Spider's suit count changes the deck itself. A seed is therefore meaningful together with those rules and the implementation that interprets it.

This repeatability applies to the current implementation. A change to the initial deck order or shuffle procedure could change the resulting deal. The seed is a useful reference for a game, but it is not a promise that any future implementation will interpret the number identically.

Where the seed comes from

For an ordinary random single-player request, the server selects a number between zero and 2^63 - 1 using Erlang's rand module. It then gives that number to the game engine. The selection does not use the player's recent wins, losses, or account history.

There is also a helper in the engine that can obtain a seed from :crypto.strong_rand_bytes. Its presence does not mean every game request uses it: the ordinary request path described above chooses its seed through rand.

That distinction matters because neither the request's generator nor the seeded exsplus shuffle should be described as cryptographically secure. Erlang's documentation explicitly distinguishes its pseudorandom generators from generators suitable for cryptography. Our implementation gives us reproducible solitaire deals; it does not provide a cryptographic fairness protocol.

How many arrangements are possible?

A deck of 52 distinct cards has 52! possible orders, roughly 8.07 × 10^67. That number counts every choice for the first card, multiplied by every remaining choice for the second, and so on.

A 63-bit seed can take only 2^63 values, roughly 9.22 × 10^18. Because each seed produces one output under a fixed implementation, it can reach at most that many deck orders, and possibly fewer if different seeds produce the same order. We cannot claim to sample every possible arrangement of a physical deck.

The smaller number is still large, but its size alone does not prove the quality of the distribution. Likewise, a few awkward deals do not establish that the shuffle is biased. A meaningful investigation needs recorded seeds, the relevant game settings, and enough results to test a specific claim.

Solvable deals use a smaller pool

Solvable mode adds a selection step before the shuffle. Offline solvers try deals and record seeds for which they find a winning path. When the relevant library is available, the server randomly selects an entry from that pool.

The resulting deal is reproducible in the same way as an ordinary one, but it comes from a filtered collection. Deals the solver could not finish are absent, even when a solution might exist. The pool is finite, so seeing a deal again is possible.

Daily challenges choose from these libraries too, using the game, variant, and UTC date to select an entry. Everyone playing that day's challenge in the same variant receives the same position. The choice is fixed for the day rather than made separately for each player.

Microsoft-numbered FreeCell deals use their own compatibility algorithm. Their numbers belong to that system; they are not interchangeable with our ordinary shuffle seeds. The deal-number guide explains how to open a particular one.

What you can check yourself

The fairness page can reconstruct starting positions for Klondike Turn 1 and Turn 3, FreeCell, and Spider's one-, two-, and four-suit variants from their public seeds. Comparing the result with the original deal checks that the seed and board agree.

That tool uses our backend. It does not independently establish how the seed was chosen, prove that a selection process was unbiased, or show that a deal is winnable. Those are separate questions.

For a suspicious deal or a bug report, keep the seed and variant alongside a description of what happened. A reproducible position gives us something to investigate. Calling a shuffle fair is much less useful unless we also explain what can actually be checked.

FAQ

Can I reproduce a Cards4.net deal?

For supported solitaire games, the same seed, variant, and shuffle implementation reproduce the same starting position. The fairness page can reconstruct that position.

What random generator does the shuffle use?

The shared card engine seeds Erlang's exsplus pseudorandom generator and calls Enum.shuffle. Ordinary single-player requests also use a pseudorandom generator to select a 63-bit seed.

Can the shuffle produce every possible deck order?

No. A fixed implementation with a 63-bit seed can produce at most 2^63 different outputs, far fewer than the 52! arrangements of a standard deck.

Does the fairness page prove that seed selection is unbiased?

No. It checks that a seed reproduces a starting position. Because it uses our backend, it is not an independent audit or proof of how the seed was selected.