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