poker card game revisited (code included)

Erik Max Francis max at alcyone.com
Tue Jun 7 15:09:28 EDT 2005


flupke wrote:

> i've included the code so people can take a look.
> I've tried to expand on the thread of 26/05/2005 on "Checking for a full
> house". Code is suboptimal as I coded it rather quickly.
> I've added the "normal" classes one would expect from a cardgame: card,
> deck, hand etc.
> 
> 1. I can detect most things except a straightflush. The problem with the
> code now is that it only returns 1 straight which is enough for mere
> "straight" detection but won't suffice for hand comparison and
> especially detecting straight flushes. For use in straight flush
> detection, the function would need to return all possible straights and
> then these would need to be checked to see if they are flushes.
> For instance a list [4,4,5,5,6,7,8] yields 4 different straights.
> A hand like [4,4,5,5,6,7,8,9] gets even worse.
> I can't see how i can do this using sets, i'll need to come up with
> another method since the suit is important.
> 
> 2. Hand comparison.
> For this to succeed the getrank function would need to return the exact
> 5 cards that represent the highest hand. This could be less than 5 cards
> if one uses wildcards. Then you not only have the correct rank but also
> the highest hand so you can compare in case there are ties.

It looks like you're not approaching this in a systematic manner. 
Algorithms for determining poker hands are already pretty well-known; 
there are several open source projects that do it efficiently which you 
could learn from.

When you're evaluating poker hands, you're looking for three basic types 
of card groups:  matches, straights, and flushes.  The most efficient 
way to look for matches is with a histogram based on the card rank.  Bin 
the cards up by rank, and then build a second "histogram" of the counts 
of those ranks indexing into a list of the ranks which had those cards 
(sorted by rank, so you can pull off the highest ones).  Now determining 
all the rank-based hands is easy:  quads have a hit with four matches, a 
boat has a hit with two three matches (there's no "two trips" so this is 
a boat at best) or both three and two matches, two pair has two hits 
with two matches, etc.

Searching for straights and flushes is much better done by masks. 
Arrange all the possible cards in a huge masks based on both cards and 
ranks (easy to do in Python with the long type) and then build up rank 
masks that build up all possible straight combinations (sorted by the 
highest rank so you can search them in order), and then build up card 
mask ranks for each suit.  For straights, just iterate through the 
straight rank masks and see if you find one that's fully occupied; if 
you do, that's a straight.  For flushes, just iterate through the card 
suit masks and see if you find one that has more five or more unique 
cards in it.  You need to iterate through all four and find the one with 
the highest value (for games with lots of cards, you could have two 
flushes; you want to count the highest one).  Finally, to look for 
straight flushes, first apply the suit masks and then turn it into ranks 
and apply the straight masks.

Then will all this information you can easily arrange the code to select 
the best existing hand.  Note that these all use well-established 
techniques and reveal nothing secret.

> 3. x wild.
> For games like "deuces wild", what would be the best way to manage
> those? I tought about removing them from a hand before shipping it of to
> the getrank function?

I'll leave it up to you to try to figure out how to make a wild card 
algorithm.

-- 
Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
   Love is the selfishness of two persons.
   -- Antoine de la Salle



More information about the Python-list mailing list