Program 3

Intermediate Program Suite II

Introduction to Computer Science I
ICS-21


Introduction Please print a copy of this assignment, read it carefully, and highlight material you think will be useful to you while you are working on the program or submitting it.

This programmmng assignment is a continuation of Program 2. It is designed to ensure that you know how to write programs that combine the standard control structures in Java: blocks, ifs, for loops, and break statements (to terminate for loops); and the other statements: declarations and expression statements. You will continue to write, test, and debug programs using iterative enhancement. Finally, work on writing the clearest and simpliest code possible, declaring the appropriate number of variables (to have their natural type, and be aggressive with final) in their appropriate block (smallest scope).

You will write three programs in this assignment. As always, you can check the behavior of your programs against mine by downloading my executable zip file Program #3 Executables and unzipping it. See Program #1) for details on how to run these executables on both PCs and in Eclipses (PCs and Macs). Remember, you can run these programs, but not examine their source (Java) code. Copy the input/output form of the executable programs in the programs that you write: use exactly the same prompts and messages. For the Cannon and Rocket programs, there are executable versions for the kernel and each enhancement.

For your information, I am listing below the number of lines in my solution programs. These programs are formated in the standard way. I am counting only lines with code (even if the only code on the line is a brace that closes a block); but I am not counting blank lines nor lines filled with comments. My "cannon" program is 34 lines; my "rocket" program is 47 lines; my "average" program is 47 lines. Your programs might be smaller, and they might be larger; but if your program starts going over 2-3 times the size of mine, you might want to rethink it (or come get some help).

Please follow the instructions below for each program: finish each enhancement before continuing to the next one (including printing whatever messages it displays in the console, copied exactly). Feel free to use the infinite for loop and if/break statements to write all loops; when you are finished, you may simplify these loops (to general forwhile or do loops); or, if you feel comfortable with these more advanced loops, write them from the start.

In each of these programs, please pay particularly close attention to the following style principles (discussed in the lecture on Coding Style).

  • Names: Choose good names for variables.
  • Alignment: Indent statements to clarify the meaning of their control structures.
  • Locality: Keep related information together; separate unrelated information.
  • Comments: Document your code appropriately with comments.
Please examine the Sample Programs that I have provided for examples of good programming style. Look at my solutions to the previous programming assignment. Learn to copy this style, just as artists in the middle ages learned to copy their master's style before developing their own. In this program, your style will be graded; before handing in these programs, wait until you receive your graded program #2, which will give you some feedback on style.

