Today I’m managing to combine multiple interests into one post; roleplaying, maths and programming. I’ve written a program that simulates poker hands, which I will post further down, but first a little background.

For the non-roleplayers; Deadlands Reloaded is a roleplaying game that is set in the Weird West and one of the mechanics involves drawing cards and attempting to make the best poker hand possible. The number of cards drawn increases as your character gains experience; a very experienced character, who has taken all the relevant advances (and is dead… don’t ask), can be drawing 14 cards to try and make a five card poker hand. Obviously, at any level, it’s good to have some idea of how likely you are to make a particular hand, given your number of cards.

For the non-mathematicians; these odds are actually pretty hard to calculate. The probabilities of getting each hand with just five cards are well known; anyone with a solid grasp of probability can grind out the numbers. However if you’re drawing a lot more cards, this is very difficult. For example, calculating the odds of getting two pairs from 12 cards is reasonably easy, but you’ve got to subtract the odds that you also have a straight (because that would override the two pair). Even that is not as simple as calculating the odds of a straight; specifically you’ve got to calculate the odds of getting a straight in a hand that also has two pairs. I’m sure this is not technically impossible, but it’s a lot of hassle, particularly as you have to do it separately for every hand size… and then add wildcard jokers on top.

So, at this point, the mathematician part of my brain switched off and the statistical programmer part of my brain switched on. I might not be able to calculate the exact odds, but simulating a few thousand hands would give me a pretty reasonable idea.

Now, it should be noted that, while I’ve been intending to learn Python for years, I’ve only actually been learning it for a couple of weeks. This program involved a lot of Googling and is probably not as efficient as it could be. However, I’m pretty confident that it at least works correctly (though if anyone spots any weird edge cases with the jokers, do let me know).

The program below (Dropbox link, as I can’t embed it here directly), when submitted, will ask for three pieces of information:

1) The number of hands you want to simulate – I’ve been running about 10,000 at a time, as that seems like a good balance between run time and statistical robustness.

2) The number of cards to draw – it suggests 5-14, as that is the maximum number a Deadlands character will realistically draw, but you can enter 54 and get a royal flush every time if you really want.

3) Whether the red joker is allowed – high level characters in Deadlands can use the red joker as a wildcard without blowing themselves up… and not blowing up is always preferable.

https://www.dropbox.com/s/6pypgxy6zzfv5si/Huckster.py?dl=0

Feel free to use this program in whatever way you want, though if you post it anywhere else online, do me the courtesy of crediting me.

If any more experienced Python programmers want to suggest code improvements, I’m all ears. In particular, does anyone know if I really need to make the variables global to pass them from function to function? It seems inelegant, but I couldn’t get it to work otherwise.

Cool program! I like how you handed checking for poker hands!

Yes! That is very cool indeed!

I made the mistake of reading this before work and now I’m going to struggle to not think about it all day.

Passing values from function to function is made easier when you define output to a functions with “return X” at the end, so that’s defined as the output (whatever sort of thing X might be) and you can assign that to a variable, which could be passed into another variable later on.

eg

def double(x):

y=x*2

return y

z=3

print(double(z))

should print 6.

—

With a project like this, i would even plan out all the functions and how they interact before actually starting to write how they work.

This was a hefty nerd snipe and no mistake!

I did look at ‘return’, but I couldn’t quite see (a) how it would work returning multiple variables (e.g. Collate function, which returns values, suits and order) and how it would handle being constantly iterated on the same variables (e.g. Draw function, which inputs hand and pack and then outputs them again, over and over).

Absolute easiest thing to do is group the output together into a single object, eg:

return [values, suits, order]

and unpack that with whatever you feed it to, eg:

y=aMadeUpFunction(x)

z=anotherMadeUpFunction( y[0] )

w=yetAnanotherMadeUpFunction( y[1] )

etc etc,

Other cleverer options abound but that’s the easiest way I can think of