Rewriting code to work with the transplanted loop

- Event has been replaced by leg, which holds the start and end coordinates, and total distance needed to pass it.
- The boats coordinates will be recalculated at each run through of the loop
- Not worrying about randomised race for now.

#refactor
main
Erika Savell 9 years ago
parent 54d4ea2d03
commit b73fee2cb5

@ -46,13 +46,13 @@ public class App extends Application
new Boat("SoftBank Team Japan", 10.5) new Boat("SoftBank Team Japan", 10.5)
}; };
RaceMarker[] marks = { Leg[] marks = {
new RaceMarker("Start", 0, 0, 295), new Leg("Start", 0, 0, 295),
new RaceMarker("Mark", 360, 360, 250), new Leg("Mark", 360, 360, 250),
new RaceMarker("Leeward Gate", 965, 630, 790), new Leg("Leeward Gate", 965, 630, 790),
new RaceMarker("Windward Gate", 1865, 205, 0), new Leg("Windward Gate", 1865, 205, 0),
new RaceMarker("Leeward Gate", 2765, 630, 790), new Leg("Leeward Gate", 2765, 630, 790),
new RaceMarker("Finish", 3035, 475, 1015) new Leg("Finish", 3035, 475, 1015)
}; };
Race race = new ConstantVelocityRace(boats, marks, timescale); Race race = new ConstantVelocityRace(boats, marks, timescale);
@ -66,7 +66,7 @@ public class App extends Application
//load the first container //load the first container
try { try {
FXMLLoader loader = new FXMLLoader(); 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); mainContainer = (BorderPane) loader.load(in);
mainScene = new Scene(mainContainer, 800, 600); mainScene = new Scene(mainContainer, 800, 600);
primaryStage.setScene(mainScene); primaryStage.setScene(mainScene);

@ -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);
}
}

@ -1,6 +1,7 @@
package seng302; package seng302;
import java.util.Collections; import java.sql.Time;
import java.util.concurrent.TimeUnit;
/** /**
* Created by cbt24 on 6/03/17. * 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 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 * @param timescale integer that the race is at timescale = 1000ms
* @see seng302.Boat * @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); super(startingBoats, marks, timescale);
} }
/**
* Generates the Race with respects to boat speed. protected void updatePosition(BoatInRace boat, int millisecondsElapsed) {
*/
protected void generateRace() { //distanceTravelled = velocity (nm p hr) * time taken to update loop
for(Boat boat : startingBoats) { double distanceTravelled = boat.getVelocity() * TimeUnit.MILLISECONDS.toHours(millisecondsElapsed);
for(int i = 0; i < marks.length; i++) { double totalDistanceTravelled = distanceTravelled + boat.getDistanceTravelledInLeg();
RaceMarker raceMarker = marks[i];
if (i != marks.length - 1) {
events.add(new Event(raceMarker, boat, (int) (raceMarker.getDistance() / boat.getVelocity()), marks[i + 1]));
} else { //Calculate new coordinates based on boat's heading for the leg, and distance traveled
events.add(new Event(raceMarker, boat, (int) (raceMarker.getDistance() / boat.getVelocity())));
}
}
}
Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime());
} }
} }

@ -16,4 +16,5 @@ public class Coordinate {
public int getY() { public int getY() {
return y; return y;
} }
} }

