CSE 142 - Summer 2003 - Homework 5 (Pairs Programming Project #2) Assigned: Monday, July 28, 2003 Written Assignment Due: MONDAY, August 4, 2003 @ 9:30pm Pairs Programming Assignment Due: MONDAY, August 4, 2003 @ 9:30pm Individual Programming Writeup Due: TUESDAY, August 5, 2003 @ 9:30pm A link to the turn-in pages will appear on the course calendar webpage. ------------------ Written Assignment ------------------ To gain full credit on each question, your answer must have no significant flaws, must be clear to the reader, and must be complete (but remember that complete does not mean verbose -- be concise and to the point). As always, you should record your answers to the questions in a plain-text file (for example, "answers.txt") and then submit that text file along with the rest of your electronic turn-in. Do not collaborate with (i.e. copy from) your programming partner when writing your answers to the Written portion of the Assignment. 1. Interfaces. Write a complete Java source file that defines an interface called GeometricFigure, which could be used to describe various geometric figures (circles, squares, and so on). This interface defines two public methods: - getPerimeter, which takes no arguments and returns a double (which is the perimeter of the figure). - isSmall, which takes no arguments and returns a boolean (true if the perimeter of the figure is < 5, false otherwise). Be sure to include appropriate Javadoc comments in your code. Starting with this assignment (Homework 5), we *will* be grading the comments in your Written and Programming submissions for completeness, conciseness, and correctness of information. 2. Implementing Interfaces. Write a complete Java source file that defines a class called MyRectangle that implements the GeometricFigure interface (described in the previous question). Include the following in your implementation: - Write a MyRectangle constructor that takes two values of type double, and sets two instance variables, length and width, respectively, to those values. - Write the methods required by the GeometricFigure interface. You can calculate the perimeter of the rectangle as 2 * (length + width). - Write two additional public methods: setSides -- which takes two arguments of type double, sets the length instance variable to one and the width instance variable to the other, and returns nothing. getLength -- which takes no arguments and returns the length of the Rectangle. Be sure to include appropriate Javadoc comments in your code! 3. Reading Interfaces. Use the Java standard library documentation to answer the following questions: a) What method(s) is/are guaranteed to be implemented by any class that implements the Runnable interface defined in the java.lang package? b) What method(s) is/are guaranteed to be implemented by any class that implements the FileFilter interface defined in the java.io package? ---------------------- Programming Assignment ---------------------- Turn in Car.java when you have completed this task. You should not have to modify any of the other source files. Your partner should submit the same Car.java file. Then, each of you should submit a separate individual project report as outlined on the "Project Report Guidelines" web page, which is linked from the course calendar page. The deadlines for these turn-ins are listed at the top of this file. This project once again deals with a network of Roads that constitute a City. Cars, now a little fancier than they were in Homework 4, travel together along these Roads and must now obey TrafficLight objects (or face the consequences!). This assignment will probably be a lot easier than homework 4, but that does not mean you shouldn't get started right away just in case. - Objective: Implement the Car's tick() method to stop at red traffic lights and start again when those lights turn green. - Objective: Add additional components to your Car's avatar using an Array. 1. If you haven't done so already, download the cse142-hw5.zip file and unzip it. The project skeleton is in directory hw5. 2. The code will compile and execute as is, but chances are high that your Cars will start crashing into each other, as they don't currently obey the TrafficLight signals. 3. This project consists of five classes, which you should be able to read and understand, but only the Car class requires editing on your part. You should read the Javadoc documentation provided in the homework distribution's "doc" directory to get a full understanding of what each of these classes does -- note that the Director, Car, and Road classes have all changed substantially since we last saw them. Here is a *brief* summary of the classes: - Road: This is similar to the Road class from homework 4, although several new methods have been added. The Road class now keeps track of the number of Cars traveling on it (which is <= 1 at all times in this assignment). Roads now have (random) preset speed limits. - TrafficLight: This represents your standard 4-directional traffic light hanging in the middle of an intersection of two Roads. It has four lamps, one for each direction, and the current color of each lamp can be accessed using the light's public methods. Each TrafficLight also has a timer that directs the light to change after a (random) preset amount of time. - Car: This class has changed significantly since homework 4. For one, it no longer speeds up at intersections. Also, the definition of "being on a Road" according to the isOnRoad(Road r) method has changed to mean whether the Car's main body Shape intersects with the Road's Shape. Finally, the Car is now able to check whether it has crashed into other Cars, and must keep track of whether it has been totaled or not. Currently the tick() method is almost identical to the advance() method from homework 4, but that will change as you complete this assignment. When you are finished editing the Car, it will have the ability to obey TrafficLights, and it will have more than just one Shape making up its avatar. - City: Whereas in Homework 4 the Director was responsible for everything on the screen, he now delegates the responsibility of managing the stationary objects (the Roads and TrafficLights) to the City class. The City stores Roads in lists of East-West ones and North-South ones and stores TrafficLights in one big list. At each clock tick, the City tells each of the TrafficLights to tick. In addition to returning Roads and TrafficLights according to their order in the City's lists, the City also performs two important new functions: (a) given two Roads, it can return the TrafficLight at the intersection of those Roads (provided such an intersection exists, and provided that a traffic light exists at that intersection); and (b) given a Car, it can return the Road whose intersection that Car is *about to enter*, or null if the Car is not about to intersect any Road. - Director: The Director object is once again in charge of the entire scene. It creates the City and then loops for a preset (but modifiable, if you want to play with it) amount of time, sending clock ticks to the City and any Cars it has created. The Director also decides when to create new Cars (assigning each one random characteristics and placing it randomly at the start of an empty Road). Finally, the Director removes Cars that have left the GWindow, and also handles checking for Cars that have gotten into traffic accidents. 4. Your first task is to modify the Car's tick() method such that it obeys TrafficLights. Specifically ... - If the Car is about to encounter an intersection where the lamp facing the Car is red, the Car should stop. Use the City's getRoadAboutToIntersect(Car car) method to check for upcoming roads. - On the other hand, if the Car is currently sitting at a TrafficLight, it should check whether the light has changed back to green and, if so, start rolling again at the Road's speed limit. Since this is a fairly simple procedure, we are leaving it largely up to you to figure out how to do all this. Notice that it might help to add one or more instance variables to your Car to keep track of what your Car is currently doing ... 5. Once your Cars are no longer careening through red lights and blowing each other up, your other task is to make them a littler fancier. To do this you'll be adding additional Shapes to your Car class. All of your Shapes should exist within the boundaries of your Car's main Rectangle body. - Include a Shape to represent the Car's driver. - Include two Shapes to represent the Car's brake lights. These lights should change color (from whatever default color you give them) to red when the Car is stopped at a traffic light and back to their default color when the Car is moving once again. Once these two features are working, feel free to include anything else you want in your Car. Just make sure that your driver and brake lights are in the right places! Your Cars don't have to look pretty, but they should at least look neat ... Now, to include these Shapes in your Car, you will be using an Array of Shapes. You will no longer have a "body" variable to represent the Car, nor will you have separate variables for the brake lights, driver, etc.; instead you will have an Array containing all of your Car parts. - Declare an instance variable (say, avatarArray) to refer to an Array of Shape objects. (Remember to include the proper import statement for Arrays at the top of your .java file.) - In your constructor, initialize your Array large enough to hold all of your Car's parts. Then, one by one, create your Car's Rectangle body, driver, brake lights, and whatever other Shapes you want and place them in the spots reserved for them in your Array. - Now go through the whole Car class and change all the methods that refer to the old "body" variable such that they refer instead to the appropriate Shape(s) in your Array. The addToWindow method, for example, should add all your Shapes to the Window. This will require you to loop over the contents of your Array and each component. Certain other methods, such as getWidth() and getX(), only really make sense in the context of your Car's body as a whole. In those cases, you'll have to access the Car's Rectangle body from the Array and query it for the appropriate information. The only method that's not straightforward regarding whether you should handle all of the Car's parts or just the Rectangle is the totalCar() method. In this case, it's pretty much up to you what you want to happen. The way I implemented it, I moved only the Rectangle and left the brake lights and the driver lying in the middle of the Road as a warning to future programmers that unimplemented code can be hazardous to your health! Of course, in the final product, none of your Cars should be hitting each other. But if you want to witness the carnage, you can always comment out the part of the tick() method that checks the TrafficLights ... just make sure everything is working when you submit your final version. 6. You *will* be graded on your comments in this Programming Assignment. Most if not all of the Javadoc comments for the methods are already present in the code you downloaded, however if you should add any additional methods or change anything from the way it was initially implemented, make sure to change any relevant comments so that your code and your documentation both say the same thing.