Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Program Description: This assignment tests your understanding of inheritance, polymorphism, interfaces, and abstract classes. The program is a simulator of city streets, traffic lights, and

Program Description: This assignment tests your understanding of inheritance, polymorphism, interfaces, and abstract classes. The program is a simulator of city streets, traffic lights, and vehicles. Your task is to write the classes to model the various vehicles in the city. The classes have many similarities, so you should use inheritance to design the classes in a way that reduces code redundancy. The starter code for the project includes a complete and correct graphical user interface (GUI). The GUI shows pictures for the map terrain and vehicles. The GUI loads the city map and vehicle starting positions from the provided file city_map.txt. There are buttons to start and stop the city's animation, as well as to step through it one frame at a time and to reset the vehicles to their initial layout. Each time the GUI redraws, it moves each of the vehicles. If any two vehicles end up on the same square, the GUI tells the vehicles that they have collided with each other, which may "kill" them temporarily. "Dead" vehicles appear upside down on the screen. The rate of city animation is controllable via a slider at the bottom of the interface. Also, debug information can be shown using a checkbox. If debug information is enabled, all (x, y) grid positions on the map are labeled, and 2 of 10 every vehicle's toString output is shown next to the vehicle. You can put any information you like into your vehicles toString methods to help you debug their behavior. You must write Vehicle sub-classes (and a common parent class called AbstractVehicle) for this assignment. Each of the Vehicle classes must implement the provided Vehicle interface described in this document. Note that a Human is a Vehicle for the purposes of this assignment. Vehicle behavior includes some randomness. If you need to create an object of type Random, then your project code should only create a single object of type Random that all Vehicle objects can share. Vehicle Descriptions:

Truck Constructor: public Truck(int theX, int theY, Direction theDir) Images: truck.gif (alive), truck_dead.gif (dead) Movement behavior: Trucks travel only on streets and through lights and crosswalks. Trucks randomly select to go straight, turn left, or turn right. As a last resort, if none of these three directions is legal (all not streets, lights, or crosswalks), the truck turns around. Trucks drive through all traffic lights without stopping! Trucks stop for red crosswalk lights, but drive through yellow or green crosswalk lights without stopping. Collision behavior: A truck survives a collision with anything, living or dead.

Car Constructor: public Car(int theX, int theY, Direction theDir) Images: car.gif (alive), car_dead.gif (dead) Movement behavior: Cars only travel on streets and through traffic lights and crosswalks. Cars prefer to drive straight ahead on streets, traffic lights, and crosswalks. If a Car cannot move straight ahead, it turns left if possible; if it cannot turn left, it turns right if possible; as a last resort, it turns around. Cars stop for red and yellow traffic lights; if a traffic light is immediately ahead of the car and the light is yellow or red, the car stays still and does not move. It does not turn to avoid the light. When the light turns green, the car resumes its original direction. Cars stop for red and yellow crosswalk lights, but drive through green crosswalk lights without stopping. Collision behavior: A car dies if it collides with a living truck, and stays dead for 10 moves.

All-Terrain Vehicle (ATV) Constructor: public Atv(int theX, int theY, Direction theDir) Images: atv.gif (alive), atv_dead.gif (dead) Movement behavior: ATVs can travel on any terrain except walls. They randomly select to go straight, turn left, or turn right. ATVs only reverse direction if they have no other option. ATVs drive through all traffic lights and crosswalk lights without stopping! Collision behavior: An ATV dies if it collides with a living truck or car and stays dead for 20 moves. Vehicle Descriptions:

