Case Study: Card Shuffling and Dealing Simulation

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 7.2 that the elements of an array can be either primitive types or reference types. This section uses random number generation and an array of reference-type elements, namely objects representing playing cards, to develop a class that simulates card shuffling and dealing. This class can then be used to implement applications that play specific card games. The exercises at the end of the chapter use the classes developed here to build a simple poker application.

We first develop class Card (Fig. 7.9), 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. 7.10), which creates a deck of 52 playing cards in which each element is a Card object. We then build a test application (Fig. 7.11) that demonstrates class DeckOfCards's card shuffling and dealing capabilities.

Figure 7.9. Card class represents a playing card.

(This item is displayed on page 299 in the print version)

 1 // Fig. 7.9: Card.java
 2 // Card class represents a playing card.
 3
 4 public class Card
 5 {
 6 private String face; // face of card ("Ace", "Deuce", ...)
 7 private String suit; // suit of card ("Hearts", "Diamonds", ...)
 8
 9 // two-argument constructor initializes card's face and suit
10 public Card( String cardFace, String cardSuit )
11 {
12 face = cardFace; // initialize face of card
13 suit = cardSuit; // initialize suit of card
14 } // end two-argument Card constructor
15
16 // return String representation of Card
17 public String toString() 
18 { 
19  return face + " of " + suit; 
20 } // end method toString 
21 } // end class Card

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

(This item is displayed on pages 299 - 300 in the print version)

 1 // Fig. 7.10: DeckOfCards.java
 2 // DeckOfCards class represents a deck of playing cards.
 3 import java.util.Random;
 4
 5 public class DeckOfCards
 6 {
 7 private Card deck[]; // array of Card objects
 8 private int currentCard; // index of next Card to be dealt
 9 private final int NUMBER_OF_CARDS = 52; // constant number of Cards
10 private Random randomNumbers; // random number generator
11
12 // constructor fills deck of Cards
13 public DeckOfCards()
14 {
15 String faces[] = { "Ace", "Deuce", "Three", "Four", "Five", "Six",
16  "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" }; 
17 String suits[] = { "Hearts", "Diamonds", "Clubs", "Spades" }; 
18
19 deck = new Card[ NUMBER_OF_CARDS ]; // create array of Card objects
20 currentCard = 0; // set currentCard so first Card dealt is deck[ 0 ]
21 randomNumbers = new Random(); // create random number generator
22
23 // populate deck with Card objects 
24 for ( int count = 0; count < deck.length; count++ ) 
25  deck[ count ] = 
26  new Card( faces[ count % 13 ], suits[ count / 13 ] );
27 } // end DeckOfCards constructor
28
29 // shuffle deck of Cards with one-pass algorithm
30 public void shuffle()
31 {
32 // after shuffling, dealing should start at deck[ 0 ] again
33 currentCard = 0; // reinitialize currentCard
34
35 // for each Card, pick another random Card and swap them
36 for ( int first = 0; first < deck.length; first++ )
37 {
38 // select a random number between 0 and 51
39 int second = randomNumbers.nextInt( NUMBER_OF_CARDS );
40
41 // swap current Card with randomly selected Card
42 Card temp = deck[ first ]; 
43 deck[ first ] = deck[ second ];
44 deck[ second ] = temp; 
45 } // end for
46 } // end method shuffle
47
48 // deal one Card
49 public Card dealCard()
50 {
51 // determine whether Cards remain to be dealt
52 if ( currentCard < deck.length )
53 return deck[ currentCard++ ]; // return current Card in array
54 else
55 return null; // return null to indicate that all Cards were dealt
56 } // end method dealCard
57 } // end class DeckOfCards

Figure 7.11. Card shuffling and dealing.

(This item is displayed on page 302 in the print version)

 1 // Fig. 7.11: DeckOfCardsTest.java
 2 // Card shuffling and dealing application.
 3
 4 public class DeckOfCardsTest
 5 {
 6 // execute application
 7 public static void main( String args[] )
 8 {
 9 DeckOfCards myDeckOfCards = new DeckOfCards();
10 myDeckOfCards.shuffle(); // place Cards in random order
11
12 // print all 52 Cards in the order in which they are dealt
13 for ( int i = 0; i < 13; i++ )
14 {
15 // deal and print 4 Cards
16 System.out.printf( "%-20s%-20s%-20s%-20s
",
17 myDeckOfCards.dealCard(), myDeckOfCards.dealCard(),
18 myDeckOfCards.dealCard(), myDeckOfCards.dealCard() );
19 } // end for
20 } // end main
21 } // end class DeckOfCardsTest
 
