Section 8.5. Case Study: Card Shuffling and Dealing Simulation


8.5. Case Study: Card Shuffling and Dealing Simulation

The examples in the chapter thus far have used arrays containing elements of primitive types. Recall from Section 8.2. that the elements of an array can be of either primitive types or reference types. This section uses random number generation and an array of reference-type elements, namely references to objects representing playing cards, to develop a class that simulates card shuffling and dealing. You can then use this class to implement applications that play specific card games.

First, we develop class Card (Fig. 8.8), which represents a playing card that has a face (e.g., "Ace", "Deuce", "Three",..., "Jack", "Queen", "King") and a suit (e.g., "Hearts", "Diamonds", "Clubs", "Spades"). Next, we develop the DeckOfCards class (Fig. 8.9), which creates a deck of 52 playing cards in which each element is a Card object. We then build a test application DeckOfCardsTest (Fig. 8.10) that demonstrates class DeckOfCards's card shuffling and dealing capabilities.

Figure 8.8. Card class represents a playing card.

  1  ' Fig. 8.8: Card.vb,  2  ' Card class represents a playing card.  3  Public Class Card  4     Private face As String ' face of card ("Ace", "Deuce", ...)  5     Private suit As String ' suit of card ("Hearts", "Diamonds", ...)  6  7     ' two-argument constructor initializes card's face and suit  8     Public Sub New(ByVal cardFace As String, ByVal cardSuit As String)  9        face = cardFace ' initialize face of card 10        suit = cardSuit ' initialize suit of card 11     End Sub ' New 12 13     ' return String representation of Card, Overrides defined in Ch 9 14     Public Overrides Function ToString() As String                    15        Return face & " of " & suit                                    16     End Function ' ToString                                           17  End Class ' Card 

Figure 8.9. DeckOfCards class represents a deck of playing cards that can be shuffled and dealt one at a time.

  1  ' Fig. 8.9: DeckOfCards.vb  2  ' DeckOfCards class represents a deck of playing cards.  3  Public Class DeckOfCards  4     Private deck As Card() ' array of Card objects  5     Private currentCard As Integer ' index of next Card to be dealt  6     Private Const NUMBER_OF_CARDS As Integer = 52 ' number of cards  7     Private randomNumbers As random ' random number generator  8  9     ' constructor fills deck of Cards 10     Public Sub New() 11        Dim faces As String() = {"Ace", "Deuce", "Three", "Four", "Five", _ 12           "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"} 13        Dim suits As String() = {"Hearts", "Diamonds", "Clubs", "Spades"}   14 15        deck = New Card(NUMBER_OF_CARDS - 1) {} ' create array of Cards 16        currentCard = 0 ' set currentCard so first Card dealt is deck(0) 17        randomNumbers = New Random() ' create random number generator 18 19        ' populate deck with Card objects                                 20        For count As Integer = 0 To deck.GetUpperBound(0)                 21           deck(count) = New Card(faces(count Mod 13), suits(count \ 13)) 22        Next                                                              23     End Sub ' New 24 25     ' shuffle deck of Cards with simple one-pass algorithm 26     Public Sub Shuffle() 27        ' after shuffling, dealing should start at deck(0) again 28        currentCard = 0 ' reinitialize currentCard 29 30        ' for each Card, pick another random Card and swap them 31        For first As Integer = 0 To deck.GetUpperBound(0) 32           ' select a random number between 0 and 51 33           Dim second As Integer = randomNumbers.Next(NUMBER_OF_CARDS) 34 35           ' swap current Card with randomly selected Card 36           Dim temp As Card = deck(first)                  37           deck(first) = deck(second)                      38           deck(second) = temp                             39        Next 40     End Sub ' Shuffle 41 42     ' deal one Card 43     Public Function DealCard() As Card 44        ' determine whether Cards remain to be dealt 45        If currentCard <= deck.GetUpperBound(0) Then 46           Dim lastCard = currentCard ' store current card number 47           currentCard += 1 ' increment current card number 48           Return deck(lastCard) 49        Else 50           Return Nothing 51        End If 52     End Function ' DealCard 53  End Class ' DeckOfCards 

Figure 8.10. Card shuffling and dealing (all 52 cards are dealt).

  1  ' Fig. 8.10: DeckOfCardsTest.vb  2  ' Card shuffling and dealing application.  3  Module DeckOfCardsTest  4     Sub Main()  5        Dim cards As New DeckOfCards()  6        cards.Shuffle() ' place Cards  in random order  7  8        ' print all 52 Cards in the order in which they are dealt  9        For i As Integer = 0 To 12 10           Console.WriteLine("{0, -18} {1, -18} {2, -18}  {3, -18}", _ 11              cards.DealCard(),  cards.DealCard(), cards.DealCard(), _ 12              cards.Deal Card())                                       13        Next 14     End Sub ' Main 15  End Module ' DeckOfCardsTest 

[View full width]

