< Ch. 9 Lab - A Card Game Apllet

In the Laboratory: A Card-Game Applet

The purpose of this lab is to complete a card playing program using the Card and Deck classes just described. The objectives of this lab are

Problem Description

Write an applet that lets the user shuffle, sort, and display a deck of playing cards. The cards will be represented by the Card class, and deck of cards will be represented by the Deck class. In its completed form the applet will display cards from a set of 53 Images.

However, since it will be too time consuming to load this many images each time you wish to test your program, Card.toString() will be used to represent cards during program development -- for example, ``2C'' (2 of clubs), ``JD'' (jack of diamonds). After all other methods are developed and tested, the 53 Images will be incorporated into the applet.

GUI Specifications

The Graphical User Interface (GUI) for this applet should contain buttons labeled Shuffle, Sort, and Show/Hide Deck. Shuffling a deck is a matter of rearranging its cards. Sorting a deck will involve putting the deck into its original order, as specified below.

Showing and Hiding the deck should work like a toggle button. If the deck is currently displayed face up, the button should be labeled ``Hide Deck,'' and when it is clicked, it should redisplay the deck face down, and it should toggle its label to ``Show Deck.'' Similarly, if the deck is currently face down, the button should be labeled ``Show Deck,'' and when it is clicked, it should redisplay the deck face up and toggle the button's label to ``Hide Deck.'' (You may wish to use an instance of the ToggleButton class for this button. This class was defined in Chapter 4.)

During program development, the deck should be displayed by painting the String representation of each card on the applet (Figure 1).


  
Figure 1: The string-based user interface for CardDeckApplet.
\begin{figure}
\rule{4.75in}{.05cm}
\epsfig {file=/home/ram/java/text/ch8-arrays/figures/deck.eps}
\rule{4.75in}{.05cm}\end{figure}

You needn't implement the layout shown here, but your layout should be able to display all 52 cards of the deck in some coherent way. To help with this task, the Card.toString() method returns a string representation of the card as ``2C'' (2 of clubs) or ``AS'' (ace of spaces). The applet code may have to break this string apart in order to display the card properly.

Problem Design: The Deck Class

To complete the Deck class you must implement the shuffleDeck() and sortDeck() methods, which were outlined in the specification given in this chapter. The algorithms for shuffling and sorting the deck are discussed next.

Problem Design: The CardApplet Class

CardApplet requires instance variables for the three Buttons and the Deck. In addition it will be useful to have a private instance variable to keep track of whether the deck is currently face up or face down. This variable can be re-set each time the Show/Hide button is clicked.

CardApplet must implement three methods: an init() method, where the applet's components are instantiated and added to the applet's interface, a paint() method, which handles the painting of the deck, and an actionPerformed() method, which handles clicks on the three buttons.

Algorithm Design: Shuffling the Deck

Shuffling  a deck can be simulated by repeatedly swapping two random cards in the deck, as described in the following pseudocode:

    For some number of swaps // 26 swaps or so
        Pick random card1      // Pick two random cards
        Pick random card2 
        Swap card1 and card2   // Swap their locations in the deck

Algorithm Design: Sorting the Deck

The task of sorting  the deck can use a variation of either the bubbleSort() or the selectionSort() algorithms that were described in this chapter. Of course these algorithms must be adapted to work on Card objects.

In order to sort an array of Card objects, it's important to remember that when comparing two Cards, you must compare their respective ranks. But when swapping two Cards, you must exchange the Cards themselves in the array. The syntax for comparing two cards would be something like this:

    if (deck[currentCard].rank < deck[smallestCard].rank) ...

You must use dot notation to refer the the Card's rank, which is a public instance variable. On the other hand, when you swap two Cards, you must swap the entire object, not just its rank. As described in this chapter, this means you will need a temporary Card variable, and you would use it to swap deck[currentCard] and deck[smallestCard].

Adding Images to the Applet

After you have completed the implementation of CardApplet using Strings to display the cards, you may wish to utilize the card images provided for this lab (Figure 2). The card images were originally downloaded (with permission) from

    http://www.waste.org/~oxymoron/

using a Web browser. They should be stored in the same folder as your applet's class files. Once you have downloaded the images, you must implement code in the applet to display the Card's image  instead of its String representation. You must also implement the code in the Deck() constructor that assigns the image to each individual Card. But beware: Loading 53 card images may take a few seconds!


  
Figure 2: The user interface for CardDeckApplet.
\begin{figure}
\rule{4.75in}{.05cm}

\epsfig {file=/home/ram/java/text/ch8-arrays/figures/deck2.eps}
\rule{4.75in}{.05cm}\end{figure}

Optional Exercise

Extend your program to play a hand of Acey-Deucy. In this game two cards are dealt face up. The player decides either to ``hit me!'' or ``pass!'' If the player takes a hit, a third card is dealt. If it falls between the other two cards, the player wins. If not, the player loses. For example, if an ace and a deuce are dealt, and the player draws an ace, the player loses.

You can implement the applet portion of this game with two additional buttons. The first button, call it ``Deal,'' deals a new hand off the top of the deck each time it is clicked. The second button, call it ``Hit Me,'' deals the third card. To implement scorekeeping for this game, it will be necessary to design a method which decides for a given card, whether it falls between two other cards. One way to do this might be to design a Card method that takes two Card parameters and returns a boolean:

    public boolean isBetween(Card c1, Card c2){}



Ralph Morelli {Faculty}
12/22/1999