Write a poker card game in Visual Basic.NET.

by yutao4194 on 2010-04-06 12:36:39

There are various poker games, and the rules for the same game can differ from place to place. Hobbyists who enjoy programming often like to code local variations of poker games. So, where should one start when writing their own poker game?

The key aspects of poker game programming are two-fold: 1) Drawing the card faces; 2) Implementing the game rules algorithmically. Beginners in poker game programming can start with simple games and leverage existing resources. This article will introduce the basics of poker game programming using Windows' built-in Cards.dll and a basic 21-point (Blackjack) game as an example.

### 1. Drawing Card Faces

Cards.dll supports Windows' built-in games such as Solitaire. If we know how to use the API functions within Cards.dll, then we can draw card faces just like in Windows' built-in games. We need to use three fundamental functions: cdtInit, cdtDrawExt, and cdtTerm. Additionally, we need two variables: width and height for initializing the function cdtInit. Below are the declarations and parameter explanations for these interface functions.

```vb

Private width As Integer = 0

Private height As Integer = 0

Declare Function cdtInit Lib "cards.dll" (ByRef width As Integer, _

ByRef height As Integer) As Boolean

Parameter Explanation:

- width, height return the default width and height of the card in pixels.

Declare Function cdtDrawExt Lib "cards.dll" (ByVal hdc As IntPtr, _

ByVal x As Integer, ByVal y As Integer, ByVal dx As Integer, _

ByVal dy As Integer, ByVal card As Integer, _

ByVal mode As Integer, ByVal color As Long) As Boolean

Parameter Explanation:

- hdc (handle to a device context): The handle for the drawing surface.

- x, y: Coordinates specifying the top-left corner of the card.

- dx, dy: Width and height of the card.

- card: Specifies which card to draw (0-51 for [Ace(Clubs, Diamonds, Hearts, Spades), 2, ..., K]; 53-65 for the back of the card).

- mode: Specifies the drawing method (face up = 0, face down = 1).

- color: Specifies the background color.

Declare Sub cdtTerm Lib "cards.dll" ()

No parameters.

We need to call cdtInit at the start of the game to initialize cards.dll so that we can use functions like cdtDrawExt. For each card drawn, we call cdtDrawExt once. When the game ends, we call cdtTerm to stop using cards.dll.

```

### 2. Algorithm Implementation for Game Rules

In the 21-point game, players aim to have a higher total score than the dealer without exceeding 21 points (which results in a bust). J, Q, K count as 10 points, A can be counted as either 1 or 11 points, and other cards follow their face value. “BlackJack” consists of an Ace and any J, Q, K, or 10. Initially, each player gets two cards, one face-up and one face-down. Players can choose to draw additional cards if their total is less than 21. If the first two cards form a pair, the player can choose to split them.

For simplicity, the program only includes two players: Dealer and Player. Both receive cards, there is no betting process, no win/loss tracking, and no support for splitting or doubling down. In this 21-point game, a card has four attributes: Face (card rank), Suit (card suit), Count (point value), and FaceUp (whether the card is face up). Therefore, instead of using a Card class, we use a Card structure:

```vb

Structure card

Public face As Integer

Public suit As Integer

Public count As Integer

Public faceup As Boolean

End Structure

```

At the start of the game, we need to get a deck of cards, shuffle it, and specify which card to deal from. To obtain truly random numbers during shuffling, we use My.Computer.Clock.TickCount as the seed for generating random numbers.

```vb

Dim Deck() As card

Deck = New card(51) {}

Dim TopCard As Integer

Private Sub GetDeck()

Dim i, j As Integer

For i = 0 To 3

For j = 0 To 12

Deck(j + 13 * i).face = j

Deck(j + 13 * i).suit = i

If j = t + dt Then Exit Do

Loop

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Button1.Visible = False

Label1.Text = ""

Label2.Text = ""

Label1.Refresh()

Label2.Refresh()

MyBase.CreateGraphics.Clear(Color.DarkGreen)

dealerAce = 0

playerAce = 0

dealerCount = 0

playerCount = 0

' Draw initial cards...

' ...

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

' Handle player hitting a card...

' ...

End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

Button2.Visible = False

Button3.Visible = False

dealerPlay()

End Sub

Private Sub dealerPlay()

Do

If dealerCount < 17 Then

' Deal card to dealer...

' ...

Else

Exit Do

End If

Loop

' Determine winner...

' ...

End Sub

```

### 3. Practice and Improvement

In the above programming, we used a structure to describe the card. The values for Face (A, 2, ..., K) and Suit (Clubs, Diamonds, Hearts, Spades) were represented by the numbers 0-12 and 0-3 respectively. The game rules were simplified, with only two players and no detailed player properties (such as wealth, bets, held cards, etc.). In practice, a better approach would be to use Card and Player classes, with Face and Suit as enumeration types. These enhancements can gradually be added to the program.