Assignment 2: The Model
1 Purpose
2 The game of Freecell
2.1 Context
2.1.1 Game play
2.2 The Interface
2.3 Examples
2.4 Your Implementation
2.5 Testing
3 Package Management
4 List of Deliverables
5 Grading Standards
6 Submission
6.7

Assignment 2: The Model

Due: Tue 09/27 at 8:59pm; self-evaluation due Wed 09/28 at 8:59pm

Starter files: code.zip

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.hw02 package. Your tests may live in whichever package makes the most sense. (See Package Management below.)

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.

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.

2.2 The Interface

You will implement the interface IFreeCellModel<K>, where K is the card type. We deliberately make the interface generic over the card type, because we do not know—or care—exactly how you will choose to model cards themselves; that choice is up to you. The interface has exactly the following methods:

2.3 Examples

You must check that your FreeCellModel implementation of the IFreeCellModel 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.hw02 package, but rather place it in the default package. Nothing in your tests should rely on implementation details at all.

2.4 Your Implementation

Implement the IFreeCellModel<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.

    You are free to represent a single card in any way you wish, and the getDeck method must return a complete standard deck of playing cards (i.e. 52 cards with ace, 2, ..., jack, queen, king in each of clubs, diamonds, hearts and spades) as a List of card objects.

    Validity constraints: A deck is invalid if it does not have 52 cards, or if there are duplicate cards, or if there are invalid cards (invalid suit or invalid number).

    Printing each card: 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♣".

    Your choice of representation may significantly affect how easy or difficult it is to implement the necessary operations, and you will be graded on the appropriateness of this choice. (Hint: A good representation “properly” represents the data and entity that the class is supposed to represent, instead of being convenient for testing and debugging.)

  2. Design the startGame method to start a new game of Freecell by distributing the deck in round-robin fashion as described above. It is possible that some cascade piles have more cards than others, and this is OK. This method should 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.

  3. Design the getGameState method 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.

  4. Design the move method so that only one card can be moved at a time. This means that only the last card in a cascade pile can be moved to another pile.

  5. Implement 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.

2.5 Testing

Read the testing recommendations again.

3 Package Management

To make sure that your packages are in the correct layout, you should tell IntelliJ to do the following. Do this early, before you’ve written much code, to ensure that your files wind up in the right locations automatically, instead of having to fix it afterward:

4 List of Deliverables

Again, please ensure all of your project’s source is in the cs3500.hw02 package. The autograder will give you an automatic 0 if it cannot compile your code! You may place your tests in whichever package makes the most sense.

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 submit your homework to https://cs3500.ccs.neu.edu/ by the above deadline. Then be sure to complete your self evaluation by the second deadline.