Six of Spades Eight of Spades Six of Clubs Nine of Hearts
Queen of Hearts Seven of Clubs Nine of Spades King of Hearts
Three of Diamonds Deuce of Clubs Ace of Hearts Ten of Spades
Four of Spades Ace of Clubs Seven of Diamonds Four of Hearts
Three of Clubs Deuce of Hearts Five of Spades Jack of Diamonds
King of Clubs Ten of Hearts Three of Hearts Six of Diamonds
Queen of Clubs Eight of Diamonds Deuce of Diamonds Ten of Diamonds
Three of Spades King of Diamonds Nine of Clubs Six of Hearts
Ace of Spades Four of Diamonds Seven of Hearts Eight of Clubs
Deuce of Spades Eight of Hearts Five of Hearts Queen of Spades
Jack of Hearts Seven of Spades Four of Clubs Nine of Diamonds
Ace of Diamonds Queen of Diamonds Five of Clubs King of Spades
Five of Diamonds Ten of Clubs Jack of Spades Jack of Clubs
 

Class Card

Class Card (Fig. 7.9) 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 1014) receives two Strings that it uses to initialize face and suit. Method toString (lines 1720) creates a String consisting of the face of the card, the String " of " and the suit of the card. Recall from Chapter 6 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 the object is used where a String is expected (e.g., when printf outputs the object as a String using the %s format specifier or when the object is concatenated to a String using the + operator). For this behavior to occur, toString must be declared with the header shown in Fig. 7.9.

Class DeckOfCards

Class DeckOfCards (Fig. 7.10) declares an instance variable array named deck of Card objects (line 7). Like primitive-type array declarations, the declaration of an array of objects includes the type of the elements in the array, followed by the name of the array variable and square brackets (e.g., Card deck[]). Class DeckOfCards also declares an integer instance variable currentCard (line 8) representing the next Card to be dealt from the deck array and a named constant NUMBER_OF_CARDS (line 9) indicating the number of Cards in the deck (52).

The class's constructor instantiates the deck array (line 19) to be of size NUMBER_OF_CARDS. When first created, the elements of the deck array are null by default, so the constructor uses a for statement (lines 2426) to fill the deck array with Cards. The for statement initializes control variable count to 0 and loops while count is less than deck.length, 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 % 13 always results in a value from 0 to 12 (the 13 indices of the faces array in lines 1516), and the calculation count / 13 always results in a value from 0 to 3 (the four indices of the suits array in line 17). When the deck array is initialized, it contains the Cards with faces "Ace" through "King" in order for each suit.

Method shuffle (lines 3046) 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. Next, the current Card object and the randomly selected Card object are swapped in the array. This exchange is performed by the three assignments in lines 4244. 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. A total of only 52 swaps are made in a single pass of the entire array, and the array of Card objects is shuffled!

Method dealCard (lines 4956) 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 52 compares currentCard to the length of the deck array. If the deck is not empty (i.e., currentCard is less than 52), line 53 returns the top Card and increments currentCard to prepare for the next call to dealCardotherwise, null is returned. Recall from Chapter 3 that null represents a "reference to nothing."

Shuffling and Dealing Cards

The application of Fig. 7.11 demonstrates the card dealing and shuffling capabilities of class DeckOfCards (Fig. 7.10). Line 9 creates a DeckOfCards object named myDeckOfCards. Recall that the DeckOfCards constructor creates the deck with the 52 Card objects in order by suit and face. Line 10 invokes myDeckOfCards's shuffle method to rearrange the Card objects. The for statement in lines 1319 deals all 52 Cards in the deck and prints them in four columns of 13 Cards each. Lines 1618 deal and print four Card objects, each obtained by invoking myDeckOfCards's dealCard method. When printf outputs a Card with the %-20s format specifier, the Card's toString method (declared in lines 1720 of Fig. 7.9) is implicitly invoked, and the result is output left justified in a field of width 20.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

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