Assignment 3: Interface Design & Representation Design
Due: Mon 10/08 at 8:59pm. Self-evaluation due Tue 10/09 at 9:59pm
Starter files: code.zip
1 Purpose
The goal of this assignment is to practice writing a controller. While the model in a program represents the game state, the controller “runs” the program, effectively facilitating it through a sequence of operations. This assignment mimics the style of the previous assignment, in that you are provided an interface that you must implement and adequately test. The class you implement will act as the controller and work with the model that you created in Assignment 2: The Model. This controller will “run” a game of Marble Solitaire, asking for input and printing the game state. Since the game will still be text-based and the I/O will be limited to the console and keyboard, the notion of a “view” will be minimal in this assignment.
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 assignment. However, please ensure
all of your new code is in the cs3500.marblesolitaire.controller
package. Additionally, your
code from Assignment 2 should remain in the cs3500.marblesolitaire.model.hw02
package.
2 The Controller interface
The interface for the Marble Solitaire controller must support the following functionality (as an interface MarbleSolitaireController
):
A method
void playGame(MarbleSolitaireModel model)
. This method should play a new game of Marble Solitaire using the provided model. It should throw anIllegalArgumentException
if the provided model isnull
. It should throw anIllegalStateException
only if the controller is unable to successfully receive input or transmit output. The nature of input/output will be an implementation detail (see below).
3 The Controller implementation
Write a class MarbleSolitaireControllerImpl
that implements the MarbleSolitaireController
interface above. You will need to:
Think about which additional fields and types it needs to implement the promised functionality.
Write a constructor
MarbleSolitaireControllerImpl(Readable rd, Appendable ap) throws IllegalArgumentException
.Readable
andAppendable
are two existing interfaces in Java that abstract input and output respectively. It should throw theIllegalArgumentException
if and only either of its arguments arenull
.Your controller should accept and store these objects for doing input and output. Any input coming from the user will be received via the
Readable
object, and any output sent to the user should be written to theAppendable
object.Hint: 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 suitable data from aReadable
object. TheScanner
may offer a way out.The
void playGame(MarbleSolitaireModel model)
method should play a game. It should “run” the game in the following sequence until the game is over.NOTE: Each transmission described below should end with a newline.
Transmit game state to the
Appendable
object exactly as the model provides it.Transmit
"Score: N"
, replacing N with the actual score.If the game is ongoing, obtain the next user input from the
Readable
object. A user input consists of the following four individual values (separated by spaces or newlines):The row number of the position from where a marble is to be moved.
The column number of the position from where a marble is to be moved.
The row number of the position to where a marble is to be moved.
The column number of the position to where a marble is to be moved.
Note: To make the inputs more user-friendly, all row and columns numbers in the input begin 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 wonis over, the method should transmit each of the following in order: the message"Game over!"
, the final game state, and the message"Score: N"
with N replaced by the final score. The method should then end.For example:
Game over! _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ O _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Score: 1
Key points:
Quitting: If at any point, the next value is either the letter
'q'
or the letter'Q'
, the controller should transmit the following in order: the message "Game quit!", the message "State of game when quit:", the current game state, and the message "Score: N" with N replaced by the final score. The method should then end.For example:
Game quit! State of game when quit: O O O O _ O O O O _ O O O O O O O O O O O O O O O O O O O O O O O Score: 31
Bad inputs: If any individual value is unexpected (i.e. something other than
'q'
,'Q'
or a positive number) it should ask the user to re-enter that value again. If the user entered the from-row and from-column correctly but the to-row incorrectly, the controller should continue attempting to read a value for to-row before moving on to read the value for to-column. Once all four values are successfully read, if the move was invalid as signaled by the model, the controller should transmit a message to theAppendable
object saying"Invalid move. Play again. X"
where X is any informative message about why the move was invalid (all on one line), and resume waiting for valid input.Error handling: The
playGame
method should throw anIllegalArgumentException
if a null model is passed to it. If theAppendable
object is unable to transmit output or theReadable
object is unable to provide inputs (for whatever reason), theplayGame
method should throw anIllegalStateException
to its caller. TheplayGame
method must not throw any other exceptions, not should it propagate any exceptions thrown by the model.
Write sufficient tests to be confident that your code is correct. Note: once the model has been tested thoroughly (which you hopefully did in Assignment 2), 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 (
MarbleSolitaireModel.java
)Implementation of your interface (
MarbleSolitaireModelImpl.java
)Your interface (
MarbleSolitaireController.java
)Implementation of your interface (
MarbleSolitaireControllerImpl.java
)Any additional classes necessary to compile your code
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,
How well your code follows the design principles discussed so far,
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.