Case Study: Card Shuffling and Dealing Simulation

Một phần của tài liệu java for programmeras 2nd edition (Trang 186 - 190)

ThetryStatement

To handle an exception, place any code that might throw an exception in atrystatement (lines 17–26). Thetryblock(lines 17–20) contains the code that mightthrowan excep- tion, and thecatchblock(lines 21–26) contains the code thathandlesthe exception if one occurs. You can have manycatchblocks to handle different types of exceptions that might be thrown in the correspondingtryblock. When line 19 correctly increments an element of thefrequencyarray, lines 21–26 are ignored. The braces that delimit the bodies of the

tryandcatchblocks are required.

Executing thecatchBlock

When the program encounters theresponsesarray value14, it attempts to add1tofre-

quency[14], which isoutsidethe array’s bounds—it has only six elements. Because array bounds checking is performed at execution time, the JVM generates an exception—specifi- cally line 19 throws anArrayIndexOutOfBoundsExceptionto notify the program of this problem. At this point thetryblock terminates and thecatchblock begins executing—if you declared any variables in thetryblock, they’re now out of scope and are not accessible in thecatchblock. Thecatchblock declares a type (ArrayIndexOutOfBoundsException) and an exception parameter (e) and can handle exceptions of the specified type. In thecatch block, you can use the parameter’s identifier to interact with a caught exception object.

toStringMethod of the Exception Parameter

When lines 21–26 catch the exception, the program displays a message indicating the problem that occurred. Line 23 implicitly calls the exception object’stoStringmethod to get the error message that is stored in the exception object and display it. Once the message is displayed in this example, the exception is considered handled and the program contin- ues with the next statement after thecatchblock’s closing brace. In this example, the end of the for statement is reached (line 27), so the program continues with the increment of the control variable in line 15.

7.5 Case Study: Card Shuffling and Dealing Simulation

So far we’ve focused on primitive-type arrays. 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.

We first develop classCard(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 classDeckOfCards(Fig. 7.10), which creates a deck of 52Cards. We then build a test application (Fig. 7.11) that demonstrates classDeckOfCards’s card shuffling and dealing capabilities.

Error-Prevention Tip 7.1

When writing code to access an array element, ensure that the array index remains greater than or equal to 0 and less than the length of the array. This helps preventArrayIndex- OutOfBoundsExceptionin your program.

154 Chapter 7 Arrays and ArrayLists

ClassCard

ClassCard(Fig. 7.9) contains twoString instance variables—faceandsuit—that are used to store references to the face name and suit name for a specificCard. The constructor for the class (lines 10–14) receives twoStrings that it uses to initialize faceandsuit. MethodtoString(lines 17–20) creates aStringconsisting of thefaceof thecard, the

String " of "and thesuitof the card.Card’stoStringmethod can be invoked explicitly to obtain a string representation of aCardobject (e.g.,"Ace of Spades"). ThetoString method of an object is calledimplicitlywhen the object is used where aStringis expected (e.g., whenprintfoutputs the object as aStringusing the%sformat specifier or when the object is concatenated to aStringusing the+operator). For this behavior to occur,

toStringmust be declared with the header shown in Fig. 7.9.

ClassDeckOfCards

ClassDeckOfCards (Fig. 7.10) declares as an instance variable aCardarray nameddeck (line 7). An array of a reference type is declared like any other array. ClassDeckOfCards

also declares an integer instance variablecurrentCard(line 8) representing the nextCard to be dealt from thedeckarray and a named constantNUMBER_OF_CARDS(line 9) indicating the number ofCards in the deck (52).

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 17 18 19 20

21 } // end class Card

Fig. 7.9 | Cardclass represents a playing card.

1 // Fig. 7.10: DeckOfCards.java

2 // DeckOfCards class represents a deck of playing cards.

3 import java.util.Random;

4

Fig. 7.10 | DeckOfCardsclass represents a deck of playing cards. (Part 1 of 2.)

// return String representation of Card public String toString()

{

return face + " of " + suit;

} // end method toString

7.5 Case Study: Card Shuffling and Dealing Simulation 155

