Assignment 3: Interface Design & Representation Design
1 Purpose
2 The Controller interface
3 The Controller implementation
4 Deliverables
5 Grading standards
6 Submission
7.4

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):

  1. A method void playGame(MarbleSolitaireModel model). This method should play a new game of Marble Solitaire using the provided model. It should throw an IllegalArgumentException if the provided model is null. It should throw an IllegalStateException 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:

  1. Think about which additional fields and types it needs to implement the promised functionality.

  2. Write a constructor MarbleSolitaireControllerImpl(Readable rd, Appendable ap) throws IllegalArgumentException. Readable and Appendable are two existing interfaces in Java that abstract input and output respectively. It should throw the IllegalArgumentException if and only either of its arguments are null.

    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 the Appendable object.

    Hint: Look at the Readable and Appendable interfaces to see how to read from and write to them. Ultimately you must figure out a way to transmit a String to an Appendable and read suitable data from a Readable object. The Scanner may offer a way out.

  3. 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.

    1. Transmit game state to the Appendable object exactly as the model provides it.

    2. Transmit "Score: N", replacing N with the actual score.

    3. 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):

      1. The row number of the position from where a marble is to be moved.

      2. The column number of the position from where a marble is to be moved.

      3. The row number of the position to where a marble is to be moved.

      4. 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.

    4. 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 the Appendable 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 an IllegalArgumentException if a null model is passed to it. If the Appendable object is unable to transmit output or the Readable object is unable to provide inputs (for whatever reason), the playGame method should throw an IllegalStateException to its caller. The playGame method must not throw any other exceptions, not should it propagate any exceptions thrown by the model.

  4. 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:

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

6 Submission

Please submit your homework by the above deadline. Then be sure to complete your self evaluation by the second deadline.