CMSI 185
Homework #6
Due: 2009-04-30

Finally, the last assignment of the course! The assignment covers these learning objectives:

Your assignment is to work on the following three items, producing several classes that are all required to go into a package called edu.lmu.cs.cards.

  1. There's a Card class, and associated CardValue and Suit classes posted here. One of the problems with this class is that it has a public constructor which will allow people to create millions and millions of card objects, even though all card objects are immutable, hence you need only object for each card. Modify the Card class so that it is impossible to create for than one object for each card. To do this, make the constructor private. Then add a public static method that returns the sole card object for a given rank and suit. (Also change the name of the class CardValue to Rank). For instance, you want your users to write
        Card c = Card.fromRankAndSuit(Rank.TEN, Suit.DIAMONDS);
    
    and then c now refers to the ten of diamonds. To do this, you need to have a private, static field which stores all of the possible cards. The card objects need to be created in a static initializer. The method fromRankAndSuit simply returns a reference to one of the objects stored in this field. Use an array for the pool of card objects.
  2. Create a class called Deck for "normal" decks of cards, that is, decks with the usual 52 cards. Each deck object will be represented with an array of 52 cards — the usual 52 cards. You can't add or remove cards; you can only reorder the cards. The methods you need here are:
  3. Create a class called Hand, which contains a single field that is a list of cards. The methods should include at least the following

Here are the unit tests that your code must pass.

package edu.lmu.cs.games;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import edu.lmu.cs.games.Card.Rank;
import edu.lmu.cs.games.Card.Suit;

/**
 * Unit tester for the card class.
 */
public class CardTest {

    @Test
    public void testRankAndSuitFactoryMethod() {
        Card c = Card.fromRankAndSuit(Rank.SIX, Suit.CLUBS);
        assertEquals(c.getRank(), Rank.SIX);
        assertEquals(c.getSuit(), Suit.CLUBS);
        assertFalse(c.getRank() == Rank.KING);
        assertFalse(c.getSuit() == Suit.SPADES);
        assertEquals(c.toString(), "6C");
    }

    @Test
    public void testDescriptorFactoryMethod() {
        assertCardEquals(Card.fromString("AS"), Rank.ACE, Suit.SPADES);
        assertCardEquals(Card.fromString("2S"), Rank.TWO, Suit.SPADES);
        assertCardEquals(Card.fromString("3S"), Rank.THREE, Suit.SPADES);
        assertCardEquals(Card.fromString("4S"), Rank.FOUR, Suit.SPADES);
        assertCardEquals(Card.fromString("5S"), Rank.FIVE, Suit.SPADES);
        assertCardEquals(Card.fromString("6C"), Rank.SIX, Suit.CLUBS);
        assertCardEquals(Card.fromString("7S"), Rank.SEVEN, Suit.SPADES);
        assertCardEquals(Card.fromString("8S"), Rank.EIGHT, Suit.SPADES);
        assertCardEquals(Card.fromString("9S"), Rank.NINE, Suit.SPADES);
        assertCardEquals(Card.fromString("10H"), Rank.TEN, Suit.HEARTS);
        assertCardEquals(Card.fromString("JS"), Rank.JACK, Suit.SPADES);
        assertCardEquals(Card.fromString("QD"), Rank.QUEEN, Suit.DIAMONDS);
        assertCardEquals(Card.fromString("KS"), Rank.KING, Suit.SPADES);
    }

    @Test
    public void testUnique() {
        Card c1 = Card.fromRankAndSuit(Rank.NINE, Suit.CLUBS);
        Card c2 = Card.fromRankAndSuit(Rank.NINE, Suit.CLUBS);
        assertTrue(c1 == c2);
        c1 = Card.fromString("10S");
        c2 = Card.fromString("10S");
        assertTrue(c1 == c2);
    }

    @Test
    public void testToString() {
        assertCardStringEquals(Rank.ACE, Suit.SPADES, "AS");
        assertCardStringEquals(Rank.TWO, Suit.DIAMONDS, "2D");
        assertCardStringEquals(Rank.THREE, Suit.SPADES, "3S");
        assertCardStringEquals(Rank.FOUR, Suit.SPADES, "4S");
        assertCardStringEquals(Rank.FIVE, Suit.SPADES, "5S");
        assertCardStringEquals(Rank.SIX, Suit.HEARTS, "6H");
        assertCardStringEquals(Rank.SEVEN, Suit.SPADES, "7S");
        assertCardStringEquals(Rank.EIGHT, Suit.SPADES, "8S");
        assertCardStringEquals(Rank.NINE, Suit.SPADES, "9S");
        assertCardStringEquals(Rank.TEN, Suit.SPADES, "10S");
        assertCardStringEquals(Rank.JACK, Suit.SPADES, "JS");
        assertCardStringEquals(Rank.QUEEN, Suit.SPADES, "QS");
        assertCardStringEquals(Rank.KING, Suit.SPADES, "KS");
    }

    // Helper for factory method tests
    private void assertCardEquals(Card card, Rank rank, Suit suit) {
        assertEquals(card.getRank(), rank);
        assertEquals(card.getSuit(), suit);
    }

    // Helper for toString tests
    private void assertCardStringEquals(Rank rank, Suit suit, String expected) {
        assertEquals(Card.fromRankAndSuit(rank, suit).toString(), expected);
    }
}
Missing content Missing content