CS594 -- Lab 7

Sokoban Reimplementation in Silhouette


Lab Objective

This lab is designed to give you further experience with using:

  1. a retained object model,
  2. the interactors model, and
  3. constraints

Sokoban Reimplementation

You should re-implement the sokoban game from lab 5 using Silhouette objects to display all the graphics, Silhouette interactors to implement all the different behaviors, and Silhouette constraints to perform certain alignment and data fetching operations. If you have separated the model and the views correctly, you should not have to change your model code for this lab.


Designing Your Views Using Silhouette

Since you do not have a great deal of experience designing applications using a retained object model, the following hints might help:

  1. Create visual gameboard pieces for every square of the gameboard, including forbidden squares. Forbidden squares can be represented by rectangular gameboard pieces that are drawn in the background color. Each gameboard piece should have a row and column property indicating its position on the board.

  2. Calculate the left and top position of each game piece using constraints. The constraints should use the piece's row and column property to calculate the left and top position.

  3. When the character or a ball moves onto a regular space, do not remove the regular space from the gameboard. Instead, simply let the character or ball move on top of the space object. Since Silhouette redraws overlapping objects correctly, the character or ball will be drawn on top of the space object. By adding the ball and character after the squares/goal squares, you can ensure that the ball/character pieces are always on top. Do not try to use depth numbers, because as explained in another item, you should add the game pieces to a composite object rather than directly to the game canvas. In the text view, the game pieces will all be text objects. To ensure that the ball/character pieces are drawn opaquely, you should make sure they are filled and drawn in the background color.

  4. Make each wall object be a composite object that consists of five objects, a rectangle and four lines. Give the composite object four properties, such as northBoundary, eastBoundary, westBoundary, and southBoundary, that indicate whether each of the four lines should be drawn. Each of the four lines should have a constraint on the visible property that consults the appropriate boundary variable to determine if that line should be visible.

  5. The character can be moved in a variety of ways, including by pressing a key or by dragging with a mouse. Each different move behavior should be implemented as a different interactor that is attached to the character game piece. You can decide for yourself whether the four key presses are bundled into a single interactor or put in four separate interactors.

  6. You can also move a character to an open square by pressing with the left mouse button on that square. You can implement this behavior by creating a single interactor and attaching the interactor to all squares and goal squares.

  7. You should add all the game pieces to a composite shape. That way you can center the composite shape in the game canvas using constraints. It will also simplify the constraints that calculate the game piece's position, since they can simply multiply the row or column numbers by the piece's width and height.

  8. The scoreboard should have at least two objects representing the number of pushes and moves. The two objects should extend the TextShape class and should have an integer value field that holds their current value. The text fields should have constraints that convert the integer value to a string. If you want, you can have two text objects representing the labels and two text objects representing the numbers. Alternatively, you can add a second field to a text object that represents its label, and then have the constraint concatenate the label field with the integer field to create the text that gets displayed.

  9. The gameboard editor should use Silhouette rectangles for the initial squares. Like the pieces in the gameboard, they must use constraints to calculate their position. You can attach interactors to the squares and to the game pieces to implement the various editing and selection operations.


The Use of Constraints

Although I want you to have flexibility in your design, I also want to ensure that you get experience using constraints. Therefore you will be required to use constraints to:

  1. Calculate the x/y positions of your game pieces in the game view and the squares in the gameboard editor.

  2. Calculate the text string values in the score view.

  3. Calculate the visibility of the wall borders.


Submission and Grading

You should submit your source files electronically to the TA using the TA's submit program. The TA should be able to run your program by typing the command:

java sokoban

In this lab points will again be deducted if you do not implement all of the required functionality. As with the first implementation, undo and character dragging with the mouse will count for less so you should focus on the other operations first.


Hints

  1. Your interactors will often not work correctly until you get your constraints to work properly. Hence, if you're having trouble getting your interactors to work, make sure that your constraints are working before you start doing serious debugging work on your interactors.

  2. If your constraints do not seem to be evaluating when one of the variables they reference is changed, make sure that the variable is declared to be a Silhouette property. If the variable is a regular Java type, such as an int, then the constraint will not be notified of the change to the variable and the constraint will not re-evaluate itself.