CS110: An Introduction to Computing (Java)

Lab #2

(Adapted from Lander Project by Stuart Reges at University of Washington)

Pre-Lab

Do the following tasks before coming to lab:

1.   Answer the following questions about the Java Programming language in your own words.  Each answer should be 1 paragraph long.  Your answers must be printed (not handwritten).  All your answers together must fit on one side of one sheet of paper.

A.    In Java, what is a class?  What is an object?  What is the difference?

B.       What is a Java method?  Where are methods defined?

2.  What is the printed as a result of the following Java statements?

            int i = 2, j = 3, k = 4;

            System.out.println (i + j / k);

            System.out.println ((i + j) / k);

            System.out.println (i + j % k);

            System.out.println ((i + j) % k);

3.  Read the rest of the Lab 2 instructions so that you will know what you need to do during the lab session.

Note:  The assignment is due at the BEGINNING of the lab.  You can only work on the lab once you complete the pre-lab assignment. 

Lab

In this assignment you will write one method named tick in a class named LunarLander to complete a game program.  The game program allows a user to try to land a lunar lander safely on surface of the moon.

Download and unZip on your removable media the following WinZip file containing the Lab 2 Java source files Lab2.zip.  Follow the same procedure you used for Lab 1 to create your Dr Java project file and to open all of the .java files in the directory into the project.  Be sure to save the project after you do this. 

The project files will compile successfully before you add your code for the tick method.  However if you run the project as-is, the simulated lunar lander will just hang in space at its initial location.  Not a very interesting game yet!!  You are to use Dr Java to edit the tick method in the file LunarLander.java to complete the action of the game.

Your tick method will update the lander’s current altitude, speed and fuel every second.  To keep things simple, we will use simple ints for all calculations.  Your tick method will update these variable each time it is called (once per second). In the simulation, the user will have the option to request retro-thrusts from the lander’s engines.  For each thrust request the user makes, one unit of fuel will be expended to generate a certain negative acceleration at the time of the next call to your tick method.  If the user makes more than one thrust request in a given second, then your tick method applies the requested number of fuel units and corresponding negative acceleration.  For example, if the user makes four thrust requests in a given second, then your tick method burns four times the normal amount of fuel and gives the lander four times the negative acceleration of a single thrust.  However, the user can only make retro-thrusts as long as there is enough fuel left.  Once out of fuel, the lander will merely accelerate towards the moon’s surface under the influence of gravity and will probably crash.

The class is called LunarLander and includes the following public methods:

Method

Description (Return Data Type)

getAltitude()

returns the current altitude in meters (int)

getVelocity()

returns the current velocity in meters/second (int)

getFuel()

returns the current number of thrust units remaining (int)

reset()

resets the lunar lander to the initial situation (void)

thrust()

each call adds one unit of fuel for use on the next “tick” (void) (can be called multiple times between calls to tick)

tick()

called once every second, should update the simulation variables appropriately, applying the number of thrusts and using units of fuel requested since the last “tick” (void)

In resetting the simulation, the following constants are for altitude, velocity and fuel:

public static final int INITIAL_VELOCITY = 40;   // meters/second
public static final int INITIAL_ALTITUDE = 1000; // meters
public static final int INITIAL_FUEL     = 25;   // thrusts

Assume that the reset method is called before the simulation begins.

Notice that the thrust method does not update any of the three variables, it just keeps track of how many thrust units have been requested to be applied at the end the current second (next call to tick).  All updating should be done when the tick method is called.  The tick method should first re-compute the velocity.  Because we are computing once per second, this calculation is rather simple.  You should use the following constants for the calculation:

public static final int GRAVITY = 2;  // gravitational acceleration
                                      // in meters/second/second
public static final int THRUST  = 4;  // thrust acceleration in
                                      // meters/second/second

The first constant indicates that the Moon’s gravity will increase velocity by 2 meters/second every second of the simulation.  So to account for gravity, you simply add this number to the velocity once every second.  The second constant indicates that each thrust unit will decrease velocity by 4 meters/second.  For example, with one thrust unit, the overall effect is to decrease velocity by 2 (add 2 for gravity, subtract 4 for one thrust unit).  With two thrust units the velocity is decreased by 6 (add 2 for gravity, subtract 8 for two thrust units).  With three thrust units the velocity is decreased by 10 (add 2, subtract 12).  And so on.

Once you have updated the velocity in the tick method, you should re-compute the altitude.  Because we are storing velocities as meters per second and the tick interval is one second, you can simply subtract the velocity from the current altitude.  For example, if the altitude is 900 and the velocity is 54 meters/second, then you would reset the altitude to be 846 meters (900 minus 54) to account for one second of movement at that velocity.  You do not need to make a special case for negative velocities.  If the user has applied so much thrust that the velocity has gone negative, then the new altitude will be higher than the old one because you are subtracting a negative number.

Finally, once you have updated the velocity and altitude in the tick method, you should reset the fuel by subtracting the number of thrust units requested from the current available fuel.  This is a simple computation because we are expressing the fuel level in terms of thrust units (i.e., one unit of fuel is the amount of fuel necessary to produce one thrust unit).

You have to handle one minor problem in the tick method.  It is possible that the user will request too many thrust units.  For example, suppose the fuel level is at 3 units and the user requests 5 thrust units.  You have to limit the user to the number of fuel units available.  The Math class provides a method called min that returns the minimum of two integers, as in:

int x = 3, y = 5;
int z = Math.min(x, y);
// z would now be 3

Using this code, you can reset the thrust request to the smaller of the thrust request and the available fuel.  That way the user will never be allowed to use more fuel than is left.

There is a final constant defined in the LunarLander class, although you won’t need to use it in your code.  It keeps track of the maximum velocity for a safe landing:

public static final int SAFE_LANDING = 4;  // speed at which lander can
                                           // safely land in meters/second

The user interface uses this constant to determine whether the lander crashes or lands safely.

All of the constants described above are public constants in the LunarLander class.  To make this easier for you, they have all been included in the class definition that you are to complete. You only need to modify the Java source file for the tick method.  You can look at the Java code for the other methods and may benefit from trying to understand what they are doing.  Your task is to complete the lunar lander class by writing the tick code that implements the behavior described above.

Once your version of the tick method compiles and the simulation runs properly, print your file LunarLander.java and turn it in during your next lab session along with your lab report.  You do not have to print any other files in the Lab 2 project folder.

Project Report due next Lab Session

Answer the following questions:

1. Why did the lunar lander just hang up in space before you wrote the code for the tick method?

2. Why is it a good idea to use symbolic constant names such as GRAVITY in your code?

3. If you want to make the game easier to win, you can change the value for some of the constants in the LunarLander class.  Which two constants could you change and how would you change them to make the game easier?