You are part of a team making a video game simulating car racing. Car races take place on a racetrack, with a specific set of race cars, each with their own unique behaviours.

There are a range of elements that go into making the videogame simulation including the racetrack, the commentary team, pit stop crews, crowds, etc. Behind the scenes, the game also needs to handle graphics and models and player input, but in this scenario, you are only concerned with 1) managing a small subset of these problems and 2) ensuring that other developers can extend your code to make use of it in their work without modifying it. Your responsibilities are divided into then following main areas:

RaceWeather

You should build on the class called RaceWeather. This class will be responsible for storing the state of the weather and updating other, interested classes about changes in the weather. You have a skeleton for the class provided that:

  • Represents weather as an enumerated WeatherType: DRY, MISTY, or WET
  • Declares a changeWeather() method that changes the status of the weather in a cycle. DRY will become MISTY, MISTY will become WET and WET goes back to DRY.

You should add the following functionality:

  • Allow other classes to register their interest in being updated about the weather and unregister it.
  • Update classes that are interested in changes in the weather when the weather changes.

Bear in mind:

  • Whether other programmers can make use of your RaceWeather class without changing its code.
  • Whether the class can handle any number of interested instances.
  • Whether the class can handle different types of interested class.

Hints:

  • Implementation is not the challenge; the hard part is ensuring that other coders on the team can extend your code without modifying it.
  • Think about the design patterns you have been taught - you will need to modify the classes' declaration to implement the correct design pattern.
  • You will need to create other classes as part of this process.

RaceCar

You should build on the class called RaceCar. This class represents a single Race Car in your game. You have a skeleton for the class provided that

  • Stores the name of the RaceCar (String), distance travelled in the race (int initially at 0), and the manufacturer (String).
  • getStatus() returns a string documenting the progress of the car in the race.

You should add the following functionality:

  • The RaceCar should initially be able to have one of two different types of driving behaviour based on whether the car is driven cautiously or being driven fast. The driveCar() function should return the appropriate int value based on the weather and behaviour taken from the table below:

Weather Condition Cautious Distance on driveCar() Fast Distance on driveCar()
DRY 10 20
MISTY 10 5
WET 10 8

  • Awareness of the weather - you should enable each instance of RaceCar to be updated when the RaceWeather changes and store the state of the weather in a WeatherType.
  • The changeDrivingBehaviour() function should be able to alter the cars driving behaviour at runtime changing it between cautious and fast initially - you will need to determine how this should be done and the parameters that the method takes in.

Bear in mind that you will be assessed on the following areas:

  • Other developers should be able to implement their own behaviours for the car based on the weather and use them without having to modify your RaceCar code.

Hints:

  • The same hints given for RaceWeather also apply here.
  • You're race cars will need to make use of the RaceWeather instance - make sure you follow the appropriate design pattern!
  • You will need to alter the constructor for the RaceCar class.

Race

The Race class provides a skeleton for the following:

  • The Race class stores racers, an ArrayList of the cars currently racing, an instance of RaceWeather that handles changes in the weather, and a racetrackDistance int that specifies how many meters the cars racing need to travel to complete the race.
  • progressWeather() calls the changeWeather() function of the RaceWeather object and should not need to be edited.
  • main(String args) creates a race object, makes four cars and, while the race is not over, calls the raceStep() function. When the race completes, it prints out the final outcome taken from raceOutcome.

You should edit the class to implement the following functionality:

  • raceStep() should move the race forward one "step" by calling the driveCar() method of all cars racing and printing out their status.
  • isFinished() should return true if a RaceCar has driven beyond the racetrackDistance and false otherwise.
  • getOutcome() should return a string of the format: "WINNER: " + Winning car name + , + Winning car make In the event more than one car has finished the race, the winner is the one that drove the furthest. If two or more cars have driven the same distance, return the string TIE.
  • makeFourCars() should populate the racers ArrayList with the following four cars:

Car Name Make Driving Type
Car 1 Fjord Cautious
Car 2 Fjord Fast
Car 3 Furbi Cautious
Car 4 Furbi Fast

  • changeCarBehaviour should take in an integer corresponding to the position of a RaceCar instance in the racers ArrayList and alter its behaviour. The method can take additional parameters as you deem necessary.

Starter Code

Race.java

import java.util.ArrayList;

public class Race
{
private RaceWeather raceWeather;
private int raceTrackDistance;
private ArrayList< RaceCar > racers = new ArrayList< RaceCar >();
private final int numberOfStepsToChange = 5;

public Race(WeatherType weather, int raceTrackDistance)
{
raceWeather = new RaceWeather(weather);
this.raceTrackDistance = raceTrackDistance;
}

private String getOutcome()
{
// to implement
return null;
}

public void progressWeather()
{
raceWeather.changeWeather();
}

public void changeCarBehaviour(int position)
{
// to implement

}

public void raceStep()
{

}

public boolean isFinished()
{
// to implement
return true;
}

private void makeFourCars()
{
// to implement
}

public void raceCars(){
int stepCount = 0;
while(!isFinished())
{
stepCount++;
raceStep();
if (stepCount%numberOfStepsToChange==0)
{
progressWeather();
}
}
}


public static void main(String[]args)
{
Race race = new Race(WeatherType.DRY, 100);
race.makeFourCars();
race.raceCars();
System.out.println(race.getOutcome());
}
}

RaceCar.java

public class RaceCar {

private int metersTravelled = 0;
private String manufacturer;
private String carName;


public RaceCar(String manufacturer, String carName)
{
this.manufacturer = manufacturer;
this.carName = carName;

}

public void driveCar()
{
// to implement
}

public void changeDrivingBehaviour()
{
// to implement
}


public String getStatus()
{
return carName + " built by " + manufacturer + " has travelled " + metersTravelled +" meters";
}
}

RaceWeather.java

public class RaceWeather
{
private WeatherType weather;

public RaceWeather(WeatherType weather)
{
this.weather = weather;
}


public void changeWeather()
{
weather = weather.next();
}


public WeatherType getWeather()
{
return weather;
}
}

WeatherType.java

public enum WeatherType {
DRY, MISTY, WET;

public WeatherType next(){
return values()[(ordinal()+1)%3];
}
}
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.