Bicycle Constructor: public Bicycle(int theX, int theY, Direction theDir) Images: bicycle.gif (alive), bicycle_dead.gif (dead) Movement behavior: Bicycles can travel on streets and through lights and crosswalk lights, but they prefer to travel on trails. If the terrain in front of a bicycle is a trail, the bicycle always goes straight ahead in the direction it is facing. Trails are guaranteed to be straight (horizontal or vertical) lines that end at streets, and you are guaranteed that a bicycle will never start on a trail facing terrain it cannot traverse. If a bicycle is not facing a trail, but there is a trail either to the left or to the right of the bicycles current direction, then the bicycle turns to face the trail and moves in that direction. You may assume that the map is laid out so that only one trail will neighbor a bicycle at any given time. If there is no trail straight ahead, to the left, or to the right, the bicycle prefers to move straight ahead on a street (or light or crosswalk light) if it can. If it cannot move straight ahead, it turns right if possible; if it cannot turn right, it turns left if possible. As a last resort, if none of these three directions is legal (all not streets or lights or crosswalk lights), the bicycle turns around. Bicycles stop for yellow and red lights; if a traffic light or crosswalk light is immediately ahead of the bicycle and the light is not green, the bicycle stays still and does not move unless a trail is to the left or right. If a bicycle is facing a red or yellow light and there is a trail to the left or right, the bicycle will turn to face the trail. Collision behavior: A bicycle dies if it collides with a living truck, car, or ATV. It stays dead for 30 moves.

Human Constructor: public Human(int theX, int theY, Direction theDir) Images: human.gif (alive), human_dead.gif (dead) Movement behavior: Humans move in a random direction (straight, left, right, or reverse), always on grass or crosswalks. Human never reverse direction unless there is no other option. If a human is next to a crosswalk it will always choose to turn to face in the direction of the crosswalk. (The map of terrain will never contain crosswalks that are so close together that a human might be adjacent to more than one at the same time.) Humans do not travel through crosswalks when the crosswalk light is green. If a human is facing a green crosswalk, it will wait until the light changes to yellow and then cross through the crosswalk. The human will not turn to avoid the crosswalk. Humans travel through crosswalks when the crosswalk light is yellow or red. Collision behavior: A human dies if it collides with any living vehicle except another human, and stays dead for 40 moves.

Implementation Guidelines: The GUI's interaction with your various vehicle classes is the following: When the GUI initially loads, it creates several instances of each of your vehicle classes (this is why there are compile errors in the GUI as initially provided to you; it is trying to create instances of classes you have not yet written). The GUI draws each vehicle on the map by asking for its getImageFileName string, and then loading an image file from the current directory. So, if a Human object returns "human.gif" from its getImageFileName method, it will be drawn by showing that image. When you click the Start or Step buttons, the GUI updates the state of the overall map and the state of every vehicle. The Start button causes repeated updates, while the Step button causes a single update. 4 of 10 On each update, the GUI calls the chooseDirection method on each living vehicle to see which way it prefers to move. The chooseDirection method parameter informs the vehicle about what terrain is around it. The vehicle uses this information to pick the direction it would like to move. Note that a vehicle may prefer to move in a direction that it is not currently able to move in. In particular, when stopped at a traffic light, the chooseDirection method can return the direction that would take the vehicle through the traffic light, while the canPass method (described next) reports that the vehicle cannot actually pass through the traffic light. After each vehicle reports its preferred direction of movement, the GUI controller checks each vehicle to see whether it can move in the preferred direction by calling the canPass method, passing the appropriate type of terrain and street light status. If the vehicle can traverse the given terrain with the given street light status, the GUI controller updates the vehicle's X and Y coordinates by calling its setX and setY methods, and modifies its direction by calling its setDirection method. If the vehicle cannot traverse the given terrain with the given street light status, it sits still for the round. NOTE: Every live vehicle should move on every update cycle unless stopped at a street light or crosswalk light. On each update, the GUI notifies any dead vehicles that an update has occurred by calling their poke method. Each type of vehicle has a predefined number of pokes after which it should revive itself; for example, a dead Car should revive itself after 10 pokes. Live vehicles are never poked. Vehicles should not move on the update in which they revive. Instead, they should revive after the correct number of pokes and face in a random direction. On the next update after they revive they should move. At predefined intervals, the GUI changes the map's lights in a cycle (green, yellow, red, green). Note: No vehicles will start on walls and no vehicles should at any time move onto walls. Each of your vehicle classes must have a constructor as specified in the descriptions above. Do not change the number, type or order of the parameters. You may change parameter names if you choose. Each vehicle must also implement the following methods of the instructor-provided Vehicle interface.

