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.
227 lines
5.6 KiB
227 lines
5.6 KiB
package shared.model;
|
|
|
|
import javafx.animation.AnimationTimer;
|
|
import javafx.collections.FXCollections;
|
|
import mock.model.VMG;
|
|
import network.Messages.Enums.RaceStatusEnum;
|
|
import network.Messages.Enums.RaceTypeEnum;
|
|
import network.Messages.LatestMessages;
|
|
import shared.dataInput.BoatDataSource;
|
|
import shared.dataInput.RaceDataSource;
|
|
import shared.dataInput.RegattaDataSource;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
import static java.lang.Math.cos;
|
|
|
|
|
|
/**
|
|
* Represents a yacht race.
|
|
* This is a base class inherited by {@link mock.model.MockRace} and {@link visualiser.model.VisualiserRace}.
|
|
* Has a course, state, wind, boundaries, etc.... Boats are added by inheriting classes (see {@link Boat}, {@link mock.model.MockBoat}, {@link visualiser.model.VisualiserBoat}.
|
|
*/
|
|
public abstract class Race implements Runnable {
|
|
|
|
|
|
/**
|
|
* The source of race related data.
|
|
*/
|
|
protected RaceDataSource raceDataSource;
|
|
|
|
/**
|
|
* The source of boat related data.
|
|
*/
|
|
protected BoatDataSource boatDataSource;
|
|
|
|
/**
|
|
* The source of regatta related data.
|
|
*/
|
|
protected RegattaDataSource regattaDataSource;
|
|
|
|
/**
|
|
* The collection of latest race messages.
|
|
* Can be either read from or written to.
|
|
*/
|
|
protected LatestMessages latestMessages;
|
|
|
|
/**
|
|
* The sequence number of the latest boatLocation message sent or received.
|
|
*/
|
|
protected int boatLocationSequenceNumber = 1;
|
|
|
|
|
|
|
|
/**
|
|
* A list of compound marks in the race.
|
|
*/
|
|
protected List<CompoundMark> compoundMarks;
|
|
|
|
/**
|
|
* A list of legs in the race.
|
|
*/
|
|
protected List<Leg> legs;
|
|
|
|
/**
|
|
* A list of coordinates describing the boundary of the course.
|
|
*/
|
|
protected List<GPSCoordinate> boundary;
|
|
|
|
|
|
/**
|
|
* The elapsed time, in milliseconds, of the race.
|
|
*/
|
|
protected long totalTimeElapsed;
|
|
|
|
/**
|
|
* The starting timestamp, in milliseconds, of the race.
|
|
*/
|
|
protected long startTime;
|
|
|
|
|
|
/**
|
|
* The race ID of the course.
|
|
*/
|
|
protected int raceId;
|
|
|
|
/**
|
|
* The current status of the race.
|
|
*/
|
|
protected RaceStatusEnum raceStatusEnum;
|
|
|
|
/**
|
|
* The type of race this is.
|
|
*/
|
|
protected RaceTypeEnum raceType;
|
|
|
|
|
|
/**
|
|
* The current wind direction bearing.
|
|
*/
|
|
protected Bearing windDirection;
|
|
|
|
/**
|
|
* Wind speed (knots).
|
|
* Convert this to millimeters per second before passing to RaceStatus.
|
|
*/
|
|
protected double windSpeed;
|
|
|
|
|
|
|
|
/**
|
|
* Constructs a race object with a given BoatDataSource, RaceDataSource, and RegattaDataSource.
|
|
* @param boatDataSource Data source for boat related data (yachts and marker boats).
|
|
* @param raceDataSource Data source for race related data (participating boats, legs, etc...).
|
|
* @param regattaDataSource Data source for race related data (course name, location, timezone, etc...).
|
|
* @param latestMessages The collection of latest messages, which can be written to, or read from.
|
|
*/
|
|
public Race(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages) {
|
|
|
|
//Keep a reference to data sources.
|
|
this.raceDataSource = raceDataSource;
|
|
this.boatDataSource = boatDataSource;
|
|
this.regattaDataSource = regattaDataSource;
|
|
|
|
this.latestMessages = latestMessages;
|
|
|
|
|
|
this.compoundMarks = raceDataSource.getCompoundMarks();
|
|
|
|
this.boundary = raceDataSource.getBoundary();
|
|
|
|
|
|
this.useLegsList(raceDataSource.getLegs());
|
|
|
|
|
|
this.raceId = raceDataSource.getRaceId();
|
|
|
|
|
|
this.startTime = raceDataSource.getStartDateTime().toInstant().toEpochMilli();
|
|
|
|
|
|
this.setRaceStatusEnum(RaceStatusEnum.NOT_ACTIVE);
|
|
this.raceType = raceDataSource.getRaceType();
|
|
|
|
this.windSpeed = 0;
|
|
this.windDirection = Bearing.fromDegrees(0);
|
|
|
|
this.totalTimeElapsed = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Initialise the boats in the race.
|
|
* This sets their starting positions and current legs.
|
|
*/
|
|
protected abstract void initialiseBoats();
|
|
|
|
|
|
/**
|
|
* Updates the race to use a new list of legs, and adds a dummy "Finish" leg at the end.
|
|
* @param legs The new list of legs to use.
|
|
*/
|
|
protected void useLegsList(List<Leg> legs) {
|
|
//We add a "dummy" leg at the end of the race.
|
|
this.legs = legs;
|
|
this.legs.add(new Leg("Finish", this.legs.size()));
|
|
}
|
|
|
|
/**
|
|
* Determines whether or not a specific leg is the last leg in the race.
|
|
* @param leg The leg to check.
|
|
* @return Returns true if it is the last, false otherwise.
|
|
*/
|
|
protected boolean isLastLeg(Leg leg) {
|
|
|
|
//Get the last leg.
|
|
Leg lastLeg = this.legs.get(this.legs.size() - 1);
|
|
|
|
//Check its ID.
|
|
int lastLegID = lastLeg.getLegNumber();
|
|
|
|
//Get the specified leg's ID.
|
|
int legID = leg.getLegNumber();
|
|
|
|
|
|
//Check if they are the same.
|
|
return legID == lastLegID;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Returns the current race status.
|
|
* @return The current race status.
|
|
*/
|
|
public RaceStatusEnum getRaceStatusEnum() {
|
|
return raceStatusEnum;
|
|
}
|
|
|
|
/**
|
|
* Sets the current race status.
|
|
* @param raceStatusEnum The new status of the race.
|
|
*/
|
|
protected void setRaceStatusEnum(RaceStatusEnum raceStatusEnum) {
|
|
this.raceStatusEnum = raceStatusEnum;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the type of race this is.
|
|
* @return The type of race this is.
|
|
*/
|
|
public RaceTypeEnum getRaceType() {
|
|
return raceType;
|
|
}
|
|
|
|
|
|
|
|
}
|