- Programming Card Games
- The clsCard Class
- The clsDeck Class
- Demonstrating the clsCard and clsDeck Classes
- Blackjack, Anyone?
- Summary
- Q&A
- Workshop
Demonstrating the clsCard and clsDeck Classes
Now that you've looked over the classes, you might be a little unsure exactly how to use them in your own programs. In this section, you'll build a demo program that puts the classes to work.
Building the Program
Follow these steps to create the demo program:
-
Start a new Standard EXE Visual Basic project.
-
Set the following form properties to the values shown here. (Note that the form must be named CardForm because that's the name the clsDeck class expects it to have.)
Name = CardForm
AutoRedraw = True
BackColor = Black
Height = 7815
ScaleMode = Pixel
Width = 7995
-
Add a CommandButton control to the form, giving it the following properties:
Caption = "Test Cards"
Height = 40
Left = 18
Top = 439
Width = 144
Use the Add Form command on the Project menu to add the frmCards.frm form file to the project. You can find this form in the Classes folder of this book's CD-ROM. The frmCards.frm contains the card images, as you can see in Figure 8.2.
You need this form because it contains the card images.
Use the Add Class Module command on the Project menu to add the clsCard.cls and clsDeck.cls class module files to the project. You can find these class modules in the Classes folder of this book's CD-ROM.
In order to use the clsCard and clsDeck classes in your program, you must add their files to your project, which you did in this step.
Figure 8.2
The frmCards.frm form.
Use the Add Module command on the Project menu to add the Cards.bas module file to the project. You can find this module in the Classes folder of this book's CD-ROM.
The Cards.bas module defines the constants, enumerations, and types needed by the program and the classes, as you can see in Listing 8.3.
Listing 8.3 The Cards.bas Module
1: Public Const MAXHANDS = 8 2: 3: Public Enum Orientation 4: FaceDown 5: FaceUp 6: End Enum 7: 8: Public Type hand 9: PositionInHand As Integer 10: cards(51) As clsCard 11: End Type 12: 13: Public Enum Suits 14: Diamonds 15: Clubs 16: Spades 17: Hearts 18: End Enum 19: 20: Public Enum CardNames 21: Ace 22: Two 23: Three 24: Four 25: Five 26: Six 27: Seven 28: Eight 29: Nine 30: Ten 31: Jack 32: Queen 33: King 34: End Enum
-
Double-click the project's form in order to display the code window, and then type the following lines at the top of the program:
Option Explicit Dim Deck As clsDeck Dim TestNumber As Integer
The Deck object will represent the deck of cards in the program.
-
Add to the code window the handlers in Listing 8.4 for the form object. You can either type them or copy them from the Cards1.txt file, which you can find in the Chap08\Code directory of this book's CD-ROM.
Listing 8.4 The Form Handlers
1: Private Sub Form_Load() 2: TestNumber = 0 3: End Sub 4: 5: Private Sub Form_Unload(Cancel As Integer) 6: Unload frmCards 7: End Sub
Analysis - The Unload command in the Form_Unload event handler ensures that the frmCards form will be removed from memory at the same time the main form is.
Add to the code window the command button handler for the form object, shown in Listing 8.5. You can either type the code or copy it from the Cards2.txt file, which you can find in the Chap08\Code directory of this book's CD-ROM.
Listing 8.5 The Command1_Click Handler
1: Private Sub Command1_Click() 2: Select Case TestNumber 3: Case 0 4: ShowFullDeck 5: Case 1 6: ShowShuffledDeck 7: Case 2 8: ShowFaceDownDeck 9: Case 3 10: Deal7CardHand 11: Case 4 12: ShowFaceDownHand 13: Case 5 14: ShowFaceUpHand 15: Case 6 16: ReplaceTwoCards 17: Case 7 18: DiscardEachCard 19: Case 8 20: MoveCards 21: End Select 22: TestNumber = TestNumber + 1 23: If TestNumber > 8 Then 24: TestNumber = 0 25: Set Deck = Nothing 26: End If 27: End Sub
Analysis - The command button handler calls a different subroutine depending upon the value of the TestNumber variable. This causes the program to cycle through the various tests of the clsDeck and clsCard classes.
Add to the code window the general program subroutines shown in Listing 8.6, which are the subroutines that actually put the classes to the test. You can either type the code or copy it from the Cards3.txt file, which you can find in the Chap08\Code directory of this book's CD-ROM.
Listing 8.6 The General Subroutines
1: Sub ShowFullDeck() 2: Set Deck = New clsDeck 3: Cls 4: CurrentX = 250 5: CurrentY = 430 6: Print "Full Unshuffled Deck" 7: Deck.Deal 13, 0, 20, 20, -20, FaceUp 8: Deck.Deal 13, 1, 20, 120, -20, FaceUp 9: Deck.Deal 13, 2, 20, 220, -20, FaceUp 10: Deck.Deal 13, 3, 20, 320, -20, FaceUp 11: End Sub 12: 13: Sub ShowShuffledDeck() 14: Cl 15: CurrentX = 250 16: CurrentY = 430 17: Print "Full Shuffled Deck" 18: Deck.Shuffle 19: Deck.Deal 13, 0, 20, 20, -20, FaceUp 20: Deck.Deal 13, 1, 20, 120, -20, FaceUp 21: Deck.Deal 13, 2, 20, 220, -20, FaceUp 22: Deck.Deal 13, 3, 20, 320, -20, FaceUp 23: End Sub 24: 25: Sub ShowFaceDownDeck() 26: Cls 27: CurrentX = 250 28: CurrentY = 430 29: Print "Full Face Down Deck" 30: Deck.Deal 13, 0, 20, 20, -20, FaceDown 31: Deck.Deal 13, 1, 20, 120, -20, FaceDown 32: Deck.Deal 13, 2, 20, 220, -20, FaceDown 33: Deck.Deal 13, 3, 20, 320, -20, FaceDown 34: End Sub 35: 36: Sub Deal7CardHand() 37: Cls 38: CurrentX = 250 39: CurrentY = 430 40: Print "7-Card Hand" 41: Deck.Shuffle 42: Deck.Deal 7, 0, 20, 20, 10, FaceUp 43: End Sub 44: 45: Sub ShowFaceDownHand() 46: Dim i As Integer 47: 48: Cls 49: CurrentX = 250 50: CurrentY = 430 51: Print "Face Down Hand" 52: For i = 0 To 6 53: Deck.ShowHandCard 0, i, FaceDown 54: Next i 55: End Sub 56: 57: Sub ShowFaceUpHand() 58: Dim i As Integer 59: 60: Cls 61: CurrentX = 250 62: CurrentY = 430 63: Print "Face Up Hand" 64: For i = 0 To 6 65: Deck.ShowHandCard 0, i, FaceUp 66: Next i 67: End Sub 68: 69: Sub ReplaceTwoCards() 70: Dim i As Integer 71: 72: PrepareScreen 73: Print "Replace Two Cards" 74: For i = 0 To 6 75: Deck.ShowHandCard 0, i, FaceUp 76: Next i 77: Deck.DealReplace 0, 2, FaceDown 78: Deck.DealReplace 0, 3, FaceDown 79: End Sub 80: 81: Sub DiscardEachCard() 82: Dim i As Integer 83: 84: PrepareScreen 85: Print "Discard Cards" 86: Deck.ShowHand 0, 20, 20, 10, FaceUp 87: For i = 6 To 0 Step -1 88: MsgBox "Click OK to discard a card" 89: Deck.EraseCard 0, i 90: Deck.Discard 0, 0 91: Deck.ShowHand 0, 20, 20, 10, FaceUp 92: Deck.ShowHand 7, 20, 110, -20, FaceUp 93: Next i 94: End Sub 95: 96: Sub MoveCards() 97: Dim i As Integer 98: 99: PrepareScreen 100: Print "Move Cards" 101: For i = 0 To 6 102: Deck.EraseCard 7, i 103: Deck.MoveHandCard 7, i, i * 20 + 20, 200, FaceUp 104: Next i 105: End Sub 106: 107: Sub PrepareScreen() 108: Cls 109: CurrentX = 250 110: CurrentY = 430 111: End Sub
Analysis - These subroutines are the guts of the program. You'll look at this source code in detail a little later in this chapter.
Save the project's form file as CardForm.frm and the project file as Cards.vbp.
You've now completed the Cards demo program.
Running the Demo Program
When you run this program, you first see the screen shown in Figure 8.3. Here the program has dealt four hands of 13 cards each, all before shuffling the deck. As you can see, all the cards are in order. When you press Enter, the program shuffles the cards and redeals the four hands, as shown in Figure 8.4. You can see that the cards were indeed shuffled, so the program deals them randomly. Press Enter again and the program deals the same cards face-down.
After showing the entire deck, the program manipulates the hand. Each time that you press Enter or click the Test Cards button, the program performs a new function on the current hand. First, it deals a seven-card hand and displays it face-up. The program then shows the hand face-down and again face-up.
Next, the program deals two new face-down cards into the hand (see Figure 8.5) and then reveals them by turning them over. Then, each time you press Enter, the program discards a card from the hand and displays the new discard pile. Finally, the program moves the discard pile to a new location on the screen.
Using the clsDeck Class
The demonstration program shows most of what you need to know to use the clsDeck class. Before the program can access the clsDeck class, it must create a Deck object:
Dim Deck As clsDeck
Now, to deal four, 13-card hands from the deck, the program calls the Deal subroutine four times:
Deck.Deal 13, 0, 20, 20, -20, FaceUp Deck.Deal 13, 1, 20, 120, -20, FaceUp Deck.Deal 13, 2, 20, 220, -20, FaceUp Deck.Deal 13, 3, 20, 320, -20, FaceUp
The Deal method's arguments are the number of cards to deal, the hand where the cards will be dealt, the x,y screen coordinates of the first card in the hand, the onscreen distance between each card in the hand, and the cards' orientation (either FaceUp or FaceDown). In the preceding code segment, notice that the distance between the cards is -20. A negative distance causes the cards to appear overlapped. Positive distances separate the right and left edges of adjacent cards by the given number of pixels.
Because the cards in the Deck object are all in order, the deck must be shuffled:
Deck.Shuffle
After the shuffle, the program redeals the 13-card hands in random order:
Deck.Deal 13, 0, 20, 20, -20, FaceUp Deck.Deal 13, 1, 20, 120, -20, FaceUp Deck.Deal 13, 2, 20, 220, -20, FaceUp Deck.Deal 13, 3, 20, 320, -20, FaceUp
Next, the program deals a seven-card hand, which is displayed onscreen first face-up and then face-down. The program switches the cards' orientation by using the ShowHandCard method, which can display any card face-up or face-down:
For i = 0 To 6 Deck.ShowHandCard 0, i, FaceUp Next I
The arguments for ShowHandCard are the number of the hand where the card is located, the card's position in the hand (starting at 0 for the first card), and the card's new orientation (either FaceUp or FaceDown).
To replace cards in a hand, the program calls the DealReplace method:
Deck.DealReplace 0, 2, FaceDown Deck.DealReplace 0, 3, FaceDown
This method's arguments are the number of the hand where the card to be replaced is located, the position in the hand of the card to be replaced, and the orientation of the new card's display. Note that DealReplace does not add replaced cards to the discard pile. To add cards to the discard pile, you must call the Discard method. The example program in Listing 8.7 does this.
Listing 8.7 Discarding Cards
1: For i = 6 To 0 Step -1 2: MsgBox "Click OK to discard a card" 3: Deck.EraseCard 0, i 4: Deck.Discard 0, 0 5: Deck.ShowHand 0, 20, 20, 10, FaceUp 6: Deck.ShowHand 7, 20, 110, -20, FaceUp 7: Next I
Analysis - In the For loop, the program discards each card from the hand one at a time (Lines 3 and 4), displaying the new discard pile after each discard (Lines 5 and 6). The Discard method's arguments are the number of the hand where cards must be discarded and the position within the hand of the card to discard. In the preceding code segment, Discard's arguments are always 0,0 because the first card in the hand is always the one being discarded. When a card is discarded, the other cards in the hand move back to fill in the empty space.
Finally, the example program moves the discard pile to a new screen location by calling the MoveHandCard method:
For i = 0 To 6 Deck.EraseCard 7, i Deck.MoveHandCard 7, i, i * 20 + 20, 200, FaceUp Next I
MoveHandCard moves a single card to a new screen location. Its arguments are the number of the hand that holds the card to move, the position of the card in the hand, the new x,y coordinates for the card, and the card's orientation.