CPSC 124 (Fall 1998): Lab 3
Using Subroutines and Member Variables
WELCOME TO THE THIRD LAB for Computer Science 124: Introductory Programming, Fall 1998. This is the first of two labs that deal primarily with subroutines and member variables.
As usual, you will find a set of exercises at the end of this lab. You should turn in your answers to the exercises in class on the Monday following the lab. If you work with a partner in the lab, you and your partner have the option of turning in separate reports, or turning in one report with both your names.
Before you do anything else in the lab, you should copy the files that you'll need into your own account. You can do this with the command
cp -r /home/cs124/lab3 ~
After copying the files, you should change your working directory with the command
Outline of the Lab:
Variables are used whenever the computer needs to store some data to be used later in program. Data that only needs to be remembered while a subroutine is being executed should be stored in local variables in that subroutine. Data from outside the subroutine can be passed to the subroutine in parameters. And, finally, subroutines can use data that is stored in member variables. Member variables are variables that are declared in a class outside of any subroutine. Member variables represent the "knowledge" or "state" of classes and objects. The state of the object or class is the information that persists over time, between calls to subroutines. If you want an object or class to "remember" something between calls to subroutines, you have to store it in member variables.
Member variables can be static or non-static. Static member variables belong to the class itself, and they store information about the state of the class. Non-static member variables belong to objects, and they store information about the state of the objects. (Non-static member variables are also called "instance variables.") When you work with applets, which are objects, you will store state information in non-static member variables. When you work with independent applications, which are really classes, you will store state information in static member variables. Subroutines can also be static or non-static, and follow the same rule: Applets, as objects, contain non-static subroutines. Applications, as classes, contain static subroutines.
For the first exercise of the lab, you will work with an applet. This applet is another simple animation applet, based on the same animation framework as Exercise 3 of the previous lab. However, this applet uses subroutines to organize the work it does, and it uses member variables to store information about the state of the animation. The applet is Bouncer.java. This applet shows a red circle bouncing around in a square. Your job is to add a green circle and a blue circle. In your lab3 directory, you will find a copy of Bouncer.java and an HTML file, Bouncer.html, that includes the applet. You can run the applet with the command appletviewer Bouncer.html. (You can also see the applet in action here.)
The bouncer applet must remember the position and velocity of the red circle. Since this data must persist from one frame to the next, it is stored in the member variables redCenterX, redCenterY, redVelocityX, and redVelocityY. To add blue and green circles to the applet, you'll need to create similar sets of variables for each circle. The applet uses two subroutines, initializeRedCircle() and updateRedCircle(), to do some of its work. These subroutines exist mainly to organize the applet and prevent the drawFrame from becoming too long and complicated. You'll need to create similar subroutines for the green and blue circle.
Note: If you use "Copy-and-Paste," you won't have to do too much typing for this exercise.
Consider a drunkard standing at the point x = 0 on a long street. Every second, the drunkard either staggers one step forward, or staggers one step backwards, or stays in the same place. Each action is equally likely. After N steps, how far away from the point x = 0 has the drunkard moved? Because of the randomness, we can only ask about the average or expected distance traveled by the drunkard after N steps. On a computer, we can simulate, say, 1000 walks. Each walk starts at position 0 and consists of N random steps. If we add up all the distances traveled in all the walks, we can compute the average distance traveled. This is the basic drunkard's walk experiment. (The drunkard's walk is actually a model for physical processes such as diffusion, where each molecule diffusing through a liquid is similar to a drunkard staggering at random down a street.)
In this part of the lab, you will work with a program that simulates the drunkard's walk experiment. The point of the exercise is to work with subroutines and parameters. You will use the file DrunkardsWalk.java as a starting point. (Open it with nedit.) This file defines several subroutines. One of the subroutines, doOneExperiment() is empty, and the main() routine is also empty. Your assignment is to complete these two subroutines. The completed program will simulate the basic drunkard's walk experiment, as described above, for N = 100, 200, 300, ..., and 1000. It will print the results -- the average distance traveled in 1000 walks of length N -- for each N. Here is as applet that does the same thing as the completed program. (You should ask yourself whether the results agree with your intuition about how far the drunkard will travel.)
The file DrunkardsWalk.java contains complete definitions of three subroutines:
- static int doOneWalk(int numberOfSteps) -- simulates one walk by a drunkard, consisting of numberOfSteps random steps. This subroutine returns the net distance traveled by the drunkard, that is, the absolute value of the difference between the drunkard's initial position and the drunkard's final position. (The number of steps is the N in the above description.)
- static void printHeaders() -- A little convenience routine to print out the first two lines of output, containing column headers for the data.
- static void reportData(int lengthOfWalk, int numberOfWalks, int sumOfDistances) -- Takes data collected during one experiment and outputs one line of data about the experiment. The first parameter must be the number of steps in each walk. This is the N in the above description, and is different for each experiment. The second parameter is the number of walks done in the experiment. In the above description, this is assumed to be 1000. The third parameter is the sum of the distances traveled in all the walks. The program has to keep track of this data as it does the walks. (Note: I deliberately used different parameter names for "N" in this routine and the preceding routine, to force you to deal with the fact that the name of a dummy parameter is irrelevant.)
You should first fill in the subroutine doOneExperiment() so that it does one basic drunkard's walk experiment and reports the results. Your subroutine should call the subroutines doOneWalk() and reportData(). Then fill in the main() routine so that it calls doOneExperiment() for values of numberOfSteps equal to 100, 200, ..., 1000. The main() routine should also call the printHeaders() routine. Both of the subroutines that you have to write will be pretty short.
Exercises to Turn in
Exercise 1. (9 points) Modify the file "Bouncer.java," as described above, so that the bouncer applet shows three bouncing circles instead of just one. Turn in a printout of your modified program.
Exercise 2. (6 points) Doesn't it seem pretty silly in the previous exercise to have separate sets of almost-identical variables and subroutines for the red, green, and blue circles? This is what object-oriented programming is for! Suppose you could create a "BouncingCircle" class to represent bouncing circles like the red, blue, and green circles in this applet. Each of the circles in the applet would be a BouncingCircle object. What data would a BouncingCircle object have to contain? What subroutines would it need? Explain how the Bouncer applet would be improved by using objects. (Maybe you should expect to see this continued in a future lab...)
Exercise 3. (9 points) Complete the Drunkard's Walk program by writing its main() routine and doOneExperiment() routine, as described above. You should also write an overall comment for the top of program. Turn in a printout of the completed program.
Exercise 4. (6 points) Section 3.2 of the text discusses "named constants," which are static final variables that are used to give a name to a numerical constant. Each of the programs that you worked with in this lab could have been better if it had used a named constant. What number in the BouncingCircles program could have been a named constant? Why? What number or numbers in the DrunkardsWalk program could have been named constants? Why? How would the program have been improved in each case?