Assignment 3: Interface Design & Representation Design
Due: Fri 10/07Sat 10/08 at
8:59pm. Self-evaluation due Sat 10/08Sun 10/09 at 8:59pm
Starter files: code.zip
1 Purpose
The goal of this homework is to practice writing a controller. While the model in a program represents the state, the controller “runs” the program, effectively facilitating through a sequence of operations. You will follow the same "interface-implementation" method of creating the controller, and will use the model that you created in Assignment 2: The Model. Specifically you will write a controller that will “run” a game of Freecell, asking the user for input and printing the game state to output.
The only starter file is a type-checking file. You are expected to use your code
from Assignment 2 as the starting point for this homework. However, please ensure
all of your new code is in the cs3500.hw03
package. Additionally, your
code from Assignment 2 should remain in the cs3500.hw02
package.
2 The Controller interface
The interface for the Freecell controller must support the following functionality
(as an interface IFreeCellController<K>
, parameterized over your card type):
A method
void playGame(List<K> deck, IFreeCellModel<K> model, int numCascades, int numOpens, boolean shuffle)
. This method should start a new game of Freecell using the provided model, number of cascade and open piles and the provided deck. If "shuffle" is set to false the deck must be used as-is, else the deck should be shuffled. It should throw anIllegalStateException
only if the controller has not been initialized properly to receive input and transmit output. The nature of input/output will be an implementation detail (see below).
3 The Controller implementation
Write a class FreeCellController
that implements the
IFreeCellController<K>
interface above. You will need to:
Think about which additional fields and types it needs to implement the promised functionality.
Write a constructor
FreeCellController(Readable rd, Appendable ap)
.Readable
andAppendable
are two existing interfaces in Java that abstract input and output respectively.Your controller should accept and store these objects for doing input and output. In the game, whenever you need take user input, use the
Readable
object and whenever you wish to transmit output, use theAppendable
object.Look at the
Readable
andAppendable
interfaces to see how to read from and write to them. Ultimately you must figure out a way to transmit aString
to anAppendable
and read integers and strings from aReadable
object. TheScanner
may offer a way out.The
void playGame(List<K> deck, IFreeCellModel<K> model, int numCascades, int numOpens, boolean shuffle)
method should, obviously, play a game. To do so, it should ask the provided model to start a game with the provided parameters, and then “run” the game in the following sequence until the game is over:Transmit game state to the
Appendable
object exactly as the model provides it.If the game is ongoing, wait for user input from the
Readable
object. A valid user input for a move is a sequence of three inputs (separated by spaces or newlines):The source pile (e.g.,
"C1"
, as a single word). The pile number begins at 1, so that it is more human-friendly.The card index, again with the index beginning at 1.
The destination pile (e.g.,
"F2"
, as a single word). The pile number is again counted from 1.
The controller will parse these inputs and pass the information on to the model to make the move. See below for more detail.
If the game has been won, the method should transmit the final game state, and a message "Game over." on a new line and return.
Key points:
The deck: The deck to be used is the one provided as input, and not necessarily the one returned from the model. (Why is this very important?)
Quitting: If at any point, the input is either the letter
'q'
or the letter'Q'
, the controller should write the message"Game quit prematurely."
on a separate line to theAppendable
object, and return.Invalid game parameters: If the game parameters are invalid (e.g., invalid number of cascade/open piles) and the model throws an exception as a result, the controller should transmit a message "Could not start game." and return
Bad inputs: If an input is unexpected (i.e. something other than
'q'
or'Q'
to quit the game; a letter other than'C'
,'F'
,'O'
to name a pile; anything that cannot be parsed to a valid number after the pile letter; anything that is not a number for the card index) it should ask the user to input it again. If the user entered the source pile correctly but the card index incorrectly, the controller should ask for only the card index again, not the source pile, and likewise for the destination pile. If the move was invalid as signalled by the model, the controller should transmit a message to theAppendable
object "Invalid move. Try again." plus any informative message about why the move was invalid (all on one line), and resume waiting for valid input.Error handling: The controller should throw an
IllegalStateException
if either of itsReadable
andAppendable
objects have not been initialized (i.e. if they arenull
). It should throw anIllegalArgumentException
if a null deck or model is passed to it. The controller should not propagate any exceptions thrown by the model to its caller.
Write sufficient tests to be confident that your code is correct. Note: once the model has been tested thoroughly (which you did on Assignment 2...right?), all that remains to be tested is whether the controller works correctly in all cases.
Be sure to properly document your code with Javadoc as appropriate. Method implementations that inherit Javadoc need not provide their own unless their contract differs from the inherited documentation.
4 Deliverables
At a minimum, we need the following files:
Your interface (
IFreeCellModel.java
)Implementation of your interface (
FreeCellModel.java
)Your interface (
IFreeCellController.java
)Implementation of your interface (
FreeCellController.java
)Your
Card
implementation (and interface if you had one)any additional classes you saw fit to write
Tests for all your implementations in one or more JUnit test classes. You should include at least all your tests from Assignment 2, and add to them...
As with Assignment 2, please submit a zip containing the src/
and
test/
directories with no surrounding directories, so that the
autograder recognizes your package structure.
5 Grading standards
For this assignment, you will be graded on
Whether your interfaces specify all necessary operations with appropriate method signatures,
whether your code implements the specifications (functional correctness),
the clarity of your code,
the comprehensiveness of your test coverage, and
how well you follow the style guide.
6 Submission
Please submit your homework by the above deadline. Then be sure to complete your self evaluation by the second deadline.