Bubblebeard Bubblebeard - 3 months ago 31
Vb.net Question

VB poker hand evaluator

My class programming project is to create a program that allows you to input numbers and letters to specify a card number and suit (e.g. 2 and D = 2 of Diamonds).

This is what it will look like:
Poker

This is the code I have so far:

Public Class frmPoker
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
Dim cards(4) As Integer
Dim suit(4) As String

cards(0) = CInt(txtCard1.Text)
cards(1) = CInt(txtCard2.Text)
cards(2) = CInt(txtCard3.Text)
cards(3) = CInt(txtCard4.Text)
cards(4) = CInt(txtCard5.Text)

Dim card = From item In cards
Select item
Distinct

If card.Count = 4 Then
txtDisplay.Text = "One Pair"
ElseIf card.Count = 3 Then
txtDisplay.Text = "Three of a kind"
ElseIf card.Count = 2 Then
txtDisplay.Text = "Four of a kind"
End If

suit(0) = txtSuit1.Text
suit(1) = txtSuit2.Text
suit(2) = txtSuit3.Text
suit(3) = txtSuit4.Text
suit(4) = txtSuit5.Text

Dim suits = From item In suit
Select item
Distinct

If suits.Count = 1 Then
txtDisplay.Text = "Flush"
End If


I'm not sure how to approach determining a full house and a straight flush. Also if there is, for example, two 2s and two 3s, the program will determine that is actually three of a kind.

Answer

You should never use code you dont understand. For example:

Dim card = From item In cards
           Select item
           Distinct

That will tell you the different cards in the hand but not how many of each. The hand {2, 2, 3, 2, 3} gives the same result as {9, 10, 9, 9, 9}. In fact the result for trips {3, 3, 3, 2, 7} will be the same as for 2 pair {3, 3, 2, 2, 7}. There isnt enough information there for what you want.

Here is an alternative (note: assumes a 5-card hand, and Aces Hi to start):

' dont use 0th; Ace=1 and 14
Dim counts(15) As Int32
' count how many of each rank:
For Each n As Int32 In cards
    counts(n) += 1      
Next

At the end, each element will tell you how many of each rank there is. For instance count(2) may hold the value 3 indicating there are 3 Deuces. Then iterate the array to evaluate:

Dim pairs As Int32 = 0
Dim trips As Int32 = 0
Dim quads As Int32 = 0
' count them:
For Each n As Int32 In counts
    If n = 2 Then pairs += 1
    If n = 3 Then trips += 1
    If n = 4 Then quads += 1
Next
Dim Aced = counts(14) > 0

That covers a lot of hands. You also need to know if there is an Ace so you can later test for a Wheel ({A, 2, 3, 4, 5}). Flushes come into play in 2 places, so just set a flag:

Dim Flushed = Suits(0) = Suits(1) AndAlso
              Suits(0) = Suits(2) AndAlso
              Suits(0) = Suits(3) AndAlso
              Suits(0) = Suits(4)

A Straight is harder to do since you have to check the order of an unordered set. So first, put it in order an see if that sequence matches a manufactured one. Some research needs to be left to you, but Enumerable will create the comparison range; test it using Array.Intersect or .SequenceEqual or just do something like the code for Flushed.

The Straight and Flush tests can be skipped if (pairs + trips + quads > 0), but they are pretty simple and just collecting all the metrics for the hand and doing a series of If tests at the end makes the code easier to debug.

Aces make it messy. If there is an Ace, you need to check for a Wheel: copy counts(14) to counts(1) and set counts(14) to zero. Then sort and check the sequence again. After that, it is just a matter of evaluating those variables in order from high to low. These exercises are left for the student.

Comments