Lab 11 In-Class: More Classes
Lab Objectives
- Gain more experience in the process of implementing and testing
a class incrementally.
- Gain an understanding of the concept of method overloading.
- Gain more experience using a class in more than one client program.
|
In this lab you will develop a class that models a random walk and write
a few client programs that use the class. A random walk is basically a
sequence of steps in some enclosed space where the direction of each
step is random. The walk terminates either when a maximum number of steps
has been taken or a step goes outside of the boundary of the space.
Random walks are used to model physical phenomena
such as the motion of molecules and economic phenomena such as stock
prices.
We will assume that the random walk takes place on a square grid with
the point (0,0) at the upper left hand corner (as in a graphics
window). By default each step will be one
unit up, one unit down, one unit to the left, or one unit to the right.
(No diagonal movement.)
The basic RandomWalk class will have the following instance data
(all type int):
- the x coordinate of the current position
- the y coordinate of the current position
- the maximum number of steps in the walk (the walk terminates when the
number of steps exceeds this)
- the number of steps taken so far in the walk
- the width of the square grid (a positive integer -- the x and y
coordinates of the position can vary between 0 and this
value)
Open a new class RandomWalk in Eclipse.
You'll define the RandomWalk class incrementally testing each part
as you go. Be sure to include documentation as you develop the
class. Use Eclipse to generate documentation for each class and method.
- First declare the instance data (as described above) and add the
following two constructors and toString method.
- RandomWalk (int maxSteps, int sqWidth) - Initializes the RandomWalk
object. The maximum number of
steps and the width of the grid are given by the parameters.
The x and y coordinates
should be set to the center of the square grid. The number of steps
so far should be set to 0.
- RandomWalk (int maxSteps, int sqWidth, int startX, int startY) --
Initializes
the maximum number of steps, the width, and the starting position
to those given by the parameters.
- String toString() - returns a String containing the
number of steps taken so far and the current position -- The string
should look something like: Steps: 12; Position: (30,55)
- Compile what you have so far then open the file
TestWalk.java. This file will be used
to test your RandomWalk methods. So far it prompts
the user to enter a maximum number of steps, a width for the grid and the
x and y coordinates of a position. Add the following:
- Declare and instantiate two RandomWalk objects -- one with maximum
steps 20, width 10, and centered in the square (use the two parameter constructor)
and the other with the values entered by the user.
- Print out each object. Note that you won't get any information about the
boundary or maximum number of steps (think about what your toString
method does), but that's ok.
Run the program to make sure everything is correct so far.
- Next add the following method to the RandomWalk class:
void takeStep()
This method simulates taking a single step either
up, down, left, or right.
To "take a step" generate a random number
with 4 values (say 0, 1, 2, 3)
then use a switch statement to change the position (one random value
will represent going right, one left, and so on). Your method should
also increment the number of steps taken. Use either the Random class
or Math.random from the Math class to generate the random number.
- Add a for loop to
TestWalk.java to have each of your RandomWalk objects take 5 steps.
Print out each object after each step so you can see what is going on.
Run the program to make sure it is correct so far. The
walk is random so each time you run the program the positions will
change.
- Next add graphics capabilities to the RandomWalk class so the steps can
be drawn. A step will be drawn as a line from the previous position
to the new position when a step is taken. This requires doing the following
in RandomWalk.java:
- Import java.awt.*.
- Add three new instance variables: two integers to represent
the x and y coordinates of the previous position; a Color object
for the color of the walk.
- Add two new constructors - these should be the same as the two
you already have with one additional parameter, a Color object. NOTE:
you can just copy the two constructors you have and add the Color parameter
to each.
Of course assign your Color instance variable the value passed in.
- In the original constructors assign the instance variable for color
to be black (so black will be the default color).
- Add a method void drawStep(Graphics page) that takes
a Graphics object as parameter. The method should set the color
for the Graphics object then
draw a line from the
previous position to the current position (the "step").
- Now overload the takeStep method by adding a new takeStep
that will take a step and draw the step. Clearly this method
needs a Graphics object to draw on so it must have
a Graphics parameter. It turns out that 1 pixel steps
don't show up too well so we will also have a second parameter -
an integer representing the step size.
The method should save the
current position in the instance variables for the previous position
(note: you should add code
in the current takeStep method to do this also) before
generating the new step.
The position should be updated by
adding the step size rather than just incrementing. Finally, the
drawStep method should be called to draw the step.
- Now test your new methods with a graphics application. The file
StepPanel.java contains the skeleton
of a panel to test the methods and file StepApp.java
contains the associated application. Save
these to your directory. Open StepPanel.java and add code to
instantiate two RandomWalk objects (the instance variables)
in the constructor as directed
by the comments. In the paintComponent method write a for loop that has
each object take and draw 20 steps with step size 3.
- Run the program several times to see the randomness.
- Change the step size to 8, then run again to
see the difference. Next try a step size of 1.
- Now add to RandomWalk.java the following two methods. Each should
be a single return statement (no if needed!)
that returns the value of a boolean expression.
- boolean moreSteps() - returns true if there are more steps
to be taken (that is, if the number of steps
taken is less than the maximum number); returns false otherwise
- boolean inBounds() - returns true if the current position
is on the square (include the boundary as part of the square); returns false
otherwise.
- Add to the RandomWalk class a method named walk that has no
parameters and returns nothing. Its job is to simulate a complete
random walk. That is, it should generate a sequence of steps as long
the maximum number of steps has not been taken and it is still
in bounds (inside the square). This should be a very simple loop
(while or do... while) --- you will need to call the methods takeStep,
moreSteps, and inBounds. This method should not draw the walk.
- Add to TestWalk.java a statement to instantiate a RandomWalk object
with a width of 20 and 200 as the maximum number of steps.
(You may want to comment out most of the code currently in TestWalk --
especially the user input and the loop that takes five
steps -- as the walk method will be easier to test on its own. The
/* ... */ style of comment is useful for this.)
Then
add a statement to have the object walk using the walk method.
Print the object after the
walk. Run the program more than once -- you should
be able to tell by the value printed whether the object went out of
bounds or whether it stopped because it reached the maximum number of
steps.
- Next overload the walk method in the RandomWalk class
by adding a graphical version. As with the takeStep method
this needs two parameters to represent the Graphics object and the
step size. You can copy your current walk method and make
just a few changes.
- Use the graphical panel WalkPanel.java
and associated application WalkApp.java to
test your graphical walk. Add code in WalkPanel.java to instantiate
the RandomWalk object (the instance variable)
with 5000 for the maximum number of steps and
200 (the panel width) for the width and the color
and position of your choice. Add code to the paintComponent
method to have the object do a
graphical "walk."
- Run the program several times to see the
randomness.
- Now write a client program (nongraphical)
to simulate a drunk staggering randomly on some sort of
platform (imagine a square dock in the middle of a lake). Name the
class DrunkenWalk. The goal
of the program is to simulate the walk many times
(because of randomness each walk is different) and count the number of
times the drunk falls off the platform (goes out of bounds). Your
program should do the following:
- Read in the width of the platform,
the maximum number of steps, and
the number of drunks to simulate.
- Then have a loop (a for loop would be a good idea) that on each
iteration instantiates a new RandomWalk object to represent a drunk,
has the object walk, then determines whether or not the drunk
fell off the platform (and updates a counter if it did).
- After the
loop print out the number of times the drunk fell off and the number
of times it didn't.
To see the
"randomness" you should run your program several times with at least
1000 for the number of drunks to simulate. Try input of 10 for
the width and 200 for the number of steps first (sometimes the drunk
falls off, sometimes not); try 10 for the width and 500 for the steps
(you should see different behavior); try 50 for the width and 200
for the steps (again different behavior).
- Finally you will write a second client program
that simulates two particles moving in space. Its goal
is to determine the number of times the two particles collide (occupy
exactly the same position after the same number of steps -- the steps
could be thought of as simulating time). This means your program
needs a way to determine whether or not the particles (the RandomWalk
objects) are in the same position. For this we will add
some methods to the RandomWalk class. So, do the following:
- First, add the following methods to the RandomWalk class.
- int getX() - returns the x coordinate of the current position
- int getY() - returns the y coordinate of the current position
- static boolean samePosition (RandomWalk p1, RandomWalk p2) -
returns true if RandomWalk objects p1 and p2 have the same x coordinates
and the same y coordinates.
Note that all three methods are public.
Make sure there are no syntax errors before proceding.
- Now write a graphical client program - a graphical application that
has uses random walk objects to simulate two particles moving
in space. The file CollisionsApp.java
contains the application and the file
CollisionsPanel.java contains
the skeleton of the panel for you to complete.
In writing your panel assume the
particles are in a square window with width 600 (note the size of
the panel has already been set for you).
Use 100,000 for the maximum number of steps.
Start one particle 9 pixels to the left of the applet center
and the other 9 pixels to the right. The two "particles" should
be different colors. Use a step size of 3.
Your program should contain a loop that has each particle take a step
(not a complete walk!)
as long as the particles have not exceeded the maximum number of steps
(it is ok to let them go out of bounds).
The program then determines how often the particles have collided.
The program should call the static method samePosition you just
added to the RandomWalk class to determine if the particles are in
the same position after taking each step (have "collided").
Use drawString to draw the
number of collisions (appropriately labeled) on the applet. Use
a color that will show up!
Compile and run your program to make sure it works. As before run
it several times.
- ** EXTRA CREDIT ** In using random walks to simulate
behavior it is often of interest to know how far away from the initial
position the object gets as it moves. There are several different
possibilities for measuring the distance. In this case it makes sense
to use "Manhattan" distance - the sum of the vertical and horizontal
distances from the starting point. For example, the Manhattan distance
from the point (20, 350) to (200, 100) is 430 (horizontal distance of
180 + vertical distance of 250).
- Add instance variables for the initial position (currently
that is lost as the walk takes place) and the maximum distance
so far to the RandomWalk class. Initialize these appropriately
in each constructor.
- Now the takeStep methods need to compute the distance
from the initial position (the sum of the absolute values of the
distance in the horizontal direction and in the vertical direction)
and update the maximum when a step is taken.
Remember that Math.abs returns
the absolute value of a number; you can also use the Math.max
method to find the maximum of the new distance and the previous
maximum.
- Finally add an accessor method to return that distance so
a client program can access it.
public int getMaxDistance()
- Test the maximum by adding statements in CollisionsPanel to get and
print the maximum distance for each of the particles after the
loop.
- Before printing anything be sure that all your files have appropriate
documentation including your name and are properly formatted.
What to Turn In
Turn in hardcopy of RandomWalk.java, TestWalk.java, DrunkenWalk.java, and
CollisionsPanel.java. (No need to turn in StepPanel.java and
WalkPanel.java but they should be in the directory you tar.)
Tar your lab11 directory and email it to your instructor
with cpsc120 lab11 in the subject line.