5 public class DeckOfCards 6 {

7

8 private int currentCard; // index of next Card to be dealt (0-51) 9 private static final int NUMBER_OF_CARDS = 52; // constant # of Cards 10 // random number generator

11 private static final Random randomNumbers = new Random();

12

13 // constructor fills deck of Cards 14 public DeckOfCards()

15 {

16 17 18 19 20

21 currentCard = 0; // set currentCard so first Card dealt is deck[ 0 ] 22

23 24 25 26

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 (0-51) 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

43 44

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 ( )

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

Fig. 7.10 | DeckOfCardsclass represents a deck of playing cards. (Part 2 of 2.)

private Card[] deck; // array of Card objects

String[] faces = { "Ace", "Deuce", "Three", "Four", "Five", "Six",

"Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };

String[] suits = { "Hearts", "Diamonds", "Clubs", "Spades" };

deck = new Card[ NUMBER_OF_CARDS ]; // create array of Card objects

// populate deck with Card objects

for ( int count = 0; count < deck.length; count++ ) deck[ count ] =

new Card( faces[ count % 13 ], suits[ count / 13 ] );

Card temp = deck[ first ];

deck[ first ] = deck[ second ];

deck[ second ] = temp;

currentCard < deck.length

156 Chapter 7 Arrays and ArrayLists

DeckOfCardsConstructor

The class’s constructor instantiates thedeckarray (line 20) withNUMBER_OF_CARDS(52) el- ements. The elements ofdeckarenullby default, so the constructor uses aforstatement (lines 24–26) to fill thedeckwithCards. The loop initializes control variablecountto0 and loops whilecountis less thandeck.length, causingcountto take on each integer val- ue from 0 to 51 (the indices of thedeckarray). EachCardis instantiated and initialized with twoStrings—one from thefacesarray (which contains theStrings"Ace"through

"King") and one from the suits array (which contains the Strings "Hearts", "Dia-

monds","Clubs"and"Spades"). The calculationcount % 13always results in a value from 0 to 12 (the 13 indices of thefacesarray in lines 16–17), and the calculationcount / 13 always results in a value from 0 to 3 (the four indices of thesuitsarray in line 18). When thedeckarray is initialized, it contains theCards with faces"Ace"through"King"in order for each suit ("Hearts"then"Diamonds"then"Clubs"then"Spades"). We use arrays of

Strings to represent the faces and suits in this example.

DeckOfCardsMethodshuffle

Methodshuffle(lines 30–46) shuffles theCards in the deck. The method loops through all 52Cards (array indices 0 to 51). For eachCard, a number between 0 and 51 is picked randomly to select anotherCard. Next, the currentCardobject and the randomly selected

Cardobject are swapped in the array. This exchange is performed by the three assignments in lines 42–44. The extra variabletemptemporarily stores one of the twoCardobjects be- ing swapped. The swap cannot be performed with only the two statements

Ifdeck[first]is the"Ace"of"Spades"anddeck[second]is the"Queen"of"Hearts", after the first assignment, both array elements contain the"Queen"of"Hearts"and the

"Ace"of"Spades"is lost—hence, the extra variabletempis needed. After theforloop ter- minates, theCardobjects are randomly ordered. A total of only 52 swaps are made in a single pass of the entire array, and the array ofCardobjects is shuffled!

[Note:It’s recommended that you use a so-called unbiased shuffling algorithm for real card games. Such an algorithm ensures that all possible shuffled card sequences are equally likely to occur. A popular unbiased shuffling algorithm is the Fisher-Yates algorithm.]

DeckOfCardsMethoddealCard

MethoddealCard(lines 49–56) deals oneCardin the array. Recall thatcurrentCardin- dicates the index of the nextCardto be dealt (i.e., theCardat the top of the deck). Thus, line 52 comparescurrentCard to the length of thedeckarray. If thedeckis not empty (i.e.,currentCardis less than 52), line 53 returns the “top”Cardand postincrementscur-

rentCardto prepare for the next call todealCard—otherwise,null is returned. Recall from Chapter 3 thatnullrepresents a “reference to nothing.”

Shuffling and Dealing Cards

Figure 7.11 demonstrates classDeckOfCards(Fig. 7.10). Line 9 creates aDeckOfCardsob- ject namedmyDeckOfCards. TheDeckOfCardsconstructor creates the deck with the 52

Cardobjects in order by suit and face. Line 10 invokesmyDeckOfCards’sshufflemethod to rearrange theCardobjects. Lines 13–20 deal all 52Cards and print them in four col-

deck[ first ] = deck[ second ];

deck[ second ] = deck[ first ];

Một phần của tài liệu java for programmeras 2nd edition (Trang 186 - 190)

Tải bản đầy đủ (PDF)

(1.164 trang)