16.15. Card Shuffling and Dealing Simulation In this section, we use random-number generation to develop a program that simulates card shuffling and dealing. These techniques can form the basis of programs that implement specific card games. Class Card (Fig. 16.16) contains two String instance variablesface and suitthat store references to the face value and suit name of a specific card. The constructor for the class receives two Strings that it uses to initialize face and suit. Method ToString (lines 1214) creates a String consisting of the face of the card and the suit of the card to identify the card when it is dealt. Figure 16.16. Card class. 1 ' Fig. 16.16: Card.vb 2 ' Stores suit and face information on each card. 3 Public Class Card 4 Private face As String 5 Private suit As String 6 7 Public Sub New(ByVal faceValue As String, ByVal suitValue As String) 8 face = faceValue 9 suit = suitValue 10 End Sub ' New 11 12 Public Overrides Function ToString() As String 13 Return face & " of " & suit 14 End Function ' ToString 15 End Class ' Card | The DeckForm application (Fig. 16.17) creates a deck of 52 Card objects. Users can deal each card by clicking the Deal Card button. Each dealt card is displayed in a Label. Users can also shuffle the deck at any time by clicking the Shuffle Cards button. Figure 16.17. Card shuffling and dealing simulation. 1 ' Fig. 16.17: DeckForm.vb 2 ' Simulating card shuffling and dealing. 3 Public Class frmDeck 4 Private deck(51) As Card ' deck of 52 cards 5 Private currentCard As Integer ' count which card was just dealt 6 7 ' handles form at load time 8 Private Sub frmDeck_Load(ByVal sender As System.Object, _ 9 ByVal e As System.EventArgs) Handles MyBase.Load 10 11 Dim faces As String() = _ 12 {"Ace", "Deuce", "Three", "Four" , "Five", "Six" , "Seven", _ 13 "Eight" , "Nine", "Ten", "Jack", "Queen", "King"} 14 Dim suits As String() = {"Hearts", "Diamonds", "Clubs", "Spades"} 15 16 currentCard = -1 ' no cards have been dealt 17 18 ' initialize deck 19 For i As Integer = 0 To deck.Length - 1 20 deck(i) = New Card(faces(i Mod 13), suits(i \ 13)) 21 Next i 22 End Sub ' frmDeck_Load 23 24 ' deal a card 25 Private Sub btnDeal_Click(ByVal sender As System.Object, _ 26 ByVal e As System.EventArgs) Handles btnDeal.Click 27 28 Dim dealt As Card = DealCard() 29 30 ' if dealt card is Nothing, then no cards left 31 ' player must shuffle cards 32 If Not (dealt Is Nothing) Then 33 lblDisplay.Text = dealt.ToString() 34 lblStatus.Text = "Card #: " & currentCard 35 Else 36 lblDisplay.Text = "NO MORE CARDS TO DEAL" 37 lblStatus.Text = "Shuffle cards to continue" 38 End If 39 End Sub ' btnDeal_Click 40 41 ' shuffle cards 42 Private Sub Shuffle() 43 Dim randomNumber As New Random() 44 Dim temporaryValue As Card 45 46 currentCard = -1 47 48 ' swap each card with randomly selected card (0-51) 49 For i As Integer = 0 To deck.Length - 1 50 Dim j As Integer = randomNumber.Next(52) 51 52 ' swap cards 53 temporaryValue = deck(i) 54 deck(i) = deck(j) 55 deck(j) = temporaryValue 56 Next i 57 58 btnDeal.Enabled = True ' shuffled deck can now deal cards 59 End Sub ' Shuffle 60 61 ' deal a card if the deck is not empty 62 Private Function DealCard() As Card 63 ' if there is a card to deal then deal it; 64 ' otherwise, signal that cards need to be shuffled by 65 ' disabling dealButton and returning Nothing 66 If currentCard + 1 < deck.Length Then 67 currentCard += 1 ' increment count 68 Return deck(currentCard) ' return new card 69 Else 70 btnDeal.Enabled = False ' empty deck cannot deal cards 71 Return Nothing ' do not return a card 72 End If 73 End Function ' DealCard 74 75 ' handles btnShuffle Click 76 Private Sub btnShuffle_Click(ByVal sender As System.Object, _ 77 ByVal e As System.EventArgs) Handles btnShuffle.Click 78 79 lblDisplay.Text = "SHUFFLING..." 80 Shuffle() 81 lblDisplay.Text = "DECK IS SHUFFLED" 82 End Sub ' btnShuffle_Click 83 End Class ' frmDeck
(a)
(b)
(c)
(d) | Method frmDeck_Load (lines 822 of Fig. 16.17) uses a loop (lines 1921) to fill the deck array with Cards. Each Card is instantiated and initialized with two Stringsone from the faces array (Strings "Ace" through "King") and one from the suits array ("Hearts", "Diamonds", "Clubs" or "Spades"). The calculation i Mod 13 always results in a value from 0 to 12 (the 13 subscripts of the faces array), and the calculation i \13 always results in an Integer value from 0 to 3 (the four subscripts in the suits array). The initialized deck array contains the cards with faces Ace through King for each suit. When the user clicks the Deal Card button, event handler btnDeal_Click (lines 2539) invokes method DealCard (defined in lines 6273) to get the next card in the deck array. If the deck is not empty, the method returns a Card object reference; otherwise, it returns Nothing. If the reference is not Nothing, lines 3334 display the Card in lblDisplay and display the card number in lblStatus. If DealCard returns Nothing, the String "NO MORE CARDS TO DEAL" is displayed in lblDisplay, and the String "Shuffle cards to continue" is displayed in lblStatus. When the user clicks the Shuffle Cards button, event handler btnShuffle_Click (lines 7682) invokes method Shuffle (defined in lines 4259) to shuffle the cards. The method loops through all 52 cards (array subscripts 051). For each card, the method randomly picks a number between 0 and 51. Then the current Card object and the randomly selected Card object are swapped in the array. To shuffle the cards, method Shuffle makes a total of only 52 swaps during a single pass of the entire array. When the shuffling is complete, lblDisplay displays the String "DECK IS SHUFFLED". |