Each of your vehicle classes must have a constructor as specified in the descriptions above. Do not change the number, type or order of the parameters. You may change parameter names if you choose. Each vehicle must also implement the following methods of the instructor-provided Vehicle interface.

public Direction chooseDirection(Map theNeighbors) A query that returns the direction in which this vehicle would like to move, given the specified information. Different vehicles have different movement behaviors, as described previously. theNeighbors is a Map containing the types of terrain that neighbor this vehicle. The keys are instances of the Direction enumeration, such as Direction.WEST, and the values are instances of the Terrain enumeration, such as Terrain.STREET and Terrain.GRASS. The values are guaranteed to be non-null. To access the terrain in a particular direction, retrieve it by specifying the direction you wish to check. For example, to see whether the square to the west contains a street, one could write code such as the following: if (theNeighbors.get(Direction.WEST) == Terrain.STREET) {// something} OR to see whether the square to the left contains a street, one could write code such as the following: if (theNeighbors.get(getDirection().left()) == Terrain.STREET) {// something}

public boolean canPass(Terrain theTerrain, Light theLight) A query that returns whether this vehicle can pass through the given type of terrain, when the street lights are in the given state. Different vehicles respond in different ways, as described previously. For example, a Bicycle can pass the Terrain.STREET terrain type and can also pass the Terrain.LIGHT terrain type if the light status represented by theLight is Light.GREEN. 5 of 10 public void collide(Vehicle theOther) A command that notifies this vehicle that it has collided with the given other Vehicle object. Different vehicles respond in different ways, as described previously. Collisions should only have an effect when they occur between two vehicles that are alive. When the GUI notices that two vehicles have collided (whether they are both alive or not), it calls this method on each vehicle; the order in which this happens is not defined. Each vehicle should handle only the update of its own status and not the update of the other vehicles status.

public String getImageFileName() A query that returns the name of the image file that the GUI will use to draw this Vehicle object on the screen. For example, a living Car object should return the string "car.gif" and a dead Human object should return the string "human_dead.gif". public int getDeathTime() A query that returns the number of updates between this vehicle's death and when it should revive. For example, a Car should lie dead for 10 updates and then revive (on the 10th update). Calling getDeathTime() on a Car object should always return 10. public Direction getDirection() A query that returns the direction this vehicle is facing, one of Direction.NORTH, Direction.SOUTH, Direction.EAST, or Direction.WEST. public int getX() public int getY() Queries that return the x and y coordinates of this vehicle.

public boolean isAlive() A query that returns whether this vehicle is alive; that is, if it has not collided with a more powerful vehicle and gotten killed. Killed vehicles revive themselves after a certain number of turns, as described previously.

public void poke() A command called by the graphical user interface once for each time the city animates one turn. This allows dead vehicles to keep track of how long they have been dead and revive themselves appropriately. Live vehicles are never poked. When a dead vehicle revives, it must set its direction to be a random direction. The static method Direction.random() is useful for this purpose. public void reset() A command that instructs this Vehicle object to return to the initial state (including position, direction, and being alive) it had when it was constructed. public void setDirection(Direction theDir) 6 of 10 A command that sets the movement direction of this vehicle. This should only be called by the GUI controller, and (possibly) your poke() and/or reset() methods to set direction at revival or reset. It should never be called by canPass() or chooseDirection()

public void setX(int theX)

Commands that set the x and y coordinates of this Vehicle.

public void setY(int theY)

These should only be called by the GUI controller, and (possibly) your reset() method. It should never be called by canPass() or chooseDirection() For this assignment, you do not need to code defensively. That is, you may assume that the GUI will only pass reasonable parameters to your methods.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Secrets Of Analytical Leaders Insights From Information Insiders

Authors: Wayne Eckerson

1st Edition

1935504347, 9781935504344

More Books

Students also viewed these Databases questions