In this program you will implement a simulation of a mouse looking for a piece of cheese in a maze.
Design a program to simulate mice moving through a maze until they find cheese. A mouse always starts at the starting position, and moves one unit at a time. Your program should be able to support mice with different movement strategies.
Your program should read in a maze configuration, including the starting position and the location of the cheese (the start and end locations for the maze). It should allow the user to run the experiment several times. Each time, a piece of cheese is put at the end of the maze, a mouse is put at the starting location, and the mouse is allowed to move around the maze looking for the cheese. The user should be able to choose the movement strategy for each run of the experiment. Your program should graphically display the state of the mouse and the maze at the end of each time unit. When a mouse finds the cheese, your program should report how many time units it took for the mouse to find the cheese.
Your program should have a graphical user interface with a File menu, a strategy choice menu, a start button, a panel in which the maze is graphically displayed, and a slider bar for changing the speed of the mouse movement. (Actually, it controls the speed of the animation -- how long the program pauses to let you view the display between time steps -- rather than the speed of the mice.)
You may use the following classes or files, which have been fully or partially implemented and are available in MouseInAMaze.zip:
Cheese
- a fully implemented extension of the ColorBlock
class (you could implement it in some other way, though, if you chose)MazeDataFileHandler
- a fully implemented class that reads
the maze information from a file and constructs the mazeMazeGUI
- a partially implemented class that provides a graphical
user interface for the Mouse-in-a-Maze projectMovingStrategy
- a fully defined interfacemaze1.dat
- a sample maze initial configuration filegenericEnv.jar
, mbsbb.jar
, and mbsenv.jar
- Java archive libraries containing classes such as BoundedEnv
,
ColorBlock
, ColorBlockDisplay
, EnvFileChooser
,
etc. The GenericEnvAPI.zip
file contains class documentation for all of the classes in these
libraries.You will need to implement or modify the following classes:
Maze
- an extension of the BoundedEnv
classMazeGUI
- the partially implemented GUI classMouse
- an object that moves around the maze based on a strategyMazeGUI
objectMovingStrategy
interfaceYou will probably find it useful to implement this program in stages (iterative development). For example, you might:
You do not have to develop the program in this way, but if you want to follow this structured approach you will find more details below.
MazeGUI
object.
Look at the MazeGUI
constructor to see what parameters it requires.
(You could use EnvPlotterApp
as a guide, although you will need
to define the background color as well as the width and height of the display
area. MinnowApp
may also be useful, although it does much more
than you need to do.) Add your main class to your project and make it
the target main class.Maze
class that extends BoundedEnv
.
In order for MazeDataFileHandler
to work correctly, the new
class must be called Maze
, it must have a two-parameter constructor
just like BoundedEnv
, and it must have at least two additional
methods: setStartLoc
and setFinishLoc
.
These two methods must both take a single Location
as a parameter
and have a void
return type. Your initial program will
not actually construct a maze yet, so an empty constructor and empty methods
are actually all you need at this time. Mouse
class. In order for MazeDataFileHandler
to work correctly, the new class must be called Mouse
and
it must take three parameters for its constructor: a Maze
,
a starting Location
, and a MovingStrategy
(in
that order). Your initial program will not actually construct a
mouse yet, so an empty constructor is actually all you need at this time.Maze
class as appropriate, and
implement the setStartLoc
and setFinishLoc
methods.
(You can also implement other Maze
methods, such as methods to
find out the start location or finish location, although you don't have to
do that yet.)MazeGUI
class, add the code for the Open option in the
File menu. You can use the code for the Quit option as a guide, although
the keyboard shortcut and actionPerformed
behavior should be
different. Notice that the MazeGUI
class has an openFile
method that you can use.DisplayMap.associate
method that specifies that ColorBlock
objects get displayed using
an object of the ColorBlockDisplay
class. (The MinnowApp
class provides an example of similar code.)maze1.dat
or initial configuration
files of your own making. You may wish to copy the initial configuration
file(s) to the project Data
folder so that you don't have to
navigate around every time you start the application and want to open a file.
(Be sure to copy the files rather than move them, since the project
Data
folder can easily get wiped out.) You should be able
to open a configuration file and see the resulting maze.Maze
class that you could use to find
out where to construct the mouse and where to construct the cheese.Mouse
class implement the Locatable
interface,
so that a mouse can be added to a maze. Make sure that a mouse adds
itself to the maze when it (the mouse) is constructed. Create instance
variables and additional methods if you need them.run
method in the anonymous inner Thread
subclass in the MazeGUI
start
method to construct
a mouse and a piece of cheese and to call the appropriate method in MazeGUI
to display the initial configuration of the maze.MazeGUI
class as necessary in order to add a
Start button in your Control panel. The Control Panel as a whole
will appear to the left (BoundaryLayout.WEST) of the main content panel.enableItemsThatNeedEnvironment
(in MazeGUI
) that enables and disables the Start button appropriately.smallfish.gif
image. Put a copy of it in your project Data
folder
so that the program can find it.) To associate an image with a class,
construct a new ScaledImageDisplay
as the display object, passing
it the name of the image file as a String
parameter (e.g.,
"smallfish.gif"). You can find the class documentation for
ScaledImageDisplay
(and TintedImageDisplay
, see
below) in the GenericEnvAPI folder.
Mouse
class to include a color
method that reports
the color of a mouse. (You can always return the same color (e.g.,
Color.white
), or generate a random color, or specify a mouse's
color as a parameter when you construct the mouse. If you do the latter,
though, you will have to update the way a mouse is constructed in MazeGUI
.)
Then use a TintedImageDisplay
instead of a ScaledImageDisplay
.
This will tint the image with the color specified by the Mouse
color
method.FishDisplay
class
as a model. Your display class should extend ScaledDisplay
rather than RotatedDisplay
unless you plan to add a direction
method to your Mouse
class. Note that a display class assumes
that it is drawing in a 1 x 1 area with the origin at the center of the area.
In other words, the pixels range from -0.5 to 0.5 for both the x and y coordinates.
You can leave out (or comment out) the code for the gradient if you prefer.
(I suggest you not spend time creating a clever MouseDisplay
class until after everything else in your program is working!)Cheese
class, rather than just use an object
of the ColorBlock
class.)MovingStrategy
interface. For example, you might create a class that implements
the random movement (or "clueless mouse") strategy The
toString
method of your new class should return the string
that you want to appear in the pull-down strategy chooser menu.
You can leave the getNextLocation
method empty for now.makeStrategyChooser
method in the MazeGUI
class to add an object of your new class as an item in the combo box.
How do you add items to a combo box? Research the class documentation
for JComboBox
. (Note: You can add any kind of object
to a combo box; it will use the object's toString
method
as the label in pull-down menu. You want to add the actual object
to the box, though, and not just a label, because later, when you want
to know which strategy was selected, you will want to get a strategy object,
not just its name.)makeStrategyChooser
gets added to the same panel as the Start button. You can test your
program at this point, just to make sure that the strategy chooser appears
and has appropriate text in it.toString
methods and leaving their getNextLocation
methods blank.
Add objects of your new classes to the strategy chooser combo box.
Test that the strategy chooser appears and has the appropriate items in
it. getNextLocation
method for one of your strategy
classes. Remember that mice do not just move to empty locations;
they can also move to the location that contains the cheese (which is
in the finish location). If you find yourself comparing locations
to see if they are equal, remember to use the equals
method
rather than the ==
operator.Mouse
class that will move the
mouse to a new location determined by its strategy object. If the
new location contains the cheese, the mouse should eat the cheese (remove
it from the environment) before attempting to move to the new location.
Remember to record the move with the maze environment.getStrategy
method. How do you get the currently selected item from a combo
box?start
method so that the running thread asks
the mouse to move once and then redisplays the maze. Run your program
(making sure to choose the strategy whose getNextLocation
method you have implemented!). Then modify the program and test
it again, moving the mouse two or three times. (Why would three
times be a more interesting test than twice if showEnv
didn't
have the pause built in?)makeDisplayPanel
, add the panel with the slider bar
and its labels below the environment display (use BorderLayout.SOUTH
).System.out.println
, or you may
investigate using the JOptionPane
class (optional).)
The mouse will remove the cheese from the environment, but make sure that
you remove the mouse when the run is over. This will allow you to rerun
the experiment by just clicking on the Start button. (Why is it necessary
to remove the mouse before a user clicks on the Start button?) Run your
program several times until you have confidence that your first strategy is
working correctly.