CSE 373 Winter 2005
Homework #3 DRAFT
Towers Game (I)
Due Dates
Mock-up: On paper at beginning of class, Monday Feb. 7 (see
"Getting Started").
Files: Electronically Thursday Feb. 11 8:00 pm; paperwork at beginning
of
class Friday. (Tentative: The electronic turn-in will be
done by giving us a single .jar or .zip file.)
Objectives
- Experience a more complexly packaged Java project.
- To review (or learn) some basic drawing and GUI programming in
Java.
- Experience testing with modules from unknown sources, of unknown
quality and characteristics (but known interfaces)
- Exercise the choice of data structures
Description
The Towers of Hanoi is a famous puzzle. For generations of data
structures students it has served as an example of recursion. You
can find the puzzle explained, and solved, in our textbook.
Your task is not to implement the solution! Rather, it is to
design an interactive version of the puzzle so that a player could try
to solve it manually, one move at a time. The puzzle becomes
a
kind of one-player game. The player is allowed to back up in
order to try different sets of moves. In implementing this game,
you will have to choose
some data structures and apply them in your program.
In order to gain a fresh perspective on testing, this project is
organized in a very specific way. You will have to follow
carefully the rules about where files are located, what classes are
named and what interfaces they contain, and so forth. These
limitations will eventually allow you to easily combine parts of your
version of the project with missing parts written by others (including
your classmates).
Despite the restrictions, there will actually be a lot of freedom in
certain respects. In particular, the way you control the game
(user inputs, etc.) and display the state (the towers, etc.) is limited
only by your creativity, programming ability, and screen size (and your
time, of course!).
The packaging constraints and requirements are complex enough there's a
good chance these instructions will be flawed in some way and required
you to revise something along the way. Hopefully that will be
minimal.
Overview
When the game runs, the user will see a window (JFrame) with two
panels.
- The top large panel shows the View, that is, some depiction of
the
status of the game. The major part of status is: which disks are
on which
towers. For example, you might draw the towers as poles with the
discs
on them. The View is output-only; it must not have any
interaction with the user.
- The bottom large panel is the Control. On this panel there
might
be buttons or other features for interacting with the user. Your
Control must
- provide a way for the user to start a game from scratch, with
the number of disks and towers being something the user can
select. Games can be started from scratch at any time, without
having to terminate and restart the program.
- provide a way for a user to request a move, by indicating which
are the source and destination towers for moving one disk. It's
always the top disk that is moved.
- There should be a way for the user to back up to the previous
configuration (i.e., undo the last move). In fact, the user
should be able to back up all the way to the initial state. A
back-up does not require the user to know what the previous
move was (the system should do that). Clearly, this is an area
where some data structure will be needed!
- There should be a way for the user to terminate the game.
- Various versions of the main method (TowerStarter) might have a
different layout with additional smaller panels, but the basic idea
will remain.
Structure
In addition to the View and Control, mentioned above, there is to be a
third module called the Model. The model is intended to contain
all of the data structures encoding the state of the game (i.e., what
disks are on what towers). The
View and the Control should not need to keep any information about the
state -- when they need that, they get it from the model.
- The Model is a class named TowerModel, which must implement
mvc373Hw3.ITowerModel, extend JPanel, and be in a package called
towerHw3.tmodel.
- The View is a class named TowerView, which must implement
mvc373Hw3.ITowerView, extend JPanel, and be in a package called
towerHw3.tview.
- The Control is a class named TowerControl, which must implement
mvc373Hw3.ITowerController, and be in a package called towerHw3.tcontroller.
In addition, the main Model, View, and Controller classes must each
contain certain static variables. These must be present and
named exactly as required:
public static final AUTHOR = ...; //Your name or nick-name for public
identification purposes (<25 char.)
public static final SHORT_DESCRIPTION = ...; //a brief (<40
char) description of your module
public static final LONG_DESCRIPTION = ...; //a longer (<300 char)
description of your module.
The interfaces specify certain required public methods. You can
have as many additional methods as you wish in the Model, View, and
Controller classes, but they may not be public. You may not
define any constructors except certain mandatory ones (documented in
the interfaces). Likewise, you can define additional classes
within each of the three packages, but they may not be public.
You may not define anything new within mvc373Hw3. You may not
define any additional packages. You may use any standard Java 1.4
classes.
How does the program start? There will be a class called
TowerStarter, which is given to you. Its main method will
create the
JFrame (window), create instances
of the Model, View, and Controller, and position the View and
Controller (which are also panels) on the window. Your program
must operate
properly when started in this way. Don't modify TowerStarter,
because you won't be allowed to turn it in. There will probably
be revised and improved versions of TowerStarter as time goes by.
A Bigger Picture
Design and program with this goal in mind: if any one of your modules
(say, your View) is combined with the other two models written by
someone else (say, my Controller and some stranger's Model), -- all
three should work perfectly together. This means you must program
for robustness. Make sure each of your modules works reasonably
if it gets bad data or unexpected results from the other modules.
After you have begun to turn-in working versions of your modules
electronically, we will make them available on the Web. There
will be a special tool to make it relatively easy to combine modules
into a single program and run them together. It's to enable this
combining process that the requirements for packaging and naming are so
strict.
The intention is that the modules operate without interfering with one
another. That is, they should be good neighbors. There are
ways you
could mess that up -- but you shouldn't! For example, there is a
way
(if you know how) that the Model could modify the Controller's
panel.
This would be very unneighborly -- downright malicious, in fact.
Any
modules discovered to be engaging in such activities will be removed
and the project not graded.
Looking to the Future
There will be a Part II for this project, with some additional
requirements. In addition, some of the features listed above for
Part I won't be checked or required until Part II. You are free
to postpone them if you feel it makes your life easier. Here they
are:
- The Control does not have to find out from the user how many
towers and disks are desired. The Control can instead use a
default of 3 towers and 8 disks.
- The Model does not have to accept configurations with other than
the default numbers of disks and towers (it can return false from its
start method).
- The Model does not have to honor requests to back up. It
can simply return false.
- The Control does not have to use its panel for a Graphical User
Interface
(GUI). It can use the Java console instead, or a combination of
the console and a GUI, as long as it's clear to a user how to operate
the game.
- The Model has to display its output graphically (on the panel),
but
it does not have to be "graphical". That is, instead of drawing a
tower, the Model could just output some text information (using
Graphics.drawString).
Getting Started
- Read all these instructions on this page -- again.
Carefully.
- Browse the files. The interfaces
need to be studied quite carefully, as they contain a number of
important details not covered in these instructions.
- Set up a project on your local machine with the required package
structure. Download the files into this structure.
- Create versions of the three main classes, implementing the
required methods as stubs -- as brain-dead as possible, just to get
things to compile.
- Implement the required constructors -- as simply as
possible.
- At this point, the TowerStarter program should compile. If
it doesn't, something is wrong with your classes. Did you
remember to extend JPanel for the View and Controller?
- And now, TowerStarter should run! It won't do much except
display a window with panels on it.
- Now, all of the above it just preliminary. Before you go
off on a programming binge, sit down and figure out with pencil and
paper:
- What data structures should the Model contain?
- What should the View panel look like? Draw a sketch.
- What should the Control panel look like? Draw a sketch.
- Don't start programming until you have a good grip on these basic
design decisions.
- Prepare, on paper, a "Mock-Up" to turn in. The mock-up
contains one paragraph describing your planned data structure, plus a
drawing of the window as you want it to look (showing the View and
Control panels).
- If you are new to graphics (Java Swing), get your feet wet by
figuring out how to put a simple text message on the View and
Controller panels. The secret is that all drawing is done by a
method which you MUST NEVER EVER CALL, with the signature public
void paintComponent(Graphics g); This method is called
indirectly when the method public void repaint() is
called. You must not override repaint, but you must override
paintComponent if you want to do any drawing. The first line of
paintComponent should be super.paintComponent(g);
After that you can use g.draw or g.drawString or any of the many
methods which are available. In the View, another secret is that
when you draw, you always draw the entire picture, from scratch.
What you do not do is paint part of it one time and then come back
later and add to it. Paint the entire picture, from scratch, each
time. You may not need any drawing at all in the
Controller. There you will probably add buttons to the panel when
the Controller is constructed. Things like buttons get drawn and
redrawn automatically. You do not have to write code to repaint
them your self.
Turn in:
See the deadlines specified at the beginning of this page.
Paperwork (hard copy) includes printouts
of the programs (the preferred way to do this is to
print the "receipt" you get back from the turn-in form), plus a short
report
which includes:
- Any difficulties you had in general; the list of possibilities is
longer this time than last!
- For each of the three modules, a statement as to what required
features work and what ones didn't work. This could be as simple
as "everything works" (if that's the case!)
- Instructions to the user (game player), if they are not obvious
once the program starts.
- A discussion of the data structures you used (this might be an
expansion of what you wrote for the Mock-up.) A statement about
how the data structures were implemented (i.e, by using standard Java
classes, textbook code, code you wrote from scratch, etc.)
- A discussion of a couple of the key algorithms you implemented
and their complexity.
Please staple everything together. There might not be a stapler
in the classroom, so please do this in advance. Make sure your
name is on everything you turn in! Your student ID is not needed
unless we specifically request it.
MixMatcher
MixMatcher is the tool that will facilitate testing your modules by
combining them with various people's
modules once they are posted on the web. Information about
downloading and using the tool will be available later.
Grading
Most of the grading points will come from
- Correct structuring of the packaging. If this isn't met, the
classes won't compile on our system, and you won't get any
credit. In fact, without proper structuring, TowerStarter won't
compile, unless you modify it -- don't! And don't let your IDE
"helpfully" modify package statements for you.
- Appropriate choice of data structures
- Appropriate and efficient algorithms, given the data structures
- Correct operation of your three modules, run together
- Correct operation of each of your modules, when run with any
correct implementations of the other two
- Robust and reasonable operation of each of your modules, when run
with possibly incorrect implementations of the other two.
- Following instructions and specifications (including what
materials are to be turned in, deadlines, etc. etc.)
- Programming practice (style, comments, etc.)
- The report
Good luck and have fun!
Notes
If you have questions along the way, either about the assignment or how
to do things, feel free to discuss it on the Message Board. Just
don't give away code, or any crucial aspects of the solution.
Where applicable, write your code to be reusable and modifiable.
In a later homework, you might in fact have an opportunity to reuse or
modify code from this one...