diff --git a/racevisionGame/src/main/java/mock/model/MockBoat.java b/racevisionGame/src/main/java/mock/model/MockBoat.java index 86570c75..227dfe54 100644 --- a/racevisionGame/src/main/java/mock/model/MockBoat.java +++ b/racevisionGame/src/main/java/mock/model/MockBoat.java @@ -76,7 +76,7 @@ public class MockBoat extends Boat implements Collider { public Bearing calculateBearingToNextMarker() { //Get the start and end points. - GPSCoordinate currentPosition = this.getCurrentPosition(); + GPSCoordinate currentPosition = this.getPosition(); GPSCoordinate nextMarkerPosition; // if boat is at the finish @@ -101,7 +101,7 @@ public class MockBoat extends Boat implements Collider { public double calculateDistanceToNextMarker() { //Get start and end markers. - GPSCoordinate startPosition = this.getCurrentPosition(); + GPSCoordinate startPosition = this.getPosition(); //When boats finish, their "current leg" doesn't have an end marker. if (this.getCurrentLeg().getEndCompoundMark() == null) { @@ -159,8 +159,8 @@ public class MockBoat extends Boat implements Collider { */ public void moveForwards(double meters) { //Updates the current position of the boat. - GPSCoordinate newPosition = GPSCoordinate.calculateNewPosition(this.getCurrentPosition(), meters, Azimuth.fromBearing(this.getBearing())); - this.setCurrentPosition(newPosition); + GPSCoordinate newPosition = GPSCoordinate.calculateNewPosition(this.getPosition(), meters, Azimuth.fromBearing(this.getBearing())); + this.setPosition(newPosition); } @@ -218,7 +218,7 @@ public class MockBoat extends Boat implements Collider { * @return true if mark is on port side */ public boolean isPortSide(Mark mark){ - Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition()); + Bearing towardsMark = GPSCoordinate.calculateBearing(this.getPosition(), mark.getPosition()); if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){ //south quadrant return this.getBearing().degrees() <= 180; @@ -244,7 +244,7 @@ public class MockBoat extends Boat implements Collider { */ public boolean isStarboardSide(Mark mark){ //if this boat is lower than the mark check which way it is facing - Bearing towardsMark = GPSCoordinate.calculateBearing(this.getCurrentPosition(), mark.getPosition()); + Bearing towardsMark = GPSCoordinate.calculateBearing(this.getPosition(), mark.getPosition()); if (towardsMark.degrees() > 315 || towardsMark.degrees() <= 45){ //south quadrant return !(this.getBearing().degrees() <= 180); @@ -306,8 +306,8 @@ public class MockBoat extends Boat implements Collider { @Override public boolean rayCast(MockBoat boat, double distance) { - double actualDistance = GPSCoordinate.calculateDistanceMeters(boat.getCurrentPosition(), this.getCurrentPosition()); - Bearing absolute = GPSCoordinate.calculateBearing(boat.getCurrentPosition(), this.getCurrentPosition()); + double actualDistance = GPSCoordinate.calculateDistanceMeters(boat.getPosition(), this.getPosition()); + Bearing absolute = GPSCoordinate.calculateBearing(boat.getPosition(), this.getPosition()); Bearing relative = Bearing.fromDegrees(absolute.degrees() - boat.getBearing().degrees()); if(actualDistance <= distance) { diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 7df41b1f..e25c0909 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -2,7 +2,6 @@ package mock.model; import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.RaceStatusEnum; -import network.Messages.LatestMessages; import shared.dataInput.BoatDataSource; import shared.dataInput.RaceDataSource; import shared.dataInput.RegattaDataSource; @@ -195,7 +194,7 @@ public class MockRace extends Race { boat.setCurrentSpeed(0d); //Place the boat at its starting position. - boat.setCurrentPosition(startPosition); + boat.setPosition(startPosition); //Boats start facing their next marker. boat.setBearing(boat.calculateBearingToNextMarker()); @@ -400,7 +399,7 @@ public class MockRace extends Race { Bearing bearing = Bearing.fromDegrees(angle); //Check that if it is acceptable. - boolean bearingIsGood = this.checkBearingInsideCourse(bearing, boat.getCurrentPosition()); + boolean bearingIsGood = this.checkBearingInsideCourse(bearing, boat.getPosition()); if (lastAngle != -1) { @@ -475,7 +474,7 @@ public class MockRace extends Race { case 0://hasn't started rounding if (boat.isPortSide(roundingMark) && GPSCoordinate.passesLine(roundingMark.getPosition(), - roundingChecks.get(0), boat.getCurrentPosition(), legBearing) && + roundingChecks.get(0), boat.getPosition(), legBearing) && gateCheck && boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) { boat.increaseRoundingStatus(); if (boat.getCurrentLeg().getLegNumber() + 2 >= legs.size()){ @@ -487,7 +486,7 @@ public class MockRace extends Race { case 1://has been parallel to the mark; if (boat.isPortSide(roundingMark) && GPSCoordinate.passesLine(roundingMark.getPosition(), - roundingChecks.get(1), boat.getCurrentPosition(), + roundingChecks.get(1), boat.getPosition(), Bearing.fromDegrees(legBearing.degrees() - 90)) &&//negative 90 from bearing because of port rounding boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) { boat.increaseRoundingStatus(); @@ -519,7 +518,7 @@ public class MockRace extends Race { case 0://hasn't started rounding if (boat.isStarboardSide(roundingMark) && GPSCoordinate.passesLine(roundingMark.getPosition(), - roundingChecks.get(0), boat.getCurrentPosition(), legBearing) && + roundingChecks.get(0), boat.getPosition(), legBearing) && gateCheck && boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(0)))) { boat.increaseRoundingStatus(); @@ -532,7 +531,7 @@ public class MockRace extends Race { case 1://has been parallel to the mark if (boat.isStarboardSide(roundingMark) && GPSCoordinate.passesLine(roundingMark.getPosition(), - roundingChecks.get(1), boat.getCurrentPosition(), Bearing.fromDegrees(legBearing.degrees() + 90)) && //positive 90 from bearing because of starboard rounding + roundingChecks.get(1), boat.getPosition(), Bearing.fromDegrees(legBearing.degrees() + 90)) && //positive 90 from bearing because of starboard rounding boat.isBetweenGate(roundingMark, Mark.tempMark(roundingChecks.get(1)))) { boat.increaseRoundingStatus(); } diff --git a/racevisionGame/src/main/java/mock/model/RaceServer.java b/racevisionGame/src/main/java/mock/model/RaceServer.java index 969a4c71..af343666 100644 --- a/racevisionGame/src/main/java/mock/model/RaceServer.java +++ b/racevisionGame/src/main/java/mock/model/RaceServer.java @@ -2,10 +2,8 @@ package mock.model; import network.Messages.*; import network.Messages.Enums.BoatLocationDeviceEnum; -import network.Utils.AC35UnitConverter; import shared.model.Bearing; import shared.model.CompoundMark; -import shared.model.Constants; import shared.model.Mark; import java.util.ArrayList; @@ -127,8 +125,8 @@ public class RaceServer { BoatLocation boatLocation = new BoatLocation( boat.getSourceID(), - boat.getCurrentPosition().getLatitude(), - boat.getCurrentPosition().getLongitude(), + boat.getPosition().getLatitude(), + boat.getPosition().getLongitude(), this.boatLocationSequenceNumber, BoatLocationDeviceEnum.RacingYacht, boat.getBearing(), diff --git a/racevisionGame/src/main/java/mock/model/SplitTODO.java b/racevisionGame/src/main/java/mock/model/SplitTODO.java deleted file mode 100644 index 20f14973..00000000 --- a/racevisionGame/src/main/java/mock/model/SplitTODO.java +++ /dev/null @@ -1,555 +0,0 @@ -//package mock.model; -// -//import javafx.animation.AnimationTimer; -//import network.Messages.BoatLocation; -//import network.Messages.BoatStatus; -//import network.Messages.Enums.BoatStatusEnum; -//import network.Messages.Enums.RaceStatusEnum; -//import network.Messages.LatestMessages; -//import network.Messages.RaceStatus; -//import network.Utils.AC35UnitConverter; -//import shared.dataInput.BoatDataSource; -//import shared.dataInput.RaceDataSource; -//import shared.dataInput.RegattaDataSource; -//import shared.model.*; -// -//import java.time.ZonedDateTime; -//import java.time.temporal.ChronoUnit; -//import java.util.ArrayList; -//import java.util.Iterator; -//import java.util.List; -//import java.util.Map; -// -//import static java.lang.Math.cos; -// -///** -// * Unused class, copy of MockRace so methods can be deleted once they are moved (more of a checklist) -// */ -//public class SplitTODO { -// -// -// /** -// * Represents a yacht race. -// * Has a course, boats, boundaries, etc... -// * Is responsible for simulating the race, and sending messages to a MockOutput instance. -// */ -// public class MockRace extends Race { -// -// /** -// * Constructs a race object with a given RaceDataSource, BoatDataSource, and RegattaDataSource and sends events to the given mockOutput. -// * @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 LatestMessages to send events to. -// * @param polars The polars table to be used for boat simulation. -// * @param timeScale The timeScale for the race. See {@link Constants#RaceTimeScale}. -// */ -// public MockRace(BoatDataSource boatDataSource, RaceDataSource raceDataSource, RegattaDataSource regattaDataSource, LatestMessages latestMessages, Polars polars, int timeScale) { -// -// super(boatDataSource, raceDataSource, regattaDataSource, latestMessages); -// -// this.scaleFactor = timeScale; -// } -// -// -// -// /** -// * Parse the compound marker boats through mock output. -// */ -// private void parseMarks() { -// for (CompoundMark compoundMark : this.compoundMarks) { -// -// //Get the individual marks from the compound mark. -// Mark mark1 = compoundMark.getMark1(); -// Mark mark2 = compoundMark.getMark2(); -// -// //If they aren't null, parse them (some compound marks only have one mark). -// if (mark1 != null) { -// this.parseIndividualMark(mark1); -// } -// -// if (mark2 != null) { -// this.parseIndividualMark(mark2); -// } -// -// } -// } -// -// /** -// * Parses an individual marker boat, and sends it to mockOutput. -// * @param mark The marker boat to parse. -// */ -// private void parseIndividualMark(Mark mark) { -// -// //Create message. -// BoatLocation boatLocation = new BoatLocation( -// mark.getSourceID(), -// mark.getPosition().getLatitude(), -// mark.getPosition().getLongitude(), -// this.boatLocationSequenceNumber, -// 0, 0, -// this.raceClock.getCurrentTimeMilli()); -// -// //Iterates the sequence number. -// this.boatLocationSequenceNumber++; -// -// this.latestMessages.setBoatLocation(boatLocation); -// -// -// } -// -// /** -// * Parse the boats in the race, and send it to mockOutput. -// */ -// private void parseBoatLocations() { -// -// //Parse each boat. -// for (MockBoat boat : this.boats) { -// -// this.parseIndividualBoatLocation(boat); -// -// } -// -// } -// -// /** -// * Parses an individual boat, and sends it to mockOutput. -// * @param boat The boat to parse. -// */ -// private void parseIndividualBoatLocation(MockBoat boat) { -// -// BoatLocation boatLocation = new BoatLocation( -// boat.getSourceID(), -// boat.getCurrentPosition().getLatitude(), -// boat.getCurrentPosition().getLongitude(), -// this.boatLocationSequenceNumber, -// boat.getBearing().degrees(), -// boat.getCurrentSpeed(), -// this.raceClock.getCurrentTimeMilli()); -// -// //Iterates the sequence number. -// this.boatLocationSequenceNumber++; -// -// this.latestMessages.setBoatLocation(boatLocation); -// -// } -// -// -// /** -// * Updates the race time to a specified value, in milliseconds since the unix epoch. -// * @param currentTime Milliseconds since unix epoch. -// */ -// private void updateRaceTime(long currentTime) { -// this.raceClock.setUTCTime(currentTime); -// } -// -// -// /** -// * Updates the race status enumeration based on the current time. -// */ -// private void updateRaceStatusEnum() { -// -// //The millisecond duration of the race. Negative means it hasn't started, so we flip sign. -// long timeToStart = - this.raceClock.getDurationMilli(); -// -// -// if (timeToStart > Constants.RacePreStartTime) { -// //Time > 3 minutes is the prestart period. -// this.setRaceStatusEnum(RaceStatusEnum.PRESTART); -// -// } else if ((timeToStart <= Constants.RacePreStartTime) && (timeToStart >= Constants.RacePreparatoryTime)) { -// //Time between [1, 3] minutes is the warning period. -// this.setRaceStatusEnum(RaceStatusEnum.WARNING); -// -// } else if ((timeToStart <= Constants.RacePreparatoryTime) && (timeToStart > 0)) { -// //Time between (0, 1] minutes is the preparatory period. -// this.setRaceStatusEnum(RaceStatusEnum.PREPARATORY); -// -// } else { -// //Otherwise, the race has started! -// this.setRaceStatusEnum(RaceStatusEnum.STARTED); -// -// } -// -// -// } -// -// /** -// * Parses the race status, and sends it to mockOutput. -// */ -// private void parseRaceStatus() { -// -// //A race status message contains a list of boat statuses. -// List boatStatuses = new ArrayList<>(); -// -// //Add each boat status to the status list. -// for (MockBoat boat : this.boats) { -// -// BoatStatus boatStatus = new BoatStatus( -// boat.getSourceID(), -// boat.getStatus(), -// boat.getCurrentLeg().getLegNumber(), -// boat.getEstimatedTimeAtNextMark().toInstant().toEpochMilli() ); -// -// boatStatuses.add(boatStatus); -// } -// -// -// //Convert wind direction and speed to ints. //TODO this conversion should be done inside the racestatus class. -// int windDirectionInt = AC35UnitConverter.encodeHeading(this.getWindDirection().degrees()); -// int windSpeedInt = (int) (this.getWindSpeed() * Constants.KnotsToMMPerSecond); -// -// //Create race status object, and send it. -// RaceStatus raceStatus = new RaceStatus( -// System.currentTimeMillis(), -// this.raceId, -// this.getRaceStatusEnum().getValue(), -// this.raceClock.getStartingTimeMilli(), -// windDirectionInt, -// windSpeedInt, -// this.getRaceType().getValue(), -// boatStatuses); -// -// -// this.latestMessages.setRaceStatus(raceStatus); -// -// -// } -// -// -// /** -// * Sets the status of all boats in the race to RACING. -// */ -// private void setBoatsStatusToRacing() { -// -// for (MockBoat boat : this.boats) { -// boat.setStatus(BoatStatusEnum.RACING); -// } -// } -// -// -// /** -// * Sets the estimated time at next mark for each boat to a specified time. This is used during the countdown timer to provide this value to boat before the race starts. -// * @param time The time to provide to each boat. -// */ -// private void setBoatsTimeNextMark(ZonedDateTime time) { -// -// for (MockBoat boat : this.boats) { -// boat.setEstimatedTimeAtNextMark(time); -// } -// } -// -// -// /** -// * Countdown timer until race starts. -// */ -// protected AnimationTimer countdownTimer = new AnimationTimer() { -// -// -// long currentTime = System.currentTimeMillis(); -// -// @Override -// public void handle(long arg0) { -// -// //Update race time. -// updateRaceTime(currentTime); -// -// //Update the race status based on the current time. -// updateRaceStatusEnum(); -// -// //Provide boat's with an estimated time at next mark until the race starts. -// setBoatsTimeNextMark(raceClock.getCurrentTime()); -// -// //Parse the boat locations. -// parseBoatLocations(); -// -// //Parse the marks. -// parseMarks(); -// -// // Change wind direction -// changeWindDirection(); -// -// //Parse the race status. -// parseRaceStatus(); -// -// -// if (getRaceStatusEnum() == RaceStatusEnum.STARTED) { -// setBoatsStatusToRacing(); -// raceTimer.start(); -// this.stop(); -// } -// -// //Update the animations timer's time. -// currentTime = System.currentTimeMillis(); -// } -// }; -// -// -// /** -// * Timer that runs for the duration of the race, until all boats finish. -// */ -// private AnimationTimer raceTimer = new AnimationTimer() { -// -// /** -// * Start time of loop, in milliseconds. -// */ -// long timeRaceStarted = System.currentTimeMillis(); -// -// /** -// * Current time during a loop iteration. -// */ -// long currentTime = System.currentTimeMillis(); -// -// /** -// * The time of the previous frame, in milliseconds. -// */ -// long lastFrameTime = timeRaceStarted; -// -// @Override -// public void handle(long arg0) { -// -// //Get the current time. -// currentTime = System.currentTimeMillis(); -// -// //Update race time. -// updateRaceTime(currentTime); -// -// -// //As long as there is at least one boat racing, we still simulate the race. -// if (getNumberOfActiveBoats() != 0) { -// -// //Get the time period of this frame. -// long framePeriod = currentTime - lastFrameTime; -// -// //For each boat, we update its position, and generate a BoatLocationMessage. -// for (MockBoat boat : boats) { -// -// //If it is still racing, update its position. -// if (boat.getStatus() == BoatStatusEnum.RACING) { -// -// updatePosition(boat, framePeriod, raceClock.getDurationMilli()); -// -// } -// -// } -// -// } else { -// //Otherwise, the race is over! -// raceFinished.start(); -// setRaceStatusEnum(RaceStatusEnum.FINISHED); -// this.stop(); -// } -// -// if (getNumberOfActiveBoats() != 0) { -// // Change wind direction -// changeWindDirection(); -// -// //Parse the boat locations. -// parseBoatLocations(); -// -// //Parse the marks. -// parseMarks(); -// -// //Parse the race status. -// parseRaceStatus(); -// -// -// //Update the last frame time. -// this.lastFrameTime = currentTime; -// } -// } -// }; -// -// /** -// * Broadcast that the race has finished. -// */ -// protected AnimationTimer raceFinished = new AnimationTimer(){ -// int iters = 0; -// @Override -// public void handle(long now) { -// -// parseRaceStatus(); -// -// if (iters > 500) { -// stop(); -// } -// iters++; -// } -// }; -// -// -// /** -// * Calculates a boat's VMG. -// * @param boat The boat to calculate VMG for. -// * @return VMG for the specified boat. -// */ -// private VMG calculateVMG(MockBoat boat) { -// -// -// //Find the VMG inside these bounds. -// VMG bestVMG = boat.getPolars().calculateVMG(this.getWindDirection(), this.getWindSpeed(), boat.calculateBearingToNextMarker(), Bearing.fromDegrees(0d), Bearing.fromDegrees(359.99999d)); -// -// -// return bestVMG; -// -// } -// -// -// /** -// * Determines whether or not a given VMG improves the velocity of a boat, if it were currently using currentVMG. -// * @param currentVMG The current VMG of the boat. -// * @param potentialVMG The new VMG to test. -// * @param bearingToDestination The bearing between the boat and its destination. -// * @return True if the new VMG is improves velocity, false otherwise. -// */ -// private boolean improvesVelocity(VMG currentVMG, VMG potentialVMG, Bearing bearingToDestination) { -// -// //Calculates the angle between the boat and its destination. -// Angle angleBetweenDestAndHeading = Angle.fromDegrees(currentVMG.getBearing().degrees() - bearingToDestination.degrees()); -// -// //Calculates the angle between the new VMG and the boat's destination. -// Angle angleBetweenDestAndNewVMG = Angle.fromDegrees(potentialVMG.getBearing().degrees() - bearingToDestination.degrees()); -// -// -// //Calculate the boat's current velocity. -// double currentVelocity = Math.cos(angleBetweenDestAndHeading.radians()) * currentVMG.getSpeed(); -// -// //Calculate the potential velocity with the new VMG. -// double vmgVelocity = Math.cos(angleBetweenDestAndNewVMG.radians()) * potentialVMG.getSpeed(); -// -// //Return whether or not the new VMG gives better velocity. -// return vmgVelocity > currentVelocity; -// -// } -// -// /** -// * Determines whether or not a given VMG improves the velocity of a boat. -// * @param boat The boat to test. -// * @param vmg The new VMG to test. -// * @return True if the new VMG is improves velocity, false otherwise. -// */ -// private boolean improvesVelocity(MockBoat boat, VMG vmg) { -// -// //Get the boats "current" VMG. -// VMG boatVMG = new VMG(boat.getCurrentSpeed(), boat.getBearing()); -// -// //Check if the new VMG is better than the boat's current VMG. -// return this.improvesVelocity(boatVMG, vmg, boat.calculateBearingToNextMarker()); -// -// } -// -// -// /** -// * Calculates the distance a boat has travelled and updates its current position according to this value. -// * -// * @param boat The boat to be updated. -// * @param updatePeriodMilliseconds The time, in milliseconds, since the last update. -// * @param totalElapsedMilliseconds The total number of milliseconds that have elapsed since the start of the race. -// */ -// protected void updatePosition(MockBoat boat, long updatePeriodMilliseconds, long totalElapsedMilliseconds) { -// -// //Checks if the current boat has finished the race or not. -// boolean finish = this.isLastLeg(boat.getCurrentLeg()); -// -// if (!finish) { -// -// -// //Calculates the distance travelled, in meters, in the current timeslice. -// double distanceTravelledMeters = boat.calculateMetersTravelled(updatePeriodMilliseconds); -// -// //Scale it. -// distanceTravelledMeters = distanceTravelledMeters * this.scaleFactor; -// -// -// //Move the boat forwards that many meters, and advances its time counters by enough milliseconds. -// boat.moveForwards(distanceTravelledMeters, updatePeriodMilliseconds * this.scaleFactor); -// -// long tackPeriod = 15000; -// if (boat.getTimeSinceTackChange() > tackPeriod) { -// //Calculate the new VMG. -// VMG newVMG = this.calculateVMG(boat); -// -// -// //If the new vmg improves velocity, use it. -// if (improvesVelocity(boat, newVMG)) { -// boat.setVMG(newVMG); -// -// } -// } -// -// this.updateEstimatedTime(boat); -// -// -// //Check the boats position (update leg and stuff). -// this.checkPosition(boat, totalElapsedMilliseconds); -// -// } -// -// } -// -// -// /** -// * Checks if a boat has finished any legs, or has pulled out of race (DNF). -// * @param boat The boat to check. -// * @param timeElapsed The total time, in milliseconds, that has elapsed since the race started. -// */ -// protected void checkPosition(MockBoat boat, long timeElapsed) { -// -// //The distance, in nautical miles, within which the boat needs to get in order to consider that it has reached the marker. -// double epsilonNauticalMiles = 100.0 / Constants.NMToMetersConversion; //100 meters. TODO should be more like 5-10. -// -// if (boat.calculateDistanceToNextMarker() < epsilonNauticalMiles) { -// //Boat has reached its target marker, and has moved on to a new leg. -// -// -// -// //Calculate how much the boat overshot the marker by. -// double overshootMeters = boat.calculateDistanceToNextMarker(); -// -// -// //Move boat on to next leg. -// Leg nextLeg = this.legs.get(boat.getCurrentLeg().getLegNumber() + 1); -// boat.setCurrentLeg(nextLeg); -// -// //Add overshoot distance into the distance travelled for the next leg. -// boat.setDistanceTravelledInLeg(overshootMeters); -// -// //Setting a high value for this allows the boat to immediately do a large turn, as it needs to in order to get to the next mark. -// boat.setTimeSinceTackChange(999999); -// -// -// //Check if the boat has finished or stopped racing. -// -// if (this.isLastLeg(boat.getCurrentLeg())) { -// //Boat has finished. -// boat.setTimeFinished(timeElapsed); -// boat.setCurrentSpeed(0); -// boat.setStatus(BoatStatusEnum.FINISHED); -// -// } -// -// } -// -// } -// -// /** -// * Updates the boat's estimated time to next mark if positive -// * @param boat to estimate time given its velocity -// */ -// private void updateEstimatedTime(MockBoat boat) { -// -// double velocityToMark = boat.getCurrentSpeed() * cos(boat.getBearing().radians() - boat.calculateBearingToNextMarker().radians()) / Constants.KnotsToMMPerSecond; -// -// if (velocityToMark > 0) { -// -// //Calculate milliseconds until boat reaches mark. -// long timeFromNow = (long) (1000 * boat.calculateDistanceToNextMarker() / velocityToMark); -// -// //Calculate time at which it will reach mark. -// ZonedDateTime timeAtMark = this.raceClock.getCurrentTime().plus(timeFromNow, ChronoUnit.MILLIS); -// boat.setEstimatedTimeAtNextMark(timeAtMark); -// } -// -// } -// } -//} diff --git a/racevisionGame/src/main/java/shared/model/Boat.java b/racevisionGame/src/main/java/shared/model/Boat.java index 385c4f3b..9d1d0c40 100644 --- a/racevisionGame/src/main/java/shared/model/Boat.java +++ b/racevisionGame/src/main/java/shared/model/Boat.java @@ -10,7 +10,7 @@ import java.time.ZonedDateTime; /** * Boat Model that is used to store information on the boats that are running in the race. */ -public class Boat { +public class Boat implements Locatable { /** * The name of the boat/team. */ @@ -30,7 +30,7 @@ public class Boat { /** * The current position of the boat. */ - private GPSCoordinate currentPosition; + private GPSCoordinate position; /** * The country or team abbreviation of the boat. @@ -57,7 +57,7 @@ public class Boat { /** * The boat's position within the race (e.g., 5th). */ - private StringProperty positionInRace = new SimpleStringProperty(); + private StringProperty placing = new SimpleStringProperty(); /** @@ -107,7 +107,7 @@ public class Boat { this.bearing = Bearing.fromDegrees(0d); - setCurrentPosition(new GPSCoordinate(0, 0)); + setPosition(new GPSCoordinate(0, 0)); this.status = BoatStatusEnum.UNDEFINED; } @@ -256,41 +256,32 @@ public class Boat { * Returns the position within the race the boat has (e.g., 5th). * @return The boat's position in race. */ - public StringProperty positionProperty() { - return positionInRace; + public StringProperty placingProperty() { + return placing; } /** * Sets the position within the race the boat has (e.g., 5th). * @param position The boat's position in race. */ - public void setPosition(String position) { - this.positionInRace.set(position); + public void setPlacing(String position) { + this.placing.set(position); } - /** - * Returns the position within the race the boat has (e.g., 5th). - * @return The boat's position in race. - */ - public String getPosition() { - return this.positionInRace.get(); - } - - /** * Returns the current position of the boat. * @return The current position of the boat. */ - public GPSCoordinate getCurrentPosition() { - return currentPosition; + public GPSCoordinate getPosition() { + return position; } /** * Sets the current position of the boat. - * @param currentPosition The new position for the boat. + * @param position The new position for the boat. */ - public void setCurrentPosition(GPSCoordinate currentPosition) { - this.currentPosition = currentPosition; + public void setPosition(GPSCoordinate position) { + this.position = position; } diff --git a/racevisionGame/src/main/java/shared/model/CompoundMark.java b/racevisionGame/src/main/java/shared/model/CompoundMark.java index 66e682e5..cabf3a02 100644 --- a/racevisionGame/src/main/java/shared/model/CompoundMark.java +++ b/racevisionGame/src/main/java/shared/model/CompoundMark.java @@ -1,16 +1,11 @@ package shared.model; - -import mock.model.MockBoat; -import mock.model.collider.Collider; -import mock.model.collider.Collision; - import shared.enums.RoundingType; /** * Represents a compound mark - that is, either one or two individual marks which form a single compound mark. */ -public class CompoundMark implements Collider { +public class CompoundMark { /** * The ID of the compound mark. @@ -146,38 +141,6 @@ public class CompoundMark implements Collider { } - private Mark closestMark(GPSCoordinate coordinate) { - double mark1distance = GPSCoordinate.calculateDistanceMeters(getMark1Position(), coordinate); - double mark2distance = GPSCoordinate.calculateDistanceMeters(getMark2Position(), coordinate); - return mark1distance <= mark2distance? mark1 : mark2; - } - - @Override - public boolean rayCast(MockBoat boat, double distance) { - GPSCoordinate position = boat.getCurrentPosition(); - double actualDistance = GPSCoordinate.calculateDistanceMeters(position, closestMark(position).getPosition()); - // Compass direction of collider - Bearing absolute = Bearing.fromAzimuth(GPSCoordinate.calculateAzimuth(position, closestMark(position).getPosition())); - // Direction of collider from heading - Bearing relative = Bearing.fromDegrees(absolute.degrees() - boat.getBearing().degrees()); - - if(actualDistance <= distance) { - onCollisionEnter(new Collision(relative, distance)); - return true; - } else return false; - } - - @Override - public boolean rayCast(MockBoat boat) { - return rayCast(boat, 100); - } - - @Override - public void onCollisionEnter(Collision e) { - if(e.getBearing().degrees() < 90) System.out.println("Starboard"); - else if(e.getBearing().degrees() > 270) System.out.println("Port"); - } - /** * Used to find how far apart the marks that make up this gate are * If this compound mark is only one point return base length of 250m diff --git a/racevisionGame/src/main/java/shared/model/Locatable.java b/racevisionGame/src/main/java/shared/model/Locatable.java new file mode 100644 index 00000000..4655563d --- /dev/null +++ b/racevisionGame/src/main/java/shared/model/Locatable.java @@ -0,0 +1,9 @@ +package shared.model; + +/** + * Created by cbt24 on 16/08/17. + */ +public interface Locatable { + GPSCoordinate getPosition(); + void setPosition(GPSCoordinate position); +} diff --git a/racevisionGame/src/main/java/shared/model/Mark.java b/racevisionGame/src/main/java/shared/model/Mark.java index 2b01184a..1dddeea8 100644 --- a/racevisionGame/src/main/java/shared/model/Mark.java +++ b/racevisionGame/src/main/java/shared/model/Mark.java @@ -1,10 +1,14 @@ package shared.model; +import mock.model.MockBoat; +import mock.model.collider.Collider; +import mock.model.collider.Collision; + /** * Represents an individual mark. * Has a source ID, name, and position. */ -public class Mark { +public class Mark implements Locatable, Collider { /** * The source ID of the mark. @@ -75,4 +79,31 @@ public class Mark { public void setPosition(GPSCoordinate position) { this.position = position; } + + @Override + public boolean rayCast(MockBoat boat, double distance) { + double actualDistance = GPSCoordinate.calculateDistanceMeters(boat.getPosition(), this.position); + // Compass direction of collider + Bearing absolute = Bearing.fromAzimuth(GPSCoordinate.calculateAzimuth(boat.getPosition(), this.position)); + // Direction of collider from heading + Bearing relative = Bearing.fromDegrees(absolute.degrees() - boat.getBearing().degrees()); + + if(actualDistance <= distance) { + onCollisionEnter(new Collision(relative, distance)); + return true; + } else return false; + } + + @Override + public boolean rayCast(MockBoat boat) { + return rayCast(boat, 100); + } + + @Override + public void onCollisionEnter(Collision e) { + if(e.getBearing().degrees() == 0) System.out.println("Ahead"); + else if(e.getBearing().degrees() < 90) System.out.println("Starboard"); + else if(e.getBearing().degrees() > 270) System.out.println("Port"); + else System.out.println("Behind"); + } } diff --git a/racevisionGame/src/main/java/shared/model/Race.java b/racevisionGame/src/main/java/shared/model/Race.java index 685af9e0..a15e2edd 100644 --- a/racevisionGame/src/main/java/shared/model/Race.java +++ b/racevisionGame/src/main/java/shared/model/Race.java @@ -118,7 +118,11 @@ public abstract class Race { this.setWind(Bearing.fromDegrees(0), 0); // Set up colliders this.colliderRegistry = new ColliderRegistry(); - this.colliderRegistry.addAllColliders(compoundMarks); + + for(CompoundMark mark: compoundMarks) { + colliderRegistry.addCollider(mark.getMark1()); + if(mark.getMark2() != null) colliderRegistry.addCollider(mark.getMark2()); + } } public ColliderRegistry getColliderRegistry() { diff --git a/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatLocationCommand.java b/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatLocationCommand.java index d2c60bd7..160955bc 100644 --- a/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatLocationCommand.java +++ b/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatLocationCommand.java @@ -8,7 +8,6 @@ import shared.exceptions.MarkNotFoundException; import shared.model.GPSCoordinate; import shared.model.Mark; import visualiser.model.VisualiserBoat; -import visualiser.model.VisualiserRaceEvent; import visualiser.model.VisualiserRaceState; import java.util.logging.Level; @@ -68,7 +67,7 @@ public class BoatLocationCommand implements Command { boatLocation.getLatitude(), boatLocation.getLongitude()); - boat.setCurrentPosition(gpsCoordinate); + boat.setPosition(gpsCoordinate); //Bearing. boat.setBearing(boatLocation.getHeading()); @@ -96,7 +95,7 @@ public class BoatLocationCommand implements Command { */ private void attemptAddTrackPoint(VisualiserBoat boat) { if (boat.getStatus() == BoatStatusEnum.RACING) { - boat.addTrackPoint(boat.getCurrentPosition(), visualiserRace.getRaceClock().getCurrentTime()); + boat.addTrackPoint(boat.getPosition(), visualiserRace.getRaceClock().getCurrentTime()); } } diff --git a/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java b/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java index b6f7dff8..c5356495 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/FinishController.java @@ -67,7 +67,7 @@ public class FinishController extends Controller { boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty()); //Rank/position. - boatRankColumn.setCellValueFactory(cellData -> cellData.getValue().positionProperty()); + boatRankColumn.setCellValueFactory(cellData -> cellData.getValue().placingProperty()); //Winner label. diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 3e4c1398..7b495411 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -23,7 +23,6 @@ import visualiser.gameController.ControllerClient; import visualiser.gameController.Keys.ControlKey; import visualiser.gameController.Keys.KeyFactory; import visualiser.model.*; -import visualiser.network.ServerConnection; import java.net.URL; import java.util.ResourceBundle; @@ -293,7 +292,7 @@ public class RaceController extends Controller { //Current place within race. boatPlacingColumn.setCellValueFactory( - cellData -> cellData.getValue().positionProperty() ); + cellData -> cellData.getValue().placingProperty() ); } diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java index d58e2afd..57c864b5 100644 --- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java +++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java @@ -269,7 +269,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { boat.getName(), boat.getCountry(), boat.getCurrentSpeed(), - this.map.convertGPS(boat.getCurrentPosition()), + this.map.convertGPS(boat.getPosition()), boat.getTimeToNextMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()), boat.getTimeSinceLastMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()) ); @@ -322,7 +322,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { } //Convert position to graph coordinate. - GraphCoordinate pos = this.map.convertGPS(boat.getCurrentPosition()); + GraphCoordinate pos = this.map.convertGPS(boat.getPosition()); //The x coordinates of each vertex of the boat. double[] x = { @@ -356,7 +356,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { private void drawClientBoat(VisualiserBoat boat) { //Convert position to graph coordinate. - GraphCoordinate pos = this.map.convertGPS(boat.getCurrentPosition()); + GraphCoordinate pos = this.map.convertGPS(boat.getPosition()); //The x coordinates of each vertex of the boat. double[] x = { @@ -390,7 +390,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { private void drawWake(VisualiserBoat boat) { //Calculate either end of wake line. - GraphCoordinate wakeFrom = this.map.convertGPS(boat.getCurrentPosition()); + GraphCoordinate wakeFrom = this.map.convertGPS(boat.getPosition()); GraphCoordinate wakeTo = this.map.convertGPS(boat.getWake()); //Draw. diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java index ce966b02..a02706a6 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java @@ -1,7 +1,5 @@ package visualiser.model; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; import javafx.scene.paint.Color; import network.Messages.Enums.BoatStatusEnum; import shared.model.Azimuth; @@ -102,7 +100,7 @@ public class VisualiserBoat extends Boat { //Calculate the new coordinate. - GPSCoordinate wakeCoordinate = GPSCoordinate.calculateNewPosition(getCurrentPosition(), wakeDistanceMeters, reverseAzimuth); + GPSCoordinate wakeCoordinate = GPSCoordinate.calculateNewPosition(getPosition(), wakeDistanceMeters, reverseAzimuth); return wakeCoordinate; } diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java index b1767cd5..3315cbfa 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserRaceState.java @@ -1,7 +1,6 @@ package visualiser.model; -import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.paint.Color; @@ -228,7 +227,7 @@ public class VisualiserRaceState extends RaceState { boat.setCurrentLeg(startingLeg); boat.setTimeAtLastMark(getRaceClock().getCurrentTime()); - boat.setCurrentPosition(new GPSCoordinate(0, 0)); + boat.setPosition(new GPSCoordinate(0, 0)); } @@ -253,10 +252,10 @@ public class VisualiserRaceState extends RaceState { if ((boat.getStatus() == BoatStatusEnum.DNF) || (boat.getStatus() == BoatStatusEnum.PRESTART) || (boat.getCurrentLeg().getLegNumber() < 0)) { - boat.setPosition("-"); + boat.setPlacing("-"); } else { - boat.setPosition(Integer.toString(i + 1)); + boat.setPlacing(Integer.toString(i + 1)); } } diff --git a/racevisionGame/src/test/java/mock/model/MockBoatTest.java b/racevisionGame/src/test/java/mock/model/MockBoatTest.java index 10792a12..dcc17f1b 100644 --- a/racevisionGame/src/test/java/mock/model/MockBoatTest.java +++ b/racevisionGame/src/test/java/mock/model/MockBoatTest.java @@ -1,6 +1,5 @@ package mock.model; -import mock.model.collider.Collision; import org.junit.Before; import org.junit.Test; import shared.model.Bearing; @@ -12,17 +11,17 @@ import static org.junit.Assert.*; public class MockBoatTest { private MockBoat boat; - private CompoundMark near; - private CompoundMark far; + private Mark near; + private Mark far; @Before public void setUp() { boat = new MockBoat(0, "Bob", "NZ", null); - boat.setCurrentPosition(new GPSCoordinate(0,0)); + boat.setPosition(new GPSCoordinate(0,0)); boat.setBearing(Bearing.fromDegrees(180)); - near = new CompoundMark(0, "Near", new Mark(0, "Near", new GPSCoordinate(-.0001, 0))); - far = new CompoundMark(1, "Far", new Mark(0, "Far", new GPSCoordinate(.001, 0))); + near = new Mark(0, "Near", new GPSCoordinate(-.0001, 0)); + far = new Mark(0, "Far", new GPSCoordinate(.001, 0)); } @Test diff --git a/racevisionGame/src/test/java/shared/model/BoatTest.java b/racevisionGame/src/test/java/shared/model/BoatTest.java index c087708c..babfbb45 100644 --- a/racevisionGame/src/test/java/shared/model/BoatTest.java +++ b/racevisionGame/src/test/java/shared/model/BoatTest.java @@ -19,7 +19,7 @@ public class BoatTest { public void setUp() { ORIGIN_COORDS = new GPSCoordinate(0, 0); TEST_BOAT = new Boat(1, "Test", "tt"); - TEST_BOAT.setCurrentPosition(ORIGIN_COORDS); + TEST_BOAT.setPosition(ORIGIN_COORDS); } //TODO these bearing tests could be tidied up to reduce code repetition. @@ -113,7 +113,7 @@ public class BoatTest { Leg start = new Leg("Start", startMarker, endMarker, 0); TEST_BOAT.setCurrentLeg(start); - assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getCurrentPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 0, 1e-8); + assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 0, 1e-8); } @@ -131,7 +131,7 @@ public class BoatTest { Leg start = new Leg("Start", startMarker, endMarker, 0); TEST_BOAT.setCurrentLeg(start); - assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getCurrentPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 90, 1e-8); + assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 90, 1e-8); } @Test @@ -148,7 +148,7 @@ public class BoatTest { Leg start = new Leg("Start", startMarker, endMarker, 0); TEST_BOAT.setCurrentLeg(start); - assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getCurrentPosition(), endMarker.getAverageGPSCoordinate()).degrees(), -180, 1e-8); + assertEquals(GPSCoordinate.calculateAzimuth(TEST_BOAT.getPosition(), endMarker.getAverageGPSCoordinate()).degrees(), -180, 1e-8); } @Test @@ -165,7 +165,7 @@ public class BoatTest { Leg start = new Leg("Start", startMarker, endMarker, 0); TEST_BOAT.setCurrentLeg(start); - assertEquals(GPSCoordinate.calculateBearing(TEST_BOAT.getCurrentPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 270, 1e-8); + assertEquals(GPSCoordinate.calculateBearing(TEST_BOAT.getPosition(), endMarker.getAverageGPSCoordinate()).degrees(), 270, 1e-8); }