You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
4.3 KiB

package seng302.Model;
import seng302.Controllers.RaceController;
import seng302.GPSCoordinate;
import java.util.*;
/**
* Parent class for races
* Created by fwy13 on 3/03/17.
*/
public abstract class Race implements Runnable {
protected BoatInRace[] startingBoats;
protected ArrayList<Leg> legs;
protected RaceController controller;
protected int boatsFinished = 0;
private int SLEEP_TIME = 1000; //time in milliseconds to pause in a paced loop
/**
* Initailiser for Race
* @param boats Takes in an array of boats that are participating in the race.
* @param marks Number of marks in order that the boats pass in order to complete the race.
*/
public Race(BoatInRace[] boats, ArrayList<Leg> marks, RaceController controller) {
this.startingBoats = boats;
this.legs = marks;
this.legs.add(new Leg("Finish"));
this.controller = controller;
}
public Race(BoatInRace[] boats, ArrayList<Leg> marks) {
this(boats, marks, null);
}
public void run() {
updateController();
preRace();
simulateRace();
}
private void preRace() {
//show the boats participating.
System.out.println("Boats Participating:");
System.out.println("====================");
for (int i = 0; i < startingBoats.length; i++) {
System.out.println(i + 1 + ". " + startingBoats[i].getName() + ", Speed: " + Math.round(startingBoats[i].getVelocity() * 1.94384) + "kn");
startingBoats[i].setCurrentLeg(legs.get(0));
}
}
/**
* Starts the Race Simulation, playing the race start to finish with the timescale.
* This prints the boats participating, the order that the events occur in time order, and the respective information of the events.
*/
private void simulateRace() {
long timeRaceStarted = System.currentTimeMillis();
long totalTimeElapsed;
long timeLoopStarted;
long timeLoopEnded;
long minutes;
long currentTimeInSeconds;
long remainingSeconds;
while (boatsFinished < startingBoats.length) {
timeLoopStarted = System.currentTimeMillis();
totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
long currentTime = System.currentTimeMillis() - timeRaceStarted;
currentTimeInSeconds = currentTime / 1000;
minutes = currentTimeInSeconds / 60;
remainingSeconds = currentTimeInSeconds % 60;
System.out.println(minutes + ":" + remainingSeconds);
for (BoatInRace boat : startingBoats) {
updatePosition(boat, SLEEP_TIME);
checkPosition(boat, totalTimeElapsed);
}
try {
timeLoopEnded = System.currentTimeMillis();
Thread.sleep(SLEEP_TIME - (timeLoopEnded - timeLoopStarted));
} catch (InterruptedException e) {
return;
}
}
}
protected void checkPosition(BoatInRace boat, long timeElapsed) {
if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()){
updateController();
//boat has passed onto new leg
if (boat.getCurrentLeg().getName().equals("Finish")) {
//boat has finished
boat.setTimeFinished(timeElapsed);
boatsFinished++;
} else {
boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg() - boat.getCurrentLeg().getDistance());
Leg nextLeg = legs.get(boat.getCurrentLeg().getLegNumber() + 1);
boat.setCurrentLeg(nextLeg);
boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg());
}
}
}
protected void updateController() {
if(controller != null) controller.updateInfoTable(this);
}
public BoatInRace[] getStartingBoats() {
return startingBoats;
}
/**
* This function is a function that generates the Race and populates the events list.
* Is automatically called by the initialiser function, so that simulateRace() does not return an empty race.
* @see Race#simulateRace()
*/
protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed);
}