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
ColorBlockclass (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 maze
MazeGUI- a partially implemented class that provides a graphical user interface for the Mouse-in-a-Maze project
MovingStrategy- a fully defined interface
maze1.dat- a sample maze initial configuration file
mbsenv.jar- Java archive libraries containing classes such as
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
MazeGUI- the partially implemented GUI class
Mouse- an object that moves around the maze based on a strategy
You 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.
MazeGUIobject. Look at the
MazeGUIconstructor to see what parameters it requires. (You could use
EnvPlotterAppas a guide, although you will need to define the background color as well as the width and height of the display area.
MinnowAppmay 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.
Mazeclass that extends
BoundedEnv. In order for
MazeDataFileHandlerto 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:
setFinishLoc. These two methods must both take a single
Locationas a parameter and have a
voidreturn 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.
Mouseclass. In order for
MazeDataFileHandlerto work correctly, the new class must be called
Mouseand 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.
Mazeclass as appropriate, and implement the
setFinishLocmethods. (You can also implement other
Mazemethods, such as methods to find out the start location or finish location, although you don't have to do that yet.)
MazeGUIclass, 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
actionPerformedbehavior should be different. Notice that the
MazeGUIclass has an
openFilemethod that you can use.
DisplayMap.associatemethod that specifies that
ColorBlockobjects get displayed using an object of the
MinnowAppclass provides an example of similar code.)
maze1.dator initial configuration files of your own making. You may wish to copy the initial configuration file(s) to the project
Datafolder 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
Datafolder can easily get wiped out.) You should be able to open a configuration file and see the resulting maze.
Mazeclass that you could use to find out where to construct the mouse and where to construct the cheese.
Mouseclass implement the
Locatableinterface, 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.
runmethod in the anonymous inner
Threadsubclass in the
startmethod to construct a mouse and a piece of cheese and to call the appropriate method in
MazeGUIto display the initial configuration of the maze.
MazeGUIclass 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.
MazeGUI) that enables and disables the Start button appropriately.
smallfish.gifimage. Put a copy of it in your project
Datafolder so that the program can find it.) To associate an image with a class, construct a new
ScaledImageDisplayas the display object, passing it the name of the image file as a
Stringparameter (e.g., "smallfish.gif"). You can find the class documentation for
TintedImageDisplay, see below) in the GenericEnvAPI folder.
Mouseclass to include a
colormethod 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
TintedImageDisplayinstead of a
ScaledImageDisplay. This will tint the image with the color specified by the
FishDisplayclass as a model. Your display class should extend
RotatedDisplayunless you plan to add a
directionmethod to your
Mouseclass. 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
MouseDisplayclass until after everything else in your program is working!)
Cheeseclass, rather than just use an object of the
MovingStrategyinterface. For example, you might create a class that implements the random movement (or "clueless mouse") strategy The
toStringmethod of your new class should return the string that you want to appear in the pull-down strategy chooser menu. You can leave the
getNextLocationmethod empty for now.
makeStrategyChoosermethod in the
MazeGUIclass 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
toStringmethod 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.)
makeStrategyChoosergets 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.
toStringmethods and leaving their
getNextLocationmethods 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.
getNextLocationmethod 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
equalsmethod rather than the
Mouseclass 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.
getStrategymethod. How do you get the currently selected item from a combo box?
startmethod 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
getNextLocationmethod 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
showEnvdidn't have the pause built in?)
makeDisplayPanel, add the panel with the slider bar and its labels below the environment display (use
System.out.println, or you may investigate using the
JOptionPaneclass (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.