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

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

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

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

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

@ -8,13 +8,11 @@ import java.util.*;
* Created by fwy13 on 3/03/17.
*/
public abstract class Race {
protected Boat[] startingBoats;
protected ArrayList<Boat> finishingBoats = new ArrayList<>();
protected RaceMarker[] marks;
protected BoatInRace[] startingBoats;
protected ArrayList<BoatInRace> finishingBoats = new ArrayList<>();
protected Leg[] marks;
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
/**
@ -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);
}

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

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

Loading…
Cancel
Save