Assignment 2: The Model
1 Purpose
2 The game of Freecell
2.1 Context
2.1.1 Game play
3 Building Freecell
3.1 Cards
3.2 The Freecell operations
3.3 Examples
3.4 Your Implementation
3.5 Testing
4 List of Deliverables
5 Grading Standards
6 Submission
7.5

Assignment 2: The Model

Due: Thu 01/30 at 9:00pm; self-evaluation due Fri 01/31 at 10:00pm

Starter files: code

Note: The description may make assignments seem longer than they are. Distilling the description to make a list of all the things you are actually supposed to do will go a long way in having a good plan to tackle it. Read the description several times to confirm this list before acting on it!

1 Purpose

The primary goal of this assignment is to practice implementing an interface based on given specifications, and by choosing an appropriate data representation that helps in providing the functionality promised by the interface.

Please ensure all of your source code is in the cs3500.freecell.hw02 package. Test code should be in the default package.

2 The game of Freecell

2.1 Context

In the next three homeworks, you will implement the popular single-player game “Freecell.” Freecell is a Solitaire-type game, which uses the regular deck of 52 suit-value cards. There are four suits: clubs (♣), diamonds (♦), hearts (♥), and spades (♠). Hearts and diamonds are colored red; clubs and spades are colored black. There are thirteen values: ace (written A), two through ten (written 2 through 10), jack (J), queen (Q) and king (K). In Freecell, aces are considered “low,” or less than a two. (In other games, they’re considered “high,” or greater than a king.)

The game play is divided among three types of card piles. First, there are four foundation piles, one for each suit (shown in the top right in figure above), and indexed 1 through 4. These four piles are initially empty, and the goal of Freecell is to collect all cards of all suits in their respective foundation piles. A card can be added to a foundation pile if and only if its suit matches that of the pile, and its value is one more than that of the card currently on top of the pile (i.e., the next card in foundation pile 2 in the figure above can only be 3♣). If a foundation pile is currently empty, any ace can be added to it: there is no required ordering of suits in the foundation piles. Note that in the figure above, the 2♣ has an A♣ underneath it, and the 2♥ has an A♥ underneath it, though these aces are not visible.

The second type of pile is the cascade pile (the eight piles in the bottom of figure above), also indexed starting from 1. Usually a game of Freecell has eight cascade piles, but our game will allow as few as four. Because the initial deal of the game is shuffled (see below), a cascade pile may initially contain cards in any order. However, a card from some pile can be moved to the end of a cascade pile if and only if its color is different from that of the currently last card, and its value is exactly one less than that of the currently last card (e.g. in the figure above, the next card in cascade pile 1 can be 4♦ or 4♥ while the next card in cascade pile 3 can be 10♠ or 10♣). This sequence of decreasing-value, alternating-color cards is called a build. (Different variants of Freecell, or other solitaire games, differ primarily in what builds are permitted.)

Finally, the third type of pile is the open pile (top left in figure above). Usually a game of Freecell has four open piles, but our game will allow as few as one. An open pile may contain at most one card. An open pile is usually used as a temporary buffer during the game to hold cards.

2.1.1 Game play