Five of Spades Nine of Spades Seven of Hearts Eight of Clubs Jack of Spades Seven of Clubs Queen of Spades Ace of Diamonds Ace of Clubs Five of Hearts Ten of Diamonds Queen of Diamonds Nine of Diamonds Four of Hearts Six of Spades Six of Diamonds Ace of Hearts King of Spades Jack of Diamonds Seven of Spades Four of Spades Seven of Diamonds Ten of Spades Eight of Spades Deuce of Spades King of Diamonds Deuce of Hearts Nine of Hearts Three of Clubs King of Hearts Six of Hearts Queen of Hearts Eight of Hearts Ten of Hearts Five of Clubs King of Clubs Five of Diamonds Jack of Clubs Jack of Hearts Eight of Diamonds Six of Clubs Deuce of Clubs Ace of Spades Three of Hearts Four of Diamonds Ten of Clubs Nine of Clubs Three of Spades Queen of Clubs Deuce of Diamonds Three of Diamonds Four of Clubs



Class Card

Class Card (Fig. 8.8) contains two String instance variablesface and suitthat are used to store references to the face name and suit name for a specific Card. The constructor for the class (lines 811) receives two Strings that it uses to initialize face and suit. Method ToString (lines 1416) creates a String consisting of the face of the card, the String " of " and the suit of the card. Recall from Chapter 3 that the & operator can be used to concatenate (i.e., combine) several Strings to form one larger String. Card's ToString method can be invoked explicitly to obtain a string representation of a Card object (e.g., "Ace of Spades"). The ToString method of an object is called implicitly when an object is output as a String. For this behavior to occur, ToString must be declared with the header shown in line 14 of Fig. 8.8. We discuss the special method ToString in Chapter 9, Classes and Objects: A Deeper Look.

Class DeckOfCards

Class DeckOfCards (Fig. 8.9) declares an instance variable array named deck, which consists of Card objects (line 4). Like primitive-type array declarations, the declaration of an array of objects includes the name of the array variable, followed by the keyword As, the type of the elements in the array and parentheses (e.g., deck As Card()). Class DeckOfCards also declares an integer instance variable currentCard (line 5) representing the next Card to be dealt from the deck array and a named constant NUMBER_OF_CARDS (line 6) indicating the number of Cards in the deck (52).

The class's constructor instantiates the deck array (line 15) with upper bound NUMBER_OF_CARDS - 1. When first created, the elements of the deck array are Nothing by default, so the constructor uses a For statement (lines 2022) to fill the deck array with Cards. This statement initializes control variable count to 0 and loops while count is less than or equal to deck.GetUpperBound(0), causing count to take on each integer value from 0 to 51 (the indices of the deck array). Each Card is instantiated and initialized with two Stringsone from the faces array (which contains the Strings "Ace" through "King") and one from the suits array (which contains the Strings "Hearts", "Diamonds", "Clubs" and "Spades"). The calculation count Mod 13 always results in a value from 0 to 12 (the 13 indices of the faces array in lines 1112), and the calculation count \ 13 always results in a value from 0 to 3 (the four indices of the suits array in line 13). When the deck array is initialized, it contains the Cards with faces "Ace" through "King" in order for each suit.

Method Shuffle (lines 2640) shuffles the Cards in the deck. The method loops through all 52 Cards (array indices 0 to 51). For each Card, a number between 0 and 51 is picked randomly to select another Card (line 33). Next, the current Card object and the randomly selected Card object are swapped in the array (lines 3638). The extra variable temp temporarily stores one of the two Card objects being swapped. The swap cannot be performed with only the two statements

 deck(first) = deck(second) deck(second) = deck(first) 


If deck(first) is the "Ace" of "Spades" and deck(second) is the "Queen" of "Hearts", after the first assignment, both array elements contain the "Queen" of "Hearts" and the "Ace" of "Spades" is losthence, the extra variable temp is needed. After the For loop terminates, the Card objects are randomly ordered. Only 52 swaps are made in a single pass of the entire array, and the array of Card objects is shuffled!

Method DealCard (lines 4352) deals one Card in the array. Recall that currentCard indicates the index of the next Card to be dealt (i.e., the Card at the top of the deck). Thus, line 45 compares currentCard to the upper bound (51) of the deck array. If the deck is not empty (i.e., currentCard is less than or equal to 51), line 46 assigns currentCard (the index of the card that will be returned) to temporary variable lastCard, line 47 increments currentCard to prepare for the next call to DealCard and line 48 returns deck(lastCard), which represents the top card of the deck for this call to DealCard. Otherwise, DealCard returns Nothing to indicate that the deck is empty.

Shuffling and Dealing Cards

The application in Fig. 8.10 demonstrates the card dealing and shuffling capabilities of class DeckOfCards (Fig. 8.9). Line 5 creates a DeckOfCards object named cards. Recall that the DeckOfCards constructor creates the deck with the 52 Card objects in order by suit and face. Line 6 invokes cards's Shuffle method to randomly rearrange the Card objects. The For statement in lines 913 deals all 52 Cards in the deck and prints them in four columns of 13 Cards each. Lines 1012 deal and print four Card objects (on one line), each obtained by invoking cards's DealCard method. When Console.WriteLine outputs a Card with the {0, -18} format specifier, the Card's ToString method (declared in lines 1416 of Fig. 8.8) is implicitly invoked, and the result is output left justified (because of the minus sign in -18) in a field of width 18. Again, we explain ToString in detail in Chapter 9.



Visual BasicR 2005 for Programmers. DeitelR Developer Series
Visual Basic 2005 for Programmers (2nd Edition)
ISBN: 013225140X
EAN: 2147483647
Year: 2004
Pages: 435

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net