To work on this assignment, create one Java project (call it Program3) and create three new Java classes in it (as you did for one class in Program #2). Each class will contain a program that you will write to solve one problem; name the classes Cannon, Rocket, and Average. Write, run, and debug each class/program as you did in Program #2. When you finish each part, submit its .java file.

Only one programmer of the pair should dropoff the programs: the same one for each part. It doesn't matter which of the pair submits, but that person should submit all the parts. Of course, each program should contain both student names (in the comment: the same one you cut, pasted, ane filled in at the top of each program in Program #1).


Physics Simulation and Optimization You will write a program that determines the angle to fire a cannon so that its projectile hits the center of the entrance to a cave. First we will discuss the relevant laws of motion and learn how to write code that simulates the flight of the projectile. Then we will write code that searches for the correct angle to fire the cannon, by repeated simulating the projectile for a range of angles. This general coupling of a simulation and an optimization (here, finding the optimal angle to shoot the cannon) is a powerful problem solving technique.

Here is a a picture with some relevant information. Note that the trajectory of a cannon shell (with no air resistance) is a parabola.

To simulate the flight of a projectile from a cannon, we must know its speed (s in feet/second) and angle (θ in radians); and we must choose a time increment (dT in seconds) for our simulation. At the start of the simulation, the x and y coordinates of the projectile are both 0 (feet) and the simulation time (t) is 0 (seconds). For each time increment

  • t is incremented by dT seconds
  • the x coordinate is incremented by s*cos(θ)*dT feet
  • the y coordinate is incremented by (s*sin(θ) - 32.17*t)*dT feet
The statements incrementing these variables should appear in the program in the order show above. These equations are imprecise: they ignore air resistance among other problems, but they are good enough (and certainly simple enough) for our purposes Here we are assuming a gravitational acceleration downward of 32.17 feet/second^2. Also, assume that dT will always be .01 seconds. The simulation runs until EITHER the y coordinate goes negative (angle was not able to reach the target) OR the x coordinate reaches or exceeds the required distance to the target (at which point we can check the y coordinate to determine whether it was the right height to hit the target).

Design, code, test, and debug this program using iterative-enhancement, as 5 mini-projects. Test each project (compare it to my executable) to ensure that it is correct before proceeding to the next enhancement. This is the same methodology that we will use for larger programs; so, it is a good idea to practice this technique here, where the program is small, even if you can write the entire program all at once.

  1. Write a kernel program that prompts the user for the speed (in feet per second) and angle (in degrees -and convert it to radians) of the projectile (the conversion is 1 degree = π/180 radians; but also look at the Javadoc for the Math class, which includes the toRadians and toDegrees methods). Use one of the advanced Prompt.forDouble methods to ensure the speed is within the range [0,10000] and the angle is within the range [0,90]. Hint: look up (in the Prompt class in the Javadoc of Introlib API) all the overloaded versions of the forDouble method and choose the correct one.

    Then write a loop that simulates the projectile using the information above until its y coordinate goes negative, printing the time, and x and y coordinates during each iteration.

    This is a pretty big kernel, with lots of details. Enter a few speeds and angles to test it (and compare it against my executable).

  2. Enhance the program so that it prompts the user for a distance (within the range [0,100000]) and terminates the simulation loop EITHER after its y coordinate goes negative OR after its x coordinate exceeds that distance. Enter a few speeds and angles to test both termination conditions.

  3. Enhance the program so that it prompts the user for a height (within the range [0,100000]) and after that computes θ (rather than prompting for it) as the angle of a straigh line from the cannon (0,0) to the entrance of the cave (distance,height). It then prints this angle (in degrees) and does the simulation with this angle. Hint: look up (in the Math class in the Javadoc of Sun's API) the two argument version of arctangent function (Math.atan2) which computes its result in radians; can you explain why this angle will never shoot the projectile too high and almost always shoot it too low?

  4. Enhance the program by prompting the user whether or not to do a detailed trace (use one of the advanced Prompt.forBoolean methods to have the default value be false): if a detailed trace is requested, print the same information as before; if it is not requested, print only the final time, x coordinate, and y coordinate when the simulation terminates.

  5. Enhance the program by embedding the entire simulation (after the prompting) inside another loop. The outer loop simulates the projectile for the calculated θ and other bigger θs. Starting at the calculated θ simulate the cannon. If after any simulation, the final y coordinate, at termination of the inner loop, is greater than the height terminate the program (the outer loop): the angle is the best approximation to shooting the projectile into the cave. Otherwise (final y coordinate is not greater than the height) increment the angle by .1 degrees (not .1 radians). If the new angle exceeds 90, print the message Entered speed cannot reach target and terminate the outer loop. Otherwise try the simulation (run the inner loop again) with that new angle.

    Ensure that for each new θ the simulation starts the cannon shell at the origin at time zero (use tracing).

Submit ONLY THE FINAL ENHANCEMENT of the program: the one meeting the complete specifications. You might try testing your final program (and my final executable) with a distance of 10,000, a height of 2,000 and a speed of 700 (with a speed of 600 it cannot hit the target). If you have any questions about my output, ask me about it.

Simulating the Flight of a Rocket Write a program that performs the following tasks.
  • Prompt the user to enter the following information describing the rocket:
    • Thrust (in pounds)
    • Thrust Duration (in seconds)
    • Mass (in pounds)
    Assume that the user always enters reasonable values; do not write input validation code for this part of the assignment.
  • Prompt the user, asking whether to print a detailed trace of the flight
  • Simulate the rocket flying vertically (straight up), using these values and a simulation time increment of .01 seconds. If the user requested tracing, print the time, thrust, acceleration, velocity at the end of the interval and height at the end of the interval. Continue the simulation until the rocket reaches its apex (recognized when its velocity, which is initially zero, then positive as the rocket ascends, begins to go negative; with insufficient thrust, the rocket's height will immediately go negative without ever launching upwards).
  • Print the following information, accumulated over the rocket's entire flight
    • The total impulse (entered thrust times thrust duration)
    • The total flight time (burn + coast time)
    • The burn time (same as thrust duration, which the user enters)
    • The coast time (time from the end of the thrust to the apex)
    • The maximum velocity it achieved during the entire simulation
    • The maximum height it achieved during the entire simulation
The basic formula for simulating rocket flight is
          th - cd v2
    a = -------------  - g
             m
We recompute this formula for every time interval during the simulation. In it a, the acceleration for that time interval, is computed from
  • th is the thrust (from time zero up to the thrust time, use the entered thrust, after that the thrust is zero while the rocket is coasting)
  • cd is the coefficient of drag (use .0001 in the program)
  • v is current velocity (at the start of the interval)
  • m is the mass of the rocket
  • g is the gravitational acceleration on the surface of the earth: 32.17 feet/sec/sec
The rocket starts at time 0. with its height and velocity both 0. For each time interval of .01 seconds (let's call it dT), the program (a) increments the total time by dT, (b) calculates the acceleration of the rocket (from the formula above) for that time interval; remember to use the correct thrust, depending on the time (either the original thrust or 0., depending on how the time compares to the thrust duration) and (c) calculates the new velocity and height (at the end of the time interval) as follows:
  • The new (end of the time interval) velocity, which is the old (start of the time interval) velocity + a * dT; the average velocity over the interval is the average of the old and new velocities.
  • The new (end of the time interval) height, which is the old (start of the time interval) height + the average velocity * dT.
  • The maximum velocity and height, which may be updated depending on their values at the start of the time interval and the newly computed velocity and height at the end of the time interval.
It is important to understand the description above before coding it in Java.

Design, code, test, and debug this program using iterative-enhancement, as 6 mini-projects. Test each project to ensure that it is correct before proceeding to the next enhancement. This is the same methodology that we will use for larger programs; so, it is a good idea to practice this technique here, where the program is small, even if you can write the entire program all at once.

  1. Write a kernel program that prompts the user for all the rocket information specified above, and then loops, incrementing the time (until it exceeds the time that the engine stops burning), displaying the time and thrust for each time interval. Ensure the time and thrust are displayed correctly, and the loop terminates at the correct time. Try a thrust of 100 for .5 seconds with a mass of 1. (for this kernel, and the subsequent enhancements). Don't worry about doing anything with the mass.

  2. Enhance the program so that it computes the acceleration and then the velocity (which starts at 0.) correctly; change the loop to terminate when the velocity becomes negative (the rocket has reached its apex and is falling back to earth). During each iteration of the loop, compute the acceleration using the formula shown above, paying close attention to whether the engine is burning, and update the velocity using the description shown above. In addition to displaying the time and thrust (which should eventually drop to 0. after it has finished burning), display the acceleration for the interval, and the velocity at the end of the interval.

  3. Enhance the program so that it computes the height (which starts at 0.) correctly. During each iteration of the loop, update the height using the formula shown above. In addition to displaying everything else, display the height at the end of each time interval.

  4. Enhance the program to keep track of the maximum velocity and height. In addition to displaying everything else, display these values at the end of each time interval. Finally, display these values after the loop terminates.

  5. Enhance the program to display all the required information after the loop terminates (display this information in the correct form). This information includes the total impulse, the flight time (broken down into burn time and coast time), the maximum velocity and the maximum height.

  6. Enhance the program to prompt the user about tracing (with a default value of false), and then display the intermediate results only if the user enters true. Always print the information after the loop terminates (see the previous enhancement).
Remember to use final appropriately/aggressively when declaring constants representing the information needed for this program.

Submit ONLY THE FINAL ENHANCEMENT of the program: the one meeting the complete specifications (note that the program you submit SHOULD NOT print any intermediate results unless the user explicitly requests tracing). Test your debugged/completed program for a thrust of 100 lbs, a time of 10 secs, and a mass of 1 lb and compare it to the results of my excutable; for full credit your results should match exactly (certainly to most of the many digits printed by a double). If you have any questions about my output, ask me about it.


Average Upgrade Don't start this project with the new project folder. Instead, download the Average project folder, unzip it, and use the unzipped folder as a project folder.

When compiled and run, it prompts the user for a file name and then processes exam scores in that file to compute the average of all the exams. The first value in the file is the maximum score possible for the exam, and almost all the remaining values are legal exam scores. The final value in the file must be -1: such a value is called a sentinel; it marks the end of data in the file; it is not a value to be processed when computing the average.

The Average project folder also includes a few data files (all ending in .txt) that you can test this program on. When prompted for a file name, type one of these names (for this too work, the files need to be at the top level in the project folder).

Don't worry about the file-reading part of this code, because it is correct and does not need to be changed: just concentrate on the overall looping structure of the program and add Java declarations and statements at appropriate locations to make the following changes. Again, make these changes one at a time, designing, coding, testing, and debugging each enhancement before proceeding to the next one. Before starting to write your program, run mine a few times to familiarize youself with it.

  1. Enhance the program to discard all scores that are not between 0 and the maximum score (inclusive). Neither count these exams nor use them in computing the sum. Display a message immediately for each illegal score that is discarded. Note that the file average3.txt contains a large number of scores, including one that is too low and one that is too high.

  2. Enhance the program to count the total number of out-of-range scores and print this value with the other statistics at the end of the program. If there are no scores, don't display any statistics.

  3. Enhance the program to keep track of the minimum and maximum legal scores in the file, and then print out their values at the end, along with the average, and the total number of out-of-range scores. Again, do not process scores that are out of range. Think about how you will initialize and update these extremal variables.

    Hint: Imagine someone is giving you one card after another, with a value on each card; you have to discard each card before you go to the next one: how could you compute the maximum of all the cards that were handed to you? What could we initialize the maximum and minimum scores to before any scores are processed to insure this process proceeds correctly? How is this problem similar to finding the maximum velocity and height in the rocket program; how is it different?

Submit ONLY THE FINAL ENHANCEMENT of the program: the one meeting the complete specifications. Test your debugged/completed program on all four input files and ensure it computes the correct statistics for each. Finally, remember to update the Description: comment to include the new functionality added to the program.