Play starts by dealing the full deck of 52 cards among the cascade piles, in a round-robin fashion (e.g. in a game with eight cascade piles, pile 1 will have card indices 0, 8, 16,..., pile 2 will have card indices 1, 9, 17, ... and so on (assuming card indices in the deck begin at 0). The player then moves cards between piles, obeying the rules above. The objective of the game is to collect all cards in the four foundation piles, at which stage the game is over.

In this homework you will write the model for this game. The model will maintain the game state and allow a client to start a game and move cards.

3 Building Freecell

3.1 Cards

Start by modeling a card in the game of Freecell. You are free to name the class and its methods whatever you want.

3.2 The Freecell operations

In order to play the game, one would expect the following operations: get a valid deck of cards, start a new game, and make a move. These operations have been specified and documented in the provided FreecellOperations<K> interface. In this interface, K is the card type (because we do not know in advance what you may choose to name your card type). You are not allowed to change the interface in any way!

A short explanation of the methods in the interface follows:

3.3 Examples

You must check that your FreecellModel implementation of the FreecellOperations interface works as specified. Please review the testing recommendations. Since you are testing the public-facing behavior of this interface, following those guidelines means that you should not place this testing code in the cs3500.freecell.hw02 package, but rather place it in the default package. Nothing in your tests should rely on implementation details at all.

3.4 Your Implementation

Implement the FreecellOperations<K> interface in a class called FreecellModel. You will need to:

  1. Design a representation for the game skeleton. Think carefully about what fields and types you need to represent the game state, and how possible values of the fields correspond to game states.

  2. Cards:

    • A correct deck of cards for Freecell contains 52 cards with ace, 2, ..., jack, queen, king in each of clubs, diamonds, hearts and spades) as a List of card objects. Thus a deck is invalid for this game if it does not have 52 cards, or if there are duplicate cards, or if there are invalid cards (invalid suit or invalid number).

    • A client for your Card implementation should be able to use its toString method to print them. Cards should be printed as their value, followed by the suit symbol above: for example, "A♦" or "3♣". You may want to copy and paste the suit symbols from this Web page into IntelliJ.

  3. Starting the game: The startGame method should start a new game of Freecell by distributing the deck in round-robin fashion as described above (in Section “Game Play”). It is possible that some cascade piles have more cards than others, and this is OK. This method should first check if the inputs are valid (valid deck, at least 4 cascade piles and at least 1 open pile). If shuffle is true then the cascade piles should look different compared to if it was false.

  4. The game state: The getGameState method may be used to print the game state in the format illustrated below. The details of the output are described in the Javadoc for this method in the provided code. The following shows the output corresponding to the screenshot above:

    F1: A♠
    F2: A♣, 2♣
    F3: A♥, 2♥
    F4:
    O1:
    O2:
    O3:
    O4: 8♦
    C1: K♠, 3♦, K♥, 8♠, 5♥, 5♦, 5♠
    C2: 4♣, 5♣, 4♠, 9♦, K♣
    C3: 2♠, 9♠, 8♣, 10♦, 8♥, Q♠, J♦
    C4: 10♥, J♠, Q♦, 6♣, 3♣, J♣
    C5: 6♦, 3♥, 10♠, Q♥, 6♠
    C6: 9♣, 7♣, 7♥, K♦, 4♥, 3♠, 2♦
    C7: Q♣, J♥, 10♣, 9♥
    C8: 7♦, 7♠, 6♥, A♦, 4♦

    NOTE: The string you return should not have a newline at the end of the last line, and there should be no spaces after the colons for O1, O2 or O3. (Try selecting and highlighting this text in your browser, to see exactly where the lines end.)

    If a game has not begun, getGameState should return an empty string.

  5. Move: The move method should work to move only one card at a time. This means that only the last card in a cascade pile can be moved to another pile. Any other kind of move is invalid for this implementation.

  6. Constructing the model: Your class should have a public default constructor (i.e., with zero arguments) for your class, and also any other constructors you think are needed. Reminder: A constructor is a good place to initialize any instance variables.

Be sure to properly document your code with Javadoc as appropriate. Method implementations that inherit Javadoc need not provide their own unless they implement something different or in addition to what is specified in the inherited documentation.

File Hw02TypeChecks.java contains a small class designed to help you detect when your code may not compile against the grading tests. In particular, if your project cannot compile while Hw02TypeChecks.javaunmodified!—is a part of it, then it won’t compile for the course staff either.

3.5 Testing

Read the testing recommendations again.

4 List of Deliverables

Again, please ensure all of your project’s source is in the cs3500.freecell.hw02 package. The autograder will give you an automatic 0 if it cannot compile your code! Place your tests in the default package.

5 Grading Standards

For this assignment, you will be graded on

6 Submission

Wait! Please read the assignment again and verify that you have not forgotten anything!

Please compress the src/ and test/ folders into a zip file and submit it. After submission, check your submitted code to ensure that you see two top-level folders: src/ and test/. If you see anything else, you did not create the zip file correctly!

Please submit your assignment to https://handins.ccs.neu.edu/ by the above deadline. Then be sure to complete your self evaluation by the second deadline.