Script efficiency - Poker simulations for statistics

My question is more about logic than coding itself: I am building a python script to simulate poker hands and get statistics from it. My code works very well for assigning and comparing hands, and the only bottleneck for my script is getting the best combination of cards for each player: The simulation is for omaha - each player gets 4 cards and the board has 5 cards. Each player must use the best combination of 5 cards (2 from the player's hand and 3 from the board).

The problem is: So far the only way I can think of doing this is comparing every possible hand a player can have and then compare to the other players.

For example, player A has cards A1A2A3A4 and the board is B1B2B3B4B5:

First I am comparing all possible hands player A can get: [A1A2B1B2B3, A1A2B1B2B4, A1A2B1B2B5,...,A3A4B3B4B5] and get his best hand (that's 60 combinations from each player).

Do this for all players and then check who has the winner hand.

My question is: Do you think there is a way to get each player's best hand without having to check all 60 combinations?

It took me 16 hours to run ~6.5 billion iterations (~2.5 million hands x 60 board combinations x 40 iterations per hand).

Could you also weight in about the efficiency? I don't know if I am trying something impossible to be done here =P

EDIT - SOLVED

Thanks for the inputs, guys. In the end I solved it by using bit manipulation:

https://codereview.stackexchange.com/questions/217597/forming-the-best-possible-poker-hand?noredirect=1#comment421020_217597

Upvotes: 0

Views: 180

Answers (2)

Shay
Shay

Reputation: 1499

I would not divide into 5-hard hands:

  • Use collections.Counter on the 9-card hand to check for 4k, fh, 3k, 2p, p
  • Use collections.Counter on map(fget_suit, hand) to check for flushes
  • Check for straights if you have to with Counter(x-y for x, y in zip(hand[1:], hand))

If you really want to see each player's best 5-card hand:

  • Dump the lowest 4 (if you have four) un-paired, un-suited, un-connected cards.
  • That won't solve all of it, but it will cut the problem down considerably

Upvotes: 0

Lee Daniel Crocker
Lee Daniel Crocker

Reputation: 13171

Depends on how your evaluation function works. If you just have a black-box that takes a 5-card hand and produces an evaluation, then there's not much you can do other than feed it all 60 5-card hands. But if it can be broken into pieces, it might be possible to bypass some of them.

My code in onejoker, for example, is a 5-step walk through a directed acyclic graph, so I made a special-case function for 7 cards that skips repeating some of the steps for combinations that begin with the same cards. It still ends up evaluating all 21 (7 choose 5) combinations, but in fewer than 5 * 21 steps. You could do something similar for Omaha hands.

Upvotes: 1

Related Questions