@ -1,88 +1,79 @@
package seng302; //package seng302;
//
/** ///**
* Created by fwy13 on 3/03/17. // * Created by fwy13 on 3/03/17.
*/ // */
public class Event { //public class Event {
private RaceMarker raceMarker; // private Leg leg;
private Boat boat; // private Boat boat;
private int time; // private int time;
private RaceMarker goalMarker; // private Leg goalMarker;
//
/** // /**
* Initaliser for Racemaker without a goal node (such as the Finish line). // * Initaliser for Racemaker without a goal node (such as the Finish line).
* @param raceMarker current Racemarker that has just been passed. // * @param leg current Racemarker that has just been passed.
* @param boat Boat that has been passed. // * @param boat Boat that has been passed.
* @param time time in seconds that the event occurred. // * @param time time in seconds that the event occurred.
* @see seng302.RaceMarker // * @see Leg
* @see seng302.Boat // * @see seng302.Boat
*/ // */
public Event(RaceMarker raceMarker, Boat boat, int time){ // public Event(Leg leg, Boat boat, int time){
this.raceMarker = raceMarker; // this.leg = leg;
this.boat = boat; // this.boat = boat;
this.time = time; // this.time = time;
} // }
//
/** // /**
* Initaliser for Racemaker with a goal node. // * Initaliser for Racemaker with a goal node.
* @param raceMarker current Racemarker that has just been passed. // * @param leg current Racemarker that has just been passed.
* @param boat Boat that has been passed. // * @param boat Boat that has been passed.
* @param time time in seconds that the event occurred. // * @param time time in seconds that the event occurred.
* @param goalMarker the next marker that the boat is aiming for. // * @param goalMarker the next marker that the boat is aiming for.
* @see seng302.RaceMarker // * @see Leg
* @see seng302.Boat // * @see seng302.Boat
*/ // */
public Event(RaceMarker raceMarker, Boat boat, int time, RaceMarker goalMarker){ // public Event(Leg leg, Boat boat, int time, Leg goalMarker){
this.raceMarker = raceMarker; // this.leg = leg;
this.boat = boat; // this.boat = boat;
this.time = time; // this.time = time;
this.goalMarker = goalMarker; // this.goalMarker = goalMarker;
} // }
//
/** //
* Calculates the bearing of the travel via map coordinates of the raceMarkers // /**
* @return // *
*/ // * @return the leg that the boat has just passed.
public double calculateHeading(){ // */
//to be changed to coordinates when used to match reality. // public Leg getLeg() {
double thetaHat = Math.atan2((goalMarker.getLatitude() - raceMarker.getLatitude()), (goalMarker.getLongitude() - raceMarker.getLongitude())); // return leg;
return thetaHat >= 0 ? Math.toDegrees(thetaHat): Math.toDegrees(thetaHat + 2 * Math.PI); // }
} //
// /**
/** // *
* // * @return the boat that this event occured for.
* @return the raceMarker that the boat has just passed. // */
*/ // public Boat getBoat() {
public RaceMarker getRaceMarker() { // return boat;
return raceMarker; // }
} //
// /**
/** // *
* // * @return the time the event occurred
* @return the boat that this event occured for. // */
*/ // public int getTime(){
public Boat getBoat() { // return this.time;
return boat; // }
} //
// /**
/** // *
* // * @return the event as a string in format {Boat Name} passed {Leg Name} at {Time Event Occurred} seconds at heading {Heading}.
* @return the time the event occurred // */
*/ // public String toString() {
public int getTime(){ // String stringToReturn = boat.getName() + " passed " + leg.toString() + " at " + time + " seconds";
return this.time; // if (goalMarker != null){
} // stringToReturn += " at heading " + (int) calculateHeading();
// }
/** // stringToReturn += ".";
* // return stringToReturn;
* @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;
}
}

@ -3,29 +3,31 @@ package seng302;
/** /**
* Created by cbt24 on 6/03/17. * Created by cbt24 on 6/03/17.
*/ */
public class RaceMarker { public class Leg {
private String name; private String name;
private double distance; private double distance;
private double latitude;
private double longitude;
private Coordinate startCoordinate;
private Coordinate endCoordinate;
/** /**
* RaceMarker Initialiser * Leg Initialiser
* @param name Name of the RaceMarker * @param name Name of the Leg
* @param distance Total Distance located in the Race * @param distance Total Distance located in the Race
* @param latitude Latitude of where it exists in the race (x coordinate) * @param latitude Latitude of where it exists in the race (x coordinate)
* @param longitude Longitude of where it exists in the race (y 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.name = name;
this.distance = distance; this.distance = distance;
this.latitude = latitude; this.startCoordinate = start;
this.longitude = longitude; this.endCoordinate = end;
} }
/** /**
* *
* @return the name of the RaceMarker * @return the name of the Leg
*/ */
public String getName() { public String getName() {
return name; 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() { public double getDistance() {
return distance; return distance;
} }
/** /**
* *
* @return the latitude that the RaceMarker exists at. * @return the name of the Leg
*/ */
public double getLatitude() { public String toString() {
return latitude; return name;
} }
/** /**
* *
* @return the longitude that the RaceMarker exists at. * @return the coordinate of the start of the leg )
*/ */
public double getLongitude() { public Coordinate getStartCoordinate() {
return longitude; return startCoordinate;
} }
/** /**
* *
* @return the name of the RaceMarker * @return the coordinate of the end of the leg
*/ */
public String toString() { public Coordinate getEndCoordinate() {
return name; return endCoordinate;
} }
} }

@ -8,13 +8,11 @@ import java.util.*;
* Created by fwy13 on 3/03/17. * Created by fwy13 on 3/03/17.
*/ */
public abstract class Race { public abstract class Race {
protected Boat[] startingBoats; protected BoatInRace[] startingBoats;
protected ArrayList<Boat> finishingBoats = new ArrayList<>(); protected ArrayList<BoatInRace> finishingBoats = new ArrayList<>();
protected RaceMarker[] marks; protected Leg[] marks;
protected int timescale = 1000; protected int timescale = 1000;
protected LinkedList<Event> events = new LinkedList<Event>();
protected Timer timer = new Timer();
private int SLEEP_TIME = 1000; //time in milliseconds to pause in a paced loop 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 marks Number of marks in order that the boats pass in order to complete the race.
* @param timescale Number or milliseconds that = 1000ms. * @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.startingBoats = boats;
this.marks = marks; this.marks = marks;
this.timescale = timescale; this.timescale = timescale;
generateRace();
} }
/** public void run() {
* Starts the Race Simulation, playing the race start to finish with the timescale. printStartingDetails();
* This prints the boats participating, the order that the events occur in time order, and the respective information of the events. simulateRace();
*/
public void simulateRace(){ }
private void printStartingDetails() {
//show the boats participating. //show the boats participating.
System.out.println("Boats Participating:"); System.out.println("Boats Participating:");
System.out.println("===================="); 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(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 timeLoopStarted;
long timeLoopEnded; long timeLoopEnded;
while (finishingBoats.size() < startingBoats.length) { while (finishingBoats.size() < startingBoats.length) {
timeLoopStarted = System.currentTimeMillis(); timeLoopStarted = System.currentTimeMillis();
timeElapsed = System.currentTimeMillis() - timeStarted; totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
for (Boat boat : startingBoats) { for (BoatInRace boat : startingBoats) {
checkPosition(boat, timeElapsed); updatePosition(boat, SLEEP_TIME);
checkPosition(boat);
} }
try { try {
timeLoopEnded = System.currentTimeMillis(); timeLoopEnded = System.currentTimeMillis();
@ -65,43 +69,11 @@ public abstract class Race {
return; 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. * Is automatically called by the initialiser function, so that simulateRace() does not return an empty race.
* @see Race#simulateRace() * @see Race#simulateRace()
*/ */
protected abstract void generateRace();
protected abstract void updatePosition(BoatInRace boat, int millisecondsElapsed);
} }

@ -1,38 +1,38 @@
package seng302; //package seng302;
//
import java.util.Collections; //import java.util.Collections;
import java.util.Random; //import java.util.Random;
//
/** ///**
* Created by cbt24 on 6/03/17. // * Created by cbt24 on 6/03/17.
*/ // */
public class RandomisedRace extends Race { //public class RandomisedRace extends Race {
/** // /**
* Randomise race, this is a race that the boats cross each mark randomly, and is a extension of Race. // * Randomise race, this is a race that the boats cross each mark randomly, and is a extension of Race.
* @param boats // * @param boats
* @param marks // * @param marks
* @param timescale // * @param timescale
* @see seng302.Race // * @see seng302.Race
*/ // */
public RandomisedRace(Boat[] boats, RaceMarker[] marks, int timescale) { // public RandomisedRace(Boat[] boats, Leg[] marks, int timescale) {
super(boats, marks, timescale); // super(boats, marks, timescale);
} // }
//
/** // /**
* Generates the Race to be reported when Simulate Race in the Race class is called. // * Generates the Race to be reported when Simulate Race in the Race class is called.
* @see Race#simulateRace() // * @see Race#simulateRace()
*/ // */
protected void generateRace() { // protected void generateRace() {
Random rand = new Random(); // Random rand = new Random();
for (Boat boat: this.boats){ // for (Boat boat: this.boats){
events.add(new Event(new RaceMarker("Start", 0, 0, 0), boat, 0)); // events.add(new Event(new Leg("Start", 0, 0, 0), boat, 0));
int prevTime = 0; // int prevTime = 0;
for (RaceMarker raceMarker: marks){ // for (Leg raceMarker: marks){
int time = rand.nextInt(12) + 6; // int time = rand.nextInt(12) + 6;
events.add(new Event(raceMarker, boat, prevTime + time)); // events.add(new Event(raceMarker, boat, prevTime + time));
prevTime += time; // prevTime += time;
} // }
} // }
Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime()); // Collections.sort(events, (o1, o2) -> o1.getTime() - o2.getTime());
} // }
} //}

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>

Loading…
Cancel
Save