6.170 Laboratory in Software Engineering
Fall 2002
Problem Set 2: Implementing an Abstract Data Type
Due: Tuesday, September 17, 2002 at 4pm

Handout P2

Quick links:

Contents:

We recommend that you read the entire problem set before you begin work.


Introduction

In this problem set, you will practice reading and interpreting specifications, as well as reading and writing Java source code.  You will implement a pair of classes that will complete the implementation of a poker game, and answer questions about both the code you are given and the code you have written.

To complete this problem set, you will need to know

  1. How to read procedural specifications (requires, modifies, effects)
  2. How to read and write basic Java code
  3. How to run a Java compiler such as javac to create .class files
  4. How to run the Java Virtual Machine (JVM) such as java to execute both your code and staff-provided libraries

Problems

Problem 1: CardValue and CardSuit (20 points)

Read the specifications for CardSuit and CardValue, classes for playing card suits and numbers. Then read over the staff-provided implementations in CardSuit.java and CardValue.java. You may find it helpful to peruse the code in CardSuitTest.javaand CardValueTest.java to see example usages of the classes (albeit in the context of a test driver, rather than application code).

Answer the following questions, writing your answers in the file problem1.txt.

  1. Why are CLUBS, DIAMONDS, HEARTS, and SPADES in CardSuit static?
  2. Why have a separate class for card suits, instead of just having them be integer constants in some other class? I.e., why not write:
    public static final int CLUBS = 1;
    public static final int DIAMONDS = 2;
    public static final int HEARTS = 3;
    public static final int SPADES = 4;
  3. Notice that CardSuit constructor checks to see if the parameter suitName is null before using it. Why isn't this also checked against nullbefore it is used? (this is dereferenced implicitly when accessing, say, smallSuitIcon.)
  4. What is the point of having the CardValue and CardSuit constructors be private?
  5. Why don't CardValue or CardSuit need to override Object.equals?
  6. What are the advantages of having CardValue and CardSuit implement the Comparable interface, as opposed to just creating a method with a different name and signature like boolean isLessThan(CardValue v)? (It might be helpful to follow the link to the Java API docs for Comparable.)


Problem 2: Card (20 points)

Read over the specifications for the Card class. Make sure that you understand the overview and specifications.

Read through the provided skeletal implementation of Card in Card.java. The most significant parts of the provided file are the comments describing how you are to use the provided fields to implement this class.

Fill in an implementation for the methods in the specification ofCard. You may define new private helper methods if you want to, but you probably won't need to.

Also, we have provided a fairly rigorous test suite in CardTest.java. You can run the given test suite with JUnit as you program and evaluate your progress and the correctness of your code.

To run the Card test suite, type the following command:

athena% java junit.swingui.TestRunner ps2.playingcards.CardTest
For a non-graphical alternative method of running JUnit, usejunit.textui.TestRunner instead ofjunit.swingui.TestRunner, as stated in the Hints.

Indicate clearly as a comment in your source code whether or not your code passes all the tests. We will assume that your code fails if you say nothing.


Problem 3: Deck (20 points)

Follow the same procedure given in Problem 2, but this time fill in the blanks for Deck. You can find the skeleton implementation in Deck.java. The same rules apply here (you may add private helper methods as you like).

We have provided a test suite in DeckTest.java. You can run the given test suite with JUnit as you program and evaluate your progress and the correctness of your code.

Indicate clearly as a comment in your source code whether or not your code passes all the tests. We will assume that your code fails if you say nothing.

Problem 4: TwoPair and Straight (30 points)

Now that you have completed the implementation of cards and decks, there are just a couple of pieces left to finish the programming of the PokerGame application. The class PokerRanking is used to compare hands to one another. You must fill in the methods evaluateHand and compareSamePokerRankings in TwoPair.java and Straight.java, which are two sub-classes of PokerRanking. You will need to look at the documentation for the Hand class. You will also probably find it helpful to look at the documentation for the PokerRanking class, since it contains helper methods like findNOfAKinds,removeNCardsWithValue, and isValidHand that could be useful.

We have provided test suites in TwoPairTest.java and StraightTest.java. You may also need to refer to the test suites' superclass GeneralRankingTest.java.

Indicate clearly as a comment in your source code whether or not your code passes all the tests. We will assume that your code fails if you say nothing.

Problem 5: Module Dependency Diagram (5 points)

Draw a diagram showing the classes in the ps2.playingcards package (CardValue, CardSuit, Card, and Deck) and their dependences --- i.e., the classes that they use or depend on.  Your diagram should represent a class by a labeled box, and a dependence by an arrow drawn from one class to another.

We will see formal rules for drawing these kinds of diagrams in a later lecture (if you want a preview, look at section 13.2 in the textbook).  Don't worry too much about the rules for now.  Your goal is to capture the structure of the program in your diagram, for another programmer who will have to understand and maintain it later.

You should decide which classes you want to include in your diagram.  You need not include any classes of the poker application for which no source code was provided, but you should make a reasonable judgment about which Java library classes and interfaces to include.

