diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index cf9d06d6..b853d22b 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -46,13 +46,13 @@ public class App extends Application new Boat("SoftBank Team Japan", 10.5) }; - RaceMarker[] marks = { - new RaceMarker("Start", 0, 0, 295), - new RaceMarker("Mark", 360, 360, 250), - new RaceMarker("Leeward Gate", 965, 630, 790), - new RaceMarker("Windward Gate", 1865, 205, 0), - new RaceMarker("Leeward Gate", 2765, 630, 790), - new RaceMarker("Finish", 3035, 475, 1015) + Leg[] marks = { + new Leg("Start", 0, 0, 295), + new Leg("Mark", 360, 360, 250), + new Leg("Leeward Gate", 965, 630, 790), + new Leg("Windward Gate", 1865, 205, 0), + new Leg("Leeward Gate", 2765, 630, 790), + new Leg("Finish", 3035, 475, 1015) }; Race race = new ConstantVelocityRace(boats, marks, timescale); @@ -66,7 +66,7 @@ public class App extends Application //load the first container try { FXMLLoader loader = new FXMLLoader(); - InputStream in = getClass().getClassLoader().getResourceAsStream("scenes//mainpane.fxml"); + InputStream in = getClass().getClassLoader().getResourceAsStream("scenes/mainpane.fxml"); mainContainer = (BorderPane) loader.load(in); mainScene = new Scene(mainContainer, 800, 600); primaryStage.setScene(mainScene); diff --git a/src/main/java/seng302/BoatInRace.java b/src/main/java/seng302/BoatInRace.java new file mode 100644 index 00000000..8c31098b --- /dev/null +++ b/src/main/java/seng302/BoatInRace.java @@ -0,0 +1,41 @@ +package seng302; + +/** + * Created by esa46 on 15/03/17. + */ +public class BoatInRace extends Boat { + + private Leg currentLeg; + + public Leg getCurrentLeg() { + return currentLeg; + } + + public double getDistanceTravelledInLeg() { + return distanceTravelledInLeg; + } + + public Coordinate getCurrentPosition() { + return currentPosition; + } + + private double distanceTravelledInLeg; + private Coordinate currentPosition; + + + BoatInRace(String name, double velocity) { + super(name, velocity); + } + + /** + * Calculates the bearing of the travel via map coordinates of the raceMarkers + * @return + */ + public double calculateHeading(){ + //to be changed to coordinates when used to match reality. + double thetaHat = Math.atan2((currentLeg.getEndCoordinate().getX() - currentPosition.getX()), (currentLeg.getEndCoordinate().getY() - currentPosition.getY())); + return thetaHat >= 0 ? Math.toDegrees(thetaHat): Math.toDegrees(thetaHat + 2 * Math.PI); + } + + +} diff --git a/src/main/java/seng302/ConstantVelocityRace.java b/src/main/java/seng302/ConstantVelocityRace.java index 7439ce52..c4e1866c 100644 --- a/src/main/java/seng302/ConstantVelocityRace.java +++ b/src/main/java/seng302/ConstantVelocityRace.java @@ -1,6 +1,7 @@ package seng302; -import java.util.Collections; +import java.sql.Time; +import java.util.concurrent.TimeUnit; /** * Created by cbt24 on 6/03/17. @@ -12,26 +13,28 @@ public class ConstantVelocityRace extends Race { * @param marks array of RaceMarkers that the boats need to pass in order to finish the course. * @param timescale integer that the race is at timescale = 1000ms * @see seng302.Boat - * @see seng302.RaceMarker + * @see Leg */ - public ConstantVelocityRace(Boat[] startingBoats, RaceMarker[] marks, int timescale) { + public ConstantVelocityRace(BoatInRace[] startingBoats, Leg[] marks, int timescale) { super(startingBoats, marks, timescale); } - /** - * Generates the Race with respects to boat speed. - */ - protected void generateRace() { - for(Boat boat : startingBoats) { - for(int i = 0; i < marks.length; i++) { - RaceMarker raceMarker = marks[i]; - if (i != marks.length - 1) { - events.add(new Event(raceMarker, boat, (int) (raceMarker.getDistance() / boat.getVelocity()), marks[i + 1])); - } else { - events.add(new Event(raceMarker, boat, (int) (raceMarker.getDistance() / boat.getVelocity()))); - } - } - } - Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime()); + + protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { + + //distanceTravelled = velocity (nm p hr) * time taken to update loop + double distanceTravelled = boat.getVelocity() * TimeUnit.MILLISECONDS.toHours(millisecondsElapsed); + double totalDistanceTravelled = distanceTravelled + boat.getDistanceTravelledInLeg(); + + + + //Calculate new coordinates based on boat's heading for the leg, and distance traveled } + + + + + + + } diff --git a/src/main/java/seng302/Coordinate.java b/src/main/java/seng302/Coordinate.java index a2b19e33..889d0d0a 100644 --- a/src/main/java/seng302/Coordinate.java +++ b/src/main/java/seng302/Coordinate.java @@ -16,4 +16,5 @@ public class Coordinate { public int getY() { return y; } + } diff --git a/src/main/java/seng302/Event.java b/src/main/java/seng302/Event.java index d68dcea6..f195ce43 100644 --- a/src/main/java/seng302/Event.java +++ b/src/main/java/seng302/Event.java @@ -1,88 +1,79 @@ -package seng302; - -/** - * Created by fwy13 on 3/03/17. - */ -public class Event { - private RaceMarker raceMarker; - private Boat boat; - private int time; - private RaceMarker goalMarker; - - /** - * Initaliser for Racemaker without a goal node (such as the Finish line). - * @param raceMarker current Racemarker that has just been passed. - * @param boat Boat that has been passed. - * @param time time in seconds that the event occurred. - * @see seng302.RaceMarker - * @see seng302.Boat - */ - public Event(RaceMarker raceMarker, Boat boat, int time){ - this.raceMarker = raceMarker; - this.boat = boat; - this.time = time; - } - - /** - * Initaliser for Racemaker with a goal node. - * @param raceMarker current Racemarker that has just been passed. - * @param boat Boat that has been passed. - * @param time time in seconds that the event occurred. - * @param goalMarker the next marker that the boat is aiming for. - * @see seng302.RaceMarker - * @see seng302.Boat - */ - public Event(RaceMarker raceMarker, Boat boat, int time, RaceMarker goalMarker){ - this.raceMarker = raceMarker; - this.boat = boat; - this.time = time; - this.goalMarker = goalMarker; - } - - /** - * Calculates the bearing of the travel via map coordinates of the raceMarkers - * @return - */ - public double calculateHeading(){ - //to be changed to coordinates when used to match reality. - double thetaHat = Math.atan2((goalMarker.getLatitude() - raceMarker.getLatitude()), (goalMarker.getLongitude() - raceMarker.getLongitude())); - return thetaHat >= 0 ? Math.toDegrees(thetaHat): Math.toDegrees(thetaHat + 2 * Math.PI); - } - - /** - * - * @return the raceMarker that the boat has just passed. - */ - public RaceMarker getRaceMarker() { - return raceMarker; - } - - /** - * - * @return the boat that this event occured for. - */ - public Boat getBoat() { - return boat; - } - - /** - * - * @return the time the event occurred - */ - public int getTime(){ - return this.time; - } - - /** - * - * @return the event as a string in format {Boat Name} passed {RaceMarker Name} at {Time Event Occurred} seconds at heading {Heading}. - */ - public String toString() { - String stringToReturn = boat.getName() + " passed " + raceMarker.toString() + " at " + time + " seconds"; - if (goalMarker != null){ - stringToReturn += " at heading " + (int) calculateHeading(); - } - stringToReturn += "."; - return stringToReturn; - } -} +//package seng302; +// +///** +// * Created by fwy13 on 3/03/17. +// */ +//public class Event { +// private Leg leg; +// private Boat boat; +// private int time; +// private Leg goalMarker; +// +// /** +// * Initaliser for Racemaker without a goal node (such as the Finish line). +// * @param leg current Racemarker that has just been passed. +// * @param boat Boat that has been passed. +// * @param time time in seconds that the event occurred. +// * @see Leg +// * @see seng302.Boat +// */ +// public Event(Leg leg, Boat boat, int time){ +// this.leg = leg; +// this.boat = boat; +// this.time = time; +// } +// +// /** +// * Initaliser for Racemaker with a goal node. +// * @param leg current Racemarker that has just been passed. +// * @param boat Boat that has been passed. +// * @param time time in seconds that the event occurred. +// * @param goalMarker the next marker that the boat is aiming for. +// * @see Leg +// * @see seng302.Boat +// */ +// public Event(Leg leg, Boat boat, int time, Leg goalMarker){ +// this.leg = leg; +// this.boat = boat; +// this.time = time; +// this.goalMarker = goalMarker; +// } +// +// +// /** +// * +// * @return the leg that the boat has just passed. +// */ +// public Leg getLeg() { +// return leg; +// } +// +// /** +// * +// * @return the boat that this event occured for. +// */ +// public Boat getBoat() { +// return boat; +// } +// +// /** +// * +// * @return the time the event occurred +// */ +// public int getTime(){ +// return this.time; +// } +// +// /** +// * +// * @return the event as a string in format {Boat Name} passed {Leg Name} at {Time Event Occurred} seconds at heading {Heading}. +// */ +// public String toString() { +// String stringToReturn = boat.getName() + " passed " + leg.toString() + " at " + time + " seconds"; +// if (goalMarker != null){ +// stringToReturn += " at heading " + (int) calculateHeading(); +// } +// stringToReturn += "."; +// return stringToReturn; +// } +//} diff --git a/src/main/java/seng302/RaceMarker.java b/src/main/java/seng302/Leg.java similarity index 50% rename from src/main/java/seng302/RaceMarker.java rename to src/main/java/seng302/Leg.java index f38aeae4..cea378fe 100644 --- a/src/main/java/seng302/RaceMarker.java +++ b/src/main/java/seng302/Leg.java @@ -3,29 +3,31 @@ package seng302; /** * Created by cbt24 on 6/03/17. */ -public class RaceMarker { +public class Leg { private String name; private double distance; - private double latitude; - private double longitude; + + + private Coordinate startCoordinate; + private Coordinate endCoordinate; /** - * RaceMarker Initialiser - * @param name Name of the RaceMarker + * Leg Initialiser + * @param name Name of the Leg * @param distance Total Distance located in the Race * @param latitude Latitude of where it exists in the race (x coordinate) * @param longitude Longitude of where it exists in the race (y coordinate) */ - public RaceMarker(String name, double distance, double latitude, double longitude) { + public Leg(String name, double distance, double latitude, double longitude, Coordinate start, Coordinate end) { this.name = name; this.distance = distance; - this.latitude = latitude; - this.longitude = longitude; + this.startCoordinate = start; + this.endCoordinate = end; } /** * - * @return the name of the RaceMarker + * @return the name of the Leg */ public String getName() { return name; @@ -33,33 +35,34 @@ public class RaceMarker { /** * - * @return the total distance location in the race. + * @return the total distance of the leg. */ public double getDistance() { return distance; } + /** * - * @return the latitude that the RaceMarker exists at. + * @return the name of the Leg */ - public double getLatitude() { - return latitude; + public String toString() { + return name; } /** * - * @return the longitude that the RaceMarker exists at. + * @return the coordinate of the start of the leg ) */ - public double getLongitude() { - return longitude; + public Coordinate getStartCoordinate() { + return startCoordinate; } /** * - * @return the name of the RaceMarker + * @return the coordinate of the end of the leg */ - public String toString() { - return name; + public Coordinate getEndCoordinate() { + return endCoordinate; } } diff --git a/src/main/java/seng302/Race.java b/src/main/java/seng302/Race.java index 08ea0212..ef6a6c0d 100644 --- a/src/main/java/seng302/Race.java +++ b/src/main/java/seng302/Race.java @@ -8,13 +8,11 @@ import java.util.*; * Created by fwy13 on 3/03/17. */ public abstract class Race { - protected Boat[] startingBoats; - protected ArrayList finishingBoats = new ArrayList<>(); - protected RaceMarker[] marks; + protected BoatInRace[] startingBoats; + protected ArrayList finishingBoats = new ArrayList<>(); + protected Leg[] marks; protected int timescale = 1000; - protected LinkedList events = new LinkedList(); - protected Timer timer = new Timer(); private int SLEEP_TIME = 1000; //time in milliseconds to pause in a paced loop /** @@ -23,40 +21,46 @@ public abstract class Race { * @param marks Number of marks in order that the boats pass in order to complete the race. * @param timescale Number or milliseconds that = 1000ms. */ - public Race(Boat[] boats, RaceMarker[] marks, int timescale) { + public Race(BoatInRace[] boats, Leg[] marks, int timescale) { this.startingBoats = boats; this.marks = marks; this.timescale = timescale; - generateRace(); } - /** - * 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. - */ - public void simulateRace(){ + public void run() { + printStartingDetails(); + simulateRace(); + + } + + private void printStartingDetails() { //show the boats participating. System.out.println("Boats Participating:"); System.out.println("===================="); - for (int i = 0; i < startingBoats.length; i ++){ + 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"); } + } - System.out.println("\nRace Events:"); - System.out.println("============"); - //show all the events that happen in the race - long timeStarted = System.currentTimeMillis(); - long timeElapsed; + /** + * 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; while (finishingBoats.size() < startingBoats.length) { timeLoopStarted = System.currentTimeMillis(); - timeElapsed = System.currentTimeMillis() - timeStarted; - for (Boat boat : startingBoats) { - checkPosition(boat, timeElapsed); + totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted; + for (BoatInRace boat : startingBoats) { + updatePosition(boat, SLEEP_TIME); + checkPosition(boat); } try { timeLoopEnded = System.currentTimeMillis(); @@ -65,43 +69,11 @@ public abstract class Race { return; } } - - - - - for (Event event: events) { - timer.schedule(new TimerTask(){ - @Override - public void run(){ - System.out.println(event); - } - }, event.getTime() * timescale); - } - - /* - As the event readout is scheduled, the list of finishers must be - displayed afterwards, without the use of threading. - */ - timer.schedule(new TimerTask() { - @Override - public void run() { - System.out.println("\nFinish:"); - System.out.println("======="); - // Print the list of finishers with their placing and time - int place = 1; - for(Event event: events) { - if(event.getRaceMarker().getName().equals("Finish")) { - System.out.println(place + ". " + event.getBoat() + " (" + event.getTime() + "s)"); - place++; - } - } - } - }, (events.getLast().getTime() + 1) * timescale); } - private void checkPosition() { + protected void checkPosition(BoatInRace boat) { } @@ -110,6 +82,7 @@ public abstract class Race { * Is automatically called by the initialiser function, so that simulateRace() does not return an empty race. * @see Race#simulateRace() */ - protected abstract void generateRace(); + + protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed); } diff --git a/src/main/java/seng302/RandomisedRace.java b/src/main/java/seng302/RandomisedRace.java index 08bfa6b0..be72f727 100644 --- a/src/main/java/seng302/RandomisedRace.java +++ b/src/main/java/seng302/RandomisedRace.java @@ -1,38 +1,38 @@ -package seng302; - -import java.util.Collections; -import java.util.Random; - -/** - * Created by cbt24 on 6/03/17. - */ -public class RandomisedRace extends Race { - /** - * Randomise race, this is a race that the boats cross each mark randomly, and is a extension of Race. - * @param boats - * @param marks - * @param timescale - * @see seng302.Race - */ - public RandomisedRace(Boat[] boats, RaceMarker[] marks, int timescale) { - super(boats, marks, timescale); - } - - /** - * Generates the Race to be reported when Simulate Race in the Race class is called. - * @see Race#simulateRace() - */ - protected void generateRace() { - Random rand = new Random(); - for (Boat boat: this.boats){ - events.add(new Event(new RaceMarker("Start", 0, 0, 0), boat, 0)); - int prevTime = 0; - for (RaceMarker raceMarker: marks){ - int time = rand.nextInt(12) + 6; - events.add(new Event(raceMarker, boat, prevTime + time)); - prevTime += time; - } - } - Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime()); - } -} +//package seng302; +// +//import java.util.Collections; +//import java.util.Random; +// +///** +// * Created by cbt24 on 6/03/17. +// */ +//public class RandomisedRace extends Race { +// /** +// * Randomise race, this is a race that the boats cross each mark randomly, and is a extension of Race. +// * @param boats +// * @param marks +// * @param timescale +// * @see seng302.Race +// */ +// public RandomisedRace(Boat[] boats, Leg[] marks, int timescale) { +// super(boats, marks, timescale); +// } +// +// /** +// * Generates the Race to be reported when Simulate Race in the Race class is called. +// * @see Race#simulateRace() +// */ +// protected void generateRace() { +// Random rand = new Random(); +// for (Boat boat: this.boats){ +// events.add(new Event(new Leg("Start", 0, 0, 0), boat, 0)); +// int prevTime = 0; +// for (Leg raceMarker: marks){ +// int time = rand.nextInt(12) + 6; +// events.add(new Event(raceMarker, boat, prevTime + time)); +// prevTime += time; +// } +// } +// Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime()); +// } +//} diff --git a/src/main/resources/scenes/mainpane.fxml b/src/main/resources/scenes/mainpane.fxml index fd1a4081..c230b883 100644 --- a/src/main/resources/scenes/mainpane.fxml +++ b/src/main/resources/scenes/mainpane.fxml @@ -1,6 +1,6 @@ - +