Results 1 to 23 of 23

Thread: Poker Hand Evaluator

  1. #1

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Poker Hand Evaluator

    After reading about how poker hands are evaluated, I decided to have a go at it. Before I proceeded further I wanted to solicit opinions for what I have done so far.

    Code:
    
    
    edit - For now I am not worried about the return, but thoughts on how the Hand Ranking is returned is appreciated.

    edit - Removed code
    Last edited by dbasnett; Jan 28th, 2010 at 09:46 AM. Reason: Remove code
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  2. #2

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    So the code has changed a lot. In pseudo code it now looks like this:

    Check for Straight and Straight Flush

    If Not Straight Flush Check for Flush

    If Not Flush and Not Straight Check 4 of a Kind

    If Not 4 of a Kind Mark Pairs and Trips Checking for Full House

    end pseudo code

    I have changed the order of checking numerous times, and I think this is best. The only thing I can think of, that might perform better is to check for full house first. But after days of thinking about it, I am not sure that I am thinking... Maybe over-thinking?

    Two hands follow

    Hand - 1
    2 clubs
    2 hearts
    3 clubs
    3 hearts
    4 clubs
    5 clubs
    6 clubs

    Hand - 2
    2 clubs
    2 hearts
    3 clubs
    3 hearts
    3 diamonds
    5 clubs
    6 clubs
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  3. #3
    Frenzied Member
    Join Date
    Jul 2006
    Location
    MI
    Posts
    2,012

    Re: Poker Hand Evaluator

    Are you just trying to compare two or more hands to see which one is the highest? Why does it matter which order you check for each type of hand?

  4. #4
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Poker Hand Evaluator

    You need to check hands in order to determine the highest hand condition is recognized. For example, if you have a 4 of a kind, the check for a 3 of a kind and a pair are also true.

    You can split some conditions up, like the test for Flush, because if Flush = True, then you proceed to check for Straight. Throw in a high-card check and you can then determine between a Flush, Straight, Straight-Flush and Royal Flush. I'll dig up my evaluator function and post it for comparison.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  5. #5

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    Quote Originally Posted by nbrege View Post
    Are you just trying to compare two or more hands to see which one is the highest? Why does it matter which order you check for each type of hand?
    The order can eliminate certain possibilities. For example, if you have a full house, you can't have straight or flush.

    The performance of the hand evaluator is dependent on the order. Right now I am around 0.00003 seconds per hand on my 1.8GHz laptop.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  6. #6
    Frenzied Member
    Join Date
    Jul 2006
    Location
    MI
    Posts
    2,012

    Re: Poker Hand Evaluator

    I disagree that the order is important, but it all depends on how you code it. A flush beats a straight regardless of which one you check for first. If you're concerned about order then why not just check each hand in the same order as the rankings? ie. check for 1 pair, then 2 pair, then 3 of a kind, etc. Also, how are you ranking hands of the same type? ie. two flushes.
    Last edited by nbrege; Jan 28th, 2010 at 12:22 PM.

  7. #7

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    Quote Originally Posted by nbrege View Post
    I disagree that the order is important, but it all depends on how you code it. A flush beats a straight regardless of which one you check for first. If you're concerned about order then why not just check each hand in the same order as the rankings? ie. check for 1 pair, then 2 pair, then 3 of a kind, etc. Also, how are you ranking hands of the same type? ie. two flushes.
    Maybe my whole approach is wrong, but the order does make a big difference in what I have done so far. A pair, two pair, and three of a kind, don't eliminate other checks.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  8. #8
    Frenzied Member
    Join Date
    Jul 2006
    Location
    MI
    Posts
    2,012

    Re: Poker Hand Evaluator

    Well, then check in reverse order ... straight flush, four of a kind, full house, etc. Whenever you find a match, you eliminate all the lesser ranked hands. What exactly is your end goal?

  9. #9
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Poker Hand Evaluator

    Have you had a look at an algorithm for it?

    http://nsayer.blogspot.com/2007/07/a...ker-hands.html

  10. #10

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    I saw that. It didn't tell me much. I was only asking if the approach I posted made sense and seemed efficient.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  11. #11
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Poker Hand Evaluator

    Funny, I implemented something extremely similar to that algorithm when I made mine. I never fully tested it but it seemed to work well enough.

    Here's my "Hand" object. Notice the very slick GetHandRank function.

    Code:
    Public Class Hand
        Inherits List(Of Card)
        Implements ICloneable
    
        Public Function GetBestHand() As HandRank
            Dim listHands As List(Of HandRank) = Me.CheckHand
            Dim bestHands = From hr In listHands Where hr.Rank = listHands.Max(Function(hr2 As HandRank) hr2.Rank)
            Return (From hr In bestHands Where hr.Highcard.Rank = bestHands.Max(Function(hr2 As HandRank) hr2.Highcard.Rank)).FirstOrDefault
        End Function
    
        Private Function CheckHand() As List(Of HandRank)
            Dim hl As New List(Of HandRank)
            If Me.Count > 5 Then
                For Each c In Me
                    Dim h2 As Hand = DirectCast(Me.Clone, Hand)
                    h2.Remove(c)
                    hl.AddRange(h2.CheckHand.ToArray)
                Next
            Else
                hl.Add(New HandRank With {.Rank = Me.GetHandRank, .Highcard = Me.GetHighCard})
                Return hl
            End If
            Return hl
        End Function
    
        Private Function GetHandRank() As HandRankType
            Dim hist = Me.GroupBy(Function(c) New With {Key c.Rank}).Select(Function(CardCount) CardCount.Count)
            If hist.Contains(4) Then Return HandRankType.FourOfAKind
            If hist.Contains(3) AndAlso hist.Contains(2) Then Return HandRankType.FullHouse
            If hist.Contains(3) AndAlso hist.Count = 3 Then Return HandRankType.ThreeOfAKind
            If hist.Contains(2) AndAlso hist.Count = 3 Then Return HandRankType.TwoPair
            If hist.Count = 4 Then Return HandRankType.OnePair
    
            Dim booFlush As Boolean = Me.GroupBy(Function(c) New With {Key c.Suite}).Count = 1
            Dim booStraight As Boolean = Me.Max(Function(c As Card) c.Rank) - Me.Min(Function(c As Card) c.Rank) = 4
            Dim booAceHigh As Boolean = Me.Max(Function(c As Card) c.Rank) = CardRank.Ace
    
            If booAceHigh AndAlso booStraight AndAlso booFlush Then Return HandRankType.RoyalFlush
            If booFlush AndAlso booStraight Then Return HandRankType.StraightFlush
            If booFlush Then Return HandRankType.Flush
            If booStraight Then Return HandRankType.Straight
    
            Return HandRankType.HighCard
        End Function
    
        Private Function GetHighCard() As Card
            Return (From c In Me Where c.Rank = Me.Max(Function(c2 As Card) c2.Rank) Select c).FirstOrDefault
        End Function
    
        Public Function Clone() As Object Implements System.ICloneable.Clone
            Dim newHand As New Hand
            newHand.AddRange(Me.ToArray)
            Return newHand
        End Function
    End Class
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  12. #12
    Master Of Orion ForumAccount's Avatar
    Join Date
    Jan 2009
    Location
    Canada
    Posts
    2,802

    Re: Poker Hand Evaluator

    This is pretty close to yours:

    Check - Straight
    Check - Flush
    If Both True Done

    Check - Four Of A Kind
    If True Done

    Check - Full House
    If True Done

    If Flush Was True Done

    If Straight Was True Done

    Check - Three Of A Kind
    If True Done

    Check - Two Pair
    If True Done

    Check - Pair
    If True Done

    If None True Then
    Result Is High Card

  13. #13
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Poker Hand Evaluator

    Here, these are the little support/data classes and enums for the above post just so you don't have to reverse engineer it from the above.

    Code:
    Public Module Enums
        Public Enum CardSuite
            Spade = 4
            Heart = 3
            Club = 2
            Diamond = 1
        End Enum
    
        Public Enum HandRankType
            RoyalFlush = 10
            StraightFlush = 9
            FourOfAKind = 8
            FullHouse = 7
            Flush = 6
            Straight = 5
            ThreeOfAKind = 4
            TwoPair = 3
            OnePair = 2
            HighCard = 1
        End Enum
    
        Public Enum CardRank
            Ace = 13
            King = 12
            Queen = 11
            Jack = 10
            Ten = 9
            Nine = 8
            Eight = 7
            Seven = 6
            Six = 5
            Five = 4
            Four = 3
            Three = 2
            Deuce = 1
        End Enum
    
    End Module
    
    Public Class HandRank
        Public Rank As HandRankType
        Public Highcard As Card
    End Class
    
    Public Class Card
        Public Suite As CardSuite
        Public Rank As CardRank
    End Class
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  14. #14

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    @Jenner - Thanks. It will take me some time to digest that. It is certainly prettier than my code.

    Have you tested it for time? In my test rig I only time the code in the hand evaluation. As I posted earlier I am around 0.00003 seconds per hand on my 1.8GHz laptop. I still need to add tie breakers for straight flush, straight, flush, two pair, pair, and high card.

    note - I am testing 7 card hands, with ace being high and low.

    I also added a singleton count. When I did it with LINQ I took a performance hit, but when I iterated throught the array manually I saw a slight increase in performance.
    Last edited by dbasnett; Jan 28th, 2010 at 04:55 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  15. #15
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Poker Hand Evaluator

    Let me convert it for ace high and low. I assume low ace is only used for evaluation of straights? Last I tested it, it was monster-fast. I don't have your code or your rig, so any number I get on my end wouldn't be a good comparison.

    EDIT: Using the diagnostics.stopwatch I'm getting a fairly consistent 0.0000185 sec/hand on my rig which is a Core 2 Duo E8400 @ 3.00Ghz. I'm not checking for low-ace though.

    EDIT #2: Altered the function to check for the wheel (ace low-straight). Time decreased to about 0.0000181 sec/hand from just sorting it once and using their indexes to figure straights. GetHandRank function now looks like this:

    Code:
        Private Function GetHandRank() As HandRankType
            Dim hist = Me.GroupBy(Function(c) New With {Key c.Rank}).Select(Function(CardCount) CardCount.Count)
            If hist.Contains(4) Then Return HandRankType.FourOfAKind
            If hist.Contains(3) AndAlso hist.Contains(2) Then Return HandRankType.FullHouse
            If hist.Contains(3) AndAlso hist.Count = 3 Then Return HandRankType.ThreeOfAKind
            If hist.Contains(2) AndAlso hist.Count = 3 Then Return HandRankType.TwoPair
            If hist.Count = 4 Then Return HandRankType.OnePair
    
            Me.Sort(New Comparison(Of Card)(Function(c1 As Card, c2 As Card) If(c1.Rank > c2.Rank, 1, If(c1.Rank < c2.Rank, -1, 0))))
            Dim booAceHigh As Boolean = Me(4).Rank = CardRank.Ace
            Dim booCheckWheel As Boolean = Me(3).Rank = CardRank.Five
            Dim booStraight As Boolean = (booAceHigh AndAlso booCheckWheel) OrElse Me(4).Rank - Me(0).Rank = 4
            Dim booFlush As Boolean = Me.GroupBy(Function(c) New With {Key c.Suite}).Count = 1
    
            If booAceHigh AndAlso booStraight AndAlso booFlush Then Return HandRankType.RoyalFlush
            If booFlush AndAlso booStraight Then Return HandRankType.StraightFlush
            If booFlush Then Return HandRankType.Flush
            If booStraight Then Return HandRankType.Straight
    
            Return HandRankType.HighCard
        End Function
    Last edited by Jenner; Jan 28th, 2010 at 05:57 PM.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  16. #16

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    I am Pentium(R) M @ 1.8Ghz, with some tie checking in place.
    0.0000230
    0.0000181

    I don't know how the processors compare, and my number is going to go up with all the other tie checking.

    BTW - I pulled the singleton check out. If you have 7 singletons you still might have a straight.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  17. #17

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    I think I have it, and the times only went up fractionally. After I run some more tests I'll post the whole project if anyone is interested.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  18. #18
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Poker Hand Evaluator

    Yea, I'd be interested.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  19. #19

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    CardBasics.zip

    Not cleaned up at all, but here you go.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  20. #20

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    added BlackJack hand evaluator

    Code:
        Public Function BlackJackHandEvaluate(ByVal theHand As Hand) As Integer
            Dim ranks() As Integer = New Integer() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
            Dim retval As Integer = 0
            For Each c As Card In theHand
                ranks(c.Rank) += 1
                If c.Rank = Rank.Ace Then
                    retval += 11
                ElseIf c.Rank + 2 >= 10 Then
                    retval += 10
                Else
                    retval += c.Rank + 2
                End If
            Next
            If retval <= 21 OrElse ranks(ranks.Length - 1) = 0 Then Return retval
            Dim z As Integer = ranks(ranks.Length - 1) 'get the count of aces
            For x As Integer = 1 To z 'loop, turning one ace at a time into a 1
                ranks(ranks.Length - 1) -= 1
                retval = x + (ranks(ranks.Length - 1) * 11) 'add remaining aces as 11
                For y As Integer = 0 To ranks.Length - 2 'get remaining card values
                    If ranks(y) > 0 Then
                        If y + 2 >= 10 Then
                            retval += 10 * ranks(y)
                        Else
                            retval += (y + 2) * ranks(y)
                        End If
                    End If
                Next
                If retval <= 21 Then Exit For
            Next
            Return retval
        End Function
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  21. #21
    Fanatic Member damasterjo's Avatar
    Join Date
    Nov 2005
    Location
    In front of my Comp DirectX7 EXpert
    Posts
    827

    Re: Poker Hand Evaluator

    i am just now trying to do this very same thing, i came on here to see if anyone had done it, but i dont want to just take the code, i want to make my very own one just to see if i can, i have a very interesting approach on it and if any one would be interested i can post my solution when i code it?

    I will be using VB6 though because this is my best language, and i have a game engine i have coded years ago already set up.

    I started coding this on a ti83 calculator recently and relized that it takes too long to check all the possibilities and shuffle.

    Also my game dosent come up with any random numbers i coded an actual shuffler, so its as if you were really shuffling yourself
    Software languages known:
    Qbasic - TI-Basic - Liberty Basic - Visual Basic 6
    Software API's known:
    Directx 7 and 8
    Internet languages, in the process of learning:
    HTML - JAVASCRIPT - PHP - CSS - MYSQL - AJAX

  22. #22

    Re: Poker Hand Evaluator

    You're in the wrong forum you realize.

  23. #23

    Thread Starter
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: Poker Hand Evaluator

    Quote Originally Posted by formlesstree4 View Post
    You're in the wrong forum you realize.
    Agreed. Should be here http://www.vbforums.com/forumdisplay.php?f=1
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width