You (and your TA) may find it useful if you use Visio or Dia to generate the diagram. Refer to the Tools Handout for more information about Visio and Dia.


Problem 6: Playing the Game (5 points)

Now that you have implemented all parts of the poker application, you can run the game by typing the following command:
athena% java ps2.PokerGame
Play a few hands of poker against the computer. Provide a screen shot of the application at this point. You can create screen shots on Athena by using the xv Grab command:
athena% add graphics
athena% xv
Right-click on the xv window to bring up its control panel, on which you'll see the Grab button.

On a Windows machine, you can use Alt-PrtScn to copy the current window to the clipboard.  You can then paste it into a document and print it.

End of Problem Set 2. Please see Problem Set Submission instructions.


Getting started

Make sure you have followed the instructions on the tools handout relevant to directory setup and using Java before you begin development.

If you are doing the problem set on Athena, then you can easily get all the source files by running the command get-ps2-files.   Fill in the skeleton source files, and test your implementation. You do not need to compile the other source code files that we have provided; compiled class files are already ready for your use in the 6.170 locker.

If you are not doing the problem set on Athena, follow the instructions above to copy the skeleton source code into your ~/6.170/ps2 directory, then download the files to your machine.  Some of the provided code is in the package ps2.playingcards, and some is in ps2.hand. Java requires that the directory structure follows the package structure. So, when you copy the files, you will need to put them in the following directory structure on your machine:

    ps2/
playingcards/
CardSuit.java
CardSuitTest.java
CardValue.java
CardValueTest.java
Card.java
CardTest.java
Deck.java
DeckTest.java
hand/
TwoPair.java
TwoPairTest.java
Straight.java
StraightTest.java
GeneralRankingTest.java
If you are not doing the problem set on Athena, you will also need ps2-lib.jar and junit.jar from /mit/6.170/lib, which contain the rest of the poker game code and the JUnit test framework, respectively.

In any case, your code MUST work on Athena, so if you choose to work on a non-Athena machine, please take a few minutes before submission of your exercises to ensure that it runs correctly on Athena. 

By the end of the problem set, you should have the following files in the~/6.170/ps2/directory on Athena, ready to submit:

All these files, plus your MDD and screenshot, should also be handed in as hardcopy, as described in the Problem Set Submission instructions.

Hints

See the problem set guidelines and advice. Think before you code!

JUnit reloads all of your classes each time you run a test, so you don't need to restart the JUnit application after making changes to your Java code (though you do need to recompile your code for the changes to take effect).

For a non-graphical alternative method of running JUnit, usejunit.textui.TestRunner instead ofjunit.swingui.TestRunner .

The provided test suites in problem set 2 are the same ones we will be using to grade your implementation; in later problem sets the staff will not provide such a thorough set of test cases to run on your implementations, but for this problem set you can consider the provided set of tests to be rigorous enough that you do not need to write your own tests.

Errata

All announcements (MOTDs) related to PS2 are periodically added here.

Thursday, 12 September 2002


Q & A

This section will list clarifications and answers to common questions about problem sets. We'll try to keep it as up-to-date as possible, so this should be the first place to look (after carefully rereading the problem set handout and the specifications) when you have a problem.
Q: What is the definition of "two pair" and "straight"?

A: Two pair is a poker hand in which one pair of cards share the same value and another pair of cards share another (different) value. The remaining cards are arbitrary.  An example is (Ace of Clubs, Ace of Hearts, 10 of Spades, 10 of Hearts, Jack of Diamonds) -- the two pairs are Aces and 10s.  Another example of two pair is (7, 7, 7, 2, 2), in which the two pairs are 7s and 2s.  This hand is also a full house.

A straight is a poker hand in which all the card values form an uninterrupted sequence, such as (2, 3, 4, 5, 6).  Aces may be either low or high, so (Ace, 2, 3, 4, 5) and (10, Jack, Queen, King, Ace) are both straights.

For more information, see Poker Hand Ranking.

Q:
When I implement Deck.listCards(), can I just return an iterator created directly from the cards collection, i.e. cards.iterator()?

A: No!  That approach is dangerous.  Unlike the iterators in the class text, Java iterators include a removemethod, which would allow clients to change your Deck's representation behind your back.  This problem is called rep exposure, and we'll see more about its subtleties and dangers in lecture next week.  You can avoid this problem in two ways.  One way is to make a copy of the card list.  The other way is to return an unmodifiable view of the list, using Collections.unmodifiableList().

Q:
I experienced a problem with Visio 2000 popping up an error dialog on starup that says, "The procedure entry point GBL could not be located in the dynamic link library VISLIB32.DLL."? I am installing Visio 2000 on a Windows 2000 machine.
A: Refer to Microsoft Support: Visio2000: Error Message: The Procedure Entry Point GBL Could Not Be Located in the Dynamic Link Library Vislib32.dll.

Q: Where can I find the JUnit API?
A: The JUnit API can be found here.


Back to the Problem Sets.
For problems or questions regarding this page, contact: 6.170-webmaster@mit.edu.

$Id: ps2.html,v 1.7 2002/09/14 02:15:56 rcm Exp $