4

there is a poker-system in java, that uses Collections.shuffle() on all available cards before the cards are dealt.

So a collection of 52 cards 2-9, J, Q, K, A in 4 types.

After that we Collections.shuffle().

The problem is, that it seems (until now we didn't have big statistic, it's possible that we only see a lot of statistic inferences), that the algorithm is VERY unclearly.

So, is Collections.shuffle() okay for a poker algorithm?


Answers to comments: With "unclearly" I mean it's very very mysteriq at some time. Much User complain about "it's not the same as live / other pokerrooms". I played a much with this system and must say, I agree, I see 3 Royal Flashs in under 2000 played hands in this system and live/in other pokerrooms with over 100.000 played hands I see 2 until today.

PassionateDeveloper
  • 14,558
  • 34
  • 107
  • 176
  • 1
    I don't understand your question; what is unclear about the algorithm? – Pops Apr 26 '10 at 17:23
  • 2
    If you're going to put money on it, I'd suggest `SecureRandom` with a good seed. (And perhaps consider paid support.) – Tom Hawtin - tackline Apr 26 '10 at 17:24
  • After your update, I think the other answerers have mostly covered it; I also found this SO question useful: http://stackoverflow.com/questions/2449594/how-does-a-cryptographically-secure-random-number-generator-work – Pops Apr 26 '10 at 17:46
  • 4
    You need to separate out the shuffling *algorithm* and the *random number generator*. The Collections.shuffle() algorithm is completely fair in a hypothetical situation where it is used with a completely random RNG. Note that (a) real card shuffles are not completely random; (b) Java's Random algorithm is not terribly good, though SecureRandom may be good enough for your purposes. – Neil Coffey Apr 26 '10 at 17:59

7 Answers7

9

If this is a serious poker application, where money can change hands, the short answer is NO. For something like this, you should really use a hardware source of true randomness.

The slightly longer answer is: if you can't get hardware for doing true randomness, Collections.shuffle(List, Random) might be good enough if you supply a SecureRandom. The tricky part with this solution is finding a good seed value.

UPDATE: Based on your clarification, I'd suggest you look into how you're seeding the PRNG (assuming you're already using a cryptographically secure implementation; if not, do that first). You should not be using a limited set of seeds. Other things to consider:

  • you should probably instantiate a single PRNG for each game
  • you should only be shuffling the deck between hands; from your question, it's not 100% clear that you aren't also shuffling the deck between the flop, turn, river, etc.
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • N.B. Just going purely from memory, I have a feeling that in the US regulations stipulate a RNG with a period greater than 2^160, so that SecureRandom *woudln't* be sufficient. I stress I could be misremembering though. – Neil Coffey Apr 26 '10 at 17:55
  • I'm pretty sure you can install more secure PRNGs and then ask for it by name using [`SecureRandom.getInstance(String)`](http://java.sun.com/javase/6/docs/api/java/security/SecureRandom.html#getInstance(java.lang.String)). – Hank Gay Apr 26 '10 at 18:02
  • @HankGay I know, that is an old answer, but it bugs me: why not shuffle the deck before flop, turn, river? I can see the reason in real life game, but why with eg. online game? – omicronns Sep 01 '23 at 10:20
6

The Collection.shuffle uses the O(n) implementation of the Fisher-Yates shuffling algorithm.

And the random indexes are chosen with the normal PRNG of Java, so it will be approximately uniform: every shuffle of the deck will be as much probable as every other one.

This is quite ok for what you want to do, but when you want real randomization you should introduce some real random factors (like System.currentTimeMillis() used to seed the random number generator) or something more realiable like a specialized hardware.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 2
    Of course, you need to seed it with something much better than System.currentTimeMillis() -- see http://www.javamex.com/tutorials/random_numbers/entropy_sources.shtml – Neil Coffey Apr 26 '10 at 17:51
4

Ok, I generally hate people saying this to me but yes and no. It's about as ok as pickrandomcardbetween(1, 52) and use a rand() function when it comes to randomness.

The no part is that for anything that deals with chance or random values you need proper hardware, a normal computer cannot even remotely generate a truly random result of any kind.

Edit: If your pokersystem is for playing for fun it's one thing, but when money is involved people will hang you for creating random results that way.

Jonas B
  • 2,351
  • 2
  • 18
  • 26
4

I suggest reading this article:

How We Learned to Cheat at Online Poker

The authors looked at one software package and found several flaws. One serious problem was the seed. If you start with a 32-bit seed (and don't generate a new independent seed during the shuffle), you can only generate 2^32 different random sequences. There are 2^226 possible shuffles of a 52 card deck, which means only a small fraction of possible deck orderings will be produced.

A player knows 5 of the card positions (7 in Omaha) at the flop. If the player knows the shuffle algorithm he can guess what the candidate seeds were based on the cards he sees. This gives him a big advantage in deducing the probabilities of what the hidden cards are.

justkevin
  • 3,089
  • 3
  • 28
  • 33
  • Nice article, though there's really no reason to not to use a rather large seed which is nicely mixed on a regularly basis. It's difficult to design a hashing operation for a small seed which can capture all the entropy that may be present in a randomness source. It's easier to capture entropy into a larger seed. – supercat Mar 22 '11 at 23:22
2

If this is serious poker software involving money, then the answer would be no. (For this, you would want some source of true randomness.) However, for simple circumstances, it is just about as good a solution as any other algorithm.

If you want more information about the shuffle algorithm itself, see Java's Collections.shuffle is doing what?.

Community
  • 1
  • 1
Justin Ardini
  • 9,768
  • 2
  • 39
  • 46
0

I can tell you that this is not how the large poker sites do it. Pre-shuffling the deck makes the card sequence available in memory in the game server somewhere, i.e. it is possible to read it if you have access to the server host (like ops have). Instead cards are randomly picked from the deck whenever they are needed (using secure random on top of hardware RNG). This screws up your mind sometimes when you get the "wrong" community cards, because if you just had waited a millisecond longer to call they had been different :)

Jonas Bergström
  • 741
  • 6
  • 15
0

The problem is that the numbers generated by random are statistically random. It means that shuffle do not behave like a deck of cards because it is more random than a real life deck shuffle. To have something more realistic you need to simulate the way you shuffle the cards in real life, like how many times you cut and so on. I saw a site with a chart comparing the results of a real dice and computer generated results that showed how different the results were. The computer results were more equally distributed, but I can't seem to find the link on google.

Beothorn
  • 1,289
  • 10
  • 19