Milestone 1 Friday, October 14th by 11:59 PM

Milestone 2 Friday, November 4th by 11:59 PM

Getting Started

Download CS201_Assign04.zip and import it into Eclipse. You should see a project called CS201_Assign04 in your Eclipse workspace.

This is a substantial project. Do not wait until the last minute to start it!

Note that there is an extra credit option: see the Insane Extra Credit section under Grading.

Your task

Your task is to implement classes that model the game of Klondike Solitaire. A very complete set of JUnit tests is provided; if the tests pass, then you can have a high degree of confidence that your code is working correctly.

There are two milestones:

Implementations of the Rank and Suit enumerations, and the Card class, are provided. These are very similar to the ones you developed in Lab 9 and Lab 10.

A few other enumerations and classes are provided. The Color enumeration represents the color of a suit: you can call the getColor method on a Suit value to determine the suit’s color (red or black.) The LocationType enumeration represents the different types of locations in the game, main deck, waste pile, foundation, and tableau. The Location class represents a location where a card (or cards) can be drawn from or moved to.

These are the classes you will need to complete:

There are very detailed comments for each method you will need to implement. You can also view the API documentation for the project.

The unit tests for KlondikeController are the most extensive and detailed tests, since they test the game logic. Note that these tests use two saved game states. You can view the image files testgame.png and testgame2.png, in the same directory as the test classes, to view these game states.

Extremely important: Do not change the name, visibility, return type, or parameter types of any of the methods in the classes you will be implementing. I will use JUnit tests to test your implementation, and my tests will not work if you modify the API of these classes. You are welcome to add additional methods: just don't change the existing ones.

Rules of the game

You can see the rules of the game in action with the following demo: klondike-obfuscated.jar

A game of Klondike consists of

A tableau pile consists of 0 or more hidden cards at the bottom of the pile. If a tableau pile is non-empty, then it has at least one exposed card on the top of the pile. A tableau pile may have more than one exposed card. Note that a tableau pile never contains a hidden card placed on top of an exposed card.

At the beginning of the game, the first tableau pile has one card, the second has two cards, etc.

A foundation pile contains cards of the same suit, arranged in order from Ace at the bottom of the pile to King at the top of the pile. (In Klondike, Aces are low.) There are four foundation piles, one for each suit.

On each turn, a player may either

Drawing a card from the main deck means removing the current top card and placing it in a waste pile. The new top card on the main deck is then exposed. If the main deck is empty, then all of the cards are transferred from the waste pile back to the main deck. (Following the transfer of cards from the waste pile back to the main deck, they should appear in the order in which they originally occurred.)

Moving a card transfers one or more cards from either the main deck or a tableau pile to a tableau pile or a foundation pile. Moves must be done following the rules of the game, which are as follows:

Following a move, the top card of the pile the card or cards were moved from is exposed (if the pile is not empty.)

Hints

There is a Color enumeration to represent suit color, with two members, Color.RED and Color.BLACK. You can call the getColor method on a Suit value to get the suit’s color. For example:

Suit s1 = ..., s2 = ...; // assume that s1 and s2 are Suit values

if (s1.getColor() == s2.getColor()) {
    // s1 and s2 have the same suit color
} else {
    // s1 and s2 have different suit colors
}

The rules for placing a card on a tableau or foundation pile involve comparing the rank of the placed card to the rank of the top card on the pile. For example, to place a card on a tableau pile, its rank must be one less than the top card on the pile. You can call the ordinal method on any enumeration value (including members of the Rank enumeration) to find out its position in the enumeration: the first member has ordinal value 0, the second has ordinal value 1, etc. So, your code for placing a card on a tableau pile might look something like this:

Card topCard = ...;   // top card on a tableau pile
Card placeCard = ...; // card being placed on the tableau pile

Rank topCardRank = topCard.getRank();
Rank placeCardRank = placeCard.getRank();

if (placeCardRank.ordinal() == topCardRank.ordinal() - 1) {
    // card being placed has a rank one less than
    // the top card's rank
}

Grading

Milestone 1:

Milestone 2:

For both milestones, points may be deducted for poor coding style, including:

Insane Extra Credit

For up to 50 points extra credit (i.e., a maximum grade of up to 150/100), implement a GUI like the one linked in the “Rules of the game” section. It should look something like this (click for larger image):

Screenshot

A partial GUI implementation is given to you in KlondikeView. If your classes are working correctly, it should show you an initial game state. You will need to handle mouse events to allow the player to draw a card, move cards, etc.

Important: Make sure all of the unit tests pass before you start working on the GUI. Also, make sure that your GUI code does not cause any of the unit tests to fail. (Your GUI code should not require any changes to your problem domain classes.)

Submitting

Save the project (CS201_Assign04) to a zip file by right-clicking it and choosing

Export…→Archive File

Upload the saved zip file to the Marmoset server as assign04_ms1 (Milestone 1) or assign04_ms2 (Milestone 2). The server URL is

https://cs.ycp.edu/marmoset/