Race events now display the boats heading and direction

- The boats velocity is being read from the config file
- The event text is now being printed when the leg starts #fix

Tags: #story[7] #implement
This commit is contained in:
Michael Rausch
2017-03-08 12:31:31 +13:00
parent 76faa53222
commit ab1445f1c2
8 changed files with 130 additions and 57 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"race-name": "AC35", "race-name": "AC35",
"time-scale": 1, "time-scale": 100,
"race-size": 2, "race-size": 2,
"teams": [ "teams": [
{"team-name": "Oracle Team USA", "velocity": 20.9}, {"team-name": "Oracle Team USA", "velocity": 20.9},
+25 -6
View File
@@ -5,6 +5,11 @@ import java.lang.reflect.Array;
public class App public class App
{ {
/**
* Builds a race object for the AC35 course
*
* @param numberOfBoats, the number of boats to include in the race
*/
public static Race createRace(int numberOfBoats) throws Exception{ public static Race createRace(int numberOfBoats) throws Exception{
Race race = new Race(); Race race = new Race();
@@ -12,6 +17,7 @@ public class App
FileParser fp = new FileParser("doc/examples/config.json"); FileParser fp = new FileParser("doc/examples/config.json");
ArrayList<String> boatNames = new ArrayList<>(); ArrayList<String> boatNames = new ArrayList<>();
ArrayList<Map<String, Object>> teams = fp.getTeams(); ArrayList<Map<String, Object>> teams = fp.getTeams();
for (Map<String, Object> team : teams) { for (Map<String, Object> team : teams) {
boatNames.add((String) team.get("team-name")); boatNames.add((String) team.get("team-name"));
} }
@@ -25,14 +31,18 @@ public class App
} }
for (int i = 0; i < numberOfBoats; i++) { for (int i = 0; i < numberOfBoats; i++) {
race.addBoat(new Boat(boatNames.get(i))); race.addBoat(new Boat(boatNames.get(i), (Double)(teams.get(i).get("velocity"))));
} }
race.addLeg(new Leg(035, 100, "Start")); race.addLeg(new Leg(035, 100, "Start"));
race.addLeg(new Leg(010, 300, "Marker 1")); race.addLeg(new Leg(010, 300, "Marker 1"));
race.addLeg(new Leg(350, 400, "Leeward Gate")); race.addLeg(new Leg(350, 400, "Leeward Gate"));
race.addLeg(new Leg(010, 400, "Windward Gate")); race.addLeg(new Leg(010, 400, "Windward Gate"));
race.addLeg(new Leg(010, 400, "Leeward Gate"));
Leg finishingLeg = new Leg(010, 400, "Leeward Gate");
finishingLeg.setFinishingLeg(true);
race.addLeg(finishingLeg);
return race; return race;
} }
@@ -43,21 +53,30 @@ public class App
try{ try{
race = createRace(2); race = createRace(2);
} }
catch (Exception e){ catch (Exception e){
System.out.println(e); System.out.println(e);
} }
// If race was created
if (race != null){ if (race != null){
race.displayStartingBoats();
System.out.println("\n\n");
System.out.println("######################");
System.out.println("# Live Race Updates ");
System.out.println("######################");
race.startRace(); race.startRace();
System.out.println("\n\n");
System.out.println("######################");
System.out.println("# Race Results ");
System.out.println("######################");
race.showRaceMarkerResults();
race.displayFinishingOrder(); race.displayFinishingOrder();
} }
else{ else{
System.out.println("e"); System.out.println("There was an error creating the race.");
} }
} }
} }
+18 -15
View File
@@ -1,35 +1,38 @@
package seng302; package seng302;
/* /**
Represents a boat in the race. * Represents a boat in the race.
*
@param teamName The name of the team sailing the boat * @param teamName The name of the team sailing the boat
* @param boatVelocity The speed of the boat in meters/second
*/ */
public class Boat public class Boat
{ {
// The name of the team, this is also the name of the boat
private String teamName = null; private String teamName; // The name of the team, this is also the name of the boat
private float velocity = 70; // please set this one to a reasonable num!!!!!, i set it just for testing ;) private double velocity; // In meters/second
public Boat(String teamName) { public Boat(String teamName) {
this.teamName = teamName; this.teamName = teamName;
this.velocity = 10; // Default velocity
} }
public Boat(String teamName, float boatVelocity) {
public Boat(String teamName, double boatVelocity) {
this.teamName = teamName; this.teamName = teamName;
this.velocity = boatVelocity; this.velocity = boatVelocity;
} }
/* /**
Returns the name of the team sailing the boat * Returns the name of the team sailing the boat
@returns The name of the team * @return The name of the team
*/ */
public String getTeamName(){ public String getTeamName(){
return this.teamName; return this.teamName;
} }
/* /**
Sets the name of the team sailing the boat * Sets the name of the team sailing the boat
@param teamName The name of the team * @param teamName The name of the team
*/ */
public void setTeamName(String teamName){ public void setTeamName(String teamName){
this.teamName = teamName; this.teamName = teamName;
@@ -47,7 +50,7 @@ public class Boat
* Gets velocity of the boat * Gets velocity of the boat
* @return a float number of the boat velocity * @return a float number of the boat velocity
*/ */
public float getVelocity() { public double getVelocity() {
return this.velocity; return this.velocity;
} }
} }
+23
View File
@@ -6,6 +6,10 @@ import java.util.Date;
/** /**
* Event class containing the time of specific event, related team/boat, and * Event class containing the time of specific event, related team/boat, and
* event location such as leg. * event location such as leg.
*
* @param eventTime, what time the event happens
* @param eventBoat, the boat that the event belongs to
* @param eventLeg, the leg the event happens on
*/ */
public class Event { public class Event {
@@ -74,4 +78,23 @@ public class Event {
public Leg getLeg() { public Leg getLeg() {
return this.leg; return this.leg;
} }
/**
* Call when the boat reaches the marker, this will tell the marker the order
* in which boats pass it
*/
public void addBoatToMarker(){
this.leg.addBoatToMarker(boat);
}
/**
* Get a string that contains the timestamp and course information for this event
* @return A string that contains the timestamp and course information for this event
*/
public String getEventString(){
String currentHeading = Integer.toString(this.getLeg().getHeading());
String velocityKnots = String.format("%1.2f", this.getBoat().getVelocity() * 1.943844492); // Convert meters/second to knots
return (this.getTimeString() + ", " + this.getBoat().getTeamName() + " passed " + this.getLeg().getMarkerLabel() + " going heading " + currentHeading + " at " + velocityKnots + " knots.");
}
} }
+7
View File
@@ -83,6 +83,13 @@ public class Leg {
return this.startingMarker.getName(); return this.startingMarker.getName();
} }
/*
Tell the marker that the boat has passed it
*/
public void addBoatToMarker(Boat boat){
this.startingMarker.addBoat(boat);
}
/* /*
Specify whether or not the race finishes on this leg Specify whether or not the race finishes on this leg
+12
View File
@@ -1,10 +1,14 @@
package seng302; package seng302;
import java.util.ArrayList;
class Marker{ class Marker{
private String name; private String name;
private ArrayList<Boat> boatOrder;
public Marker(String name){ public Marker(String name){
this.name = name; this.name = name;
this.boatOrder = new ArrayList<Boat>();
} }
public void setName(String name){ public void setName(String name){
@@ -14,4 +18,12 @@ class Marker{
public String getName(){ public String getName(){
return this.name; return this.name;
} }
public void addBoat(Boat boat){
this.boatOrder.add(boat);
}
public Boat[] getBoats(){
return this.boatOrder.toArray(new Boat[this.boatOrder.size()]);
}
} }
+43 -16
View File
@@ -1,12 +1,14 @@
package seng302; package seng302;
import java.util.*; import java.util.*;
import java.lang.reflect.Array;
import java.util.concurrent.TimeUnit;
public class Race { public class Race {
private ArrayList<Boat> boats; private ArrayList<Boat> boats; // The boats in the race
private ArrayList<Leg> legs; private ArrayList<Leg> legs; // The legs in the race
private PriorityQueue<Event> events; private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
private PriorityQueue<Event> events; // The events that occur in the race
private int numberOfBoats = 0; private int numberOfBoats = 0;
private long startTime = 0; private long startTime = 0;
private int timeScale = 1; private int timeScale = 1;
@@ -14,12 +16,15 @@ public class Race {
public Race() { public Race() {
this.boats = new ArrayList<Boat>(); this.boats = new ArrayList<Boat>();
this.legs = new ArrayList<Leg>(); this.legs = new ArrayList<Leg>();
// create a priority queue within custom Comparator to order events this.finishingOrder = new ArrayList<Boat>();
// create a priority queue with a custom Comparator to order events
this.events = new PriorityQueue<Event>(new Comparator<Event>() { this.events = new PriorityQueue<Event>(new Comparator<Event>() {
@Override @Override
public int compare(Event o1, Event o2) { public int compare(Event o1, Event o2) {
Long time1 = o1.getTime(); Long time1 = o1.getTime();
Long time2 = o2.getTime(); Long time2 = o2.getTime();
// order event asc. by time. if tie appears, then order team // order event asc. by time. if tie appears, then order team
// name alphabetically. // name alphabetically.
if (time1 != time2) { if (time1 != time2) {
@@ -60,7 +65,7 @@ public class Race {
@returns a list of boats @returns a list of boats
*/ */
public Boat[] getFinishedBoats() { public Boat[] getFinishedBoats() {
return getShuffledBoats(); return this.finishingOrder.toArray(new Boat[this.finishingOrder.size()]);
} }
/* /*
@@ -88,9 +93,10 @@ public class Race {
int numberOfBoats = this.getNumberOfBoats(); int numberOfBoats = this.getNumberOfBoats();
Boat[] boats = this.getFinishedBoats(); Boat[] boats = this.getFinishedBoats();
System.out.println("--- Finishing Order ---"); System.out.println("\n\n");
System.out.println("--- Finishing Order ---");
for (int i = 0; i < numberOfBoats; i++) { for (int i = 0; i < Array.getLength(boats); i++) {
System.out.println("#" + Integer.toString(i + 1) + " - " + boats[i].getTeamName()); System.out.println("#" + Integer.toString(i + 1) + " - " + boats[i].getTeamName());
} }
} }
@@ -98,11 +104,13 @@ public class Race {
/* /*
Prints the list of boats competing in the race Prints the list of boats competing in the race
*/ */
private void displayStartingBoats() { public void displayStartingBoats() {
int numberOfBoats = this.getNumberOfBoats(); int numberOfBoats = this.getNumberOfBoats();
Boat[] boats = this.getBoats(); Boat[] boats = this.getBoats();
System.out.println("--- Starting Boats ---"); System.out.println("######################");
System.out.println("# Competing Boats ");
System.out.println("######################");
for (int i = 0; i < numberOfBoats; i++) { for (int i = 0; i < numberOfBoats; i++) {
System.out.println(boats[i].getTeamName()); System.out.println(boats[i].getTeamName());
@@ -136,10 +144,10 @@ public class Race {
for (Boat boat : this.boats) { for (Boat boat : this.boats) {
long totalDistance = 0; long totalDistance = 0;
for (Leg leg : this.legs) { for (Leg leg : this.legs) {
totalDistance += leg.getDistance();
long time = (long) (1000 * totalDistance / (boat.getVelocity() * this.timeScale)); long time = (long) (1000 * totalDistance / (boat.getVelocity() * this.timeScale));
Event event = new Event(time, boat, leg); Event event = new Event(time, boat, leg);
events.add(event); events.add(event);
totalDistance += leg.getDistance();
} }
} }
} }
@@ -158,20 +166,34 @@ public class Race {
} }
/** /**
* Micheal, here is a demo function shows you how to iterate all events * Iterate over events in the race and print the
* event string for each event
*/ */
public void iterateEvents() { public void iterateEvents() {
// iterates all events. ends when no event in events. // iterates all events. ends when no event in events.
while (!events.isEmpty()) { while (!events.isEmpty()) {
Event peekEvent = events.peek(); Event peekEvent = events.peek();
long currentTime = System.currentTimeMillis() - this.startTime; long currentTime = System.currentTimeMillis() - this.startTime;
if (currentTime > peekEvent.getTime()) { if (currentTime > peekEvent.getTime()) {
// pull out the event // pull out the event
Event nextEvent = events.poll(); Event nextEvent = events.poll();
// I just simply print it out for testing // I just simply print it out for testing
System.out.println(nextEvent.getTimeString() + ", " + System.out.println(nextEvent.getEventString());
nextEvent.getBoat().getTeamName() + " passed " + nextEvent.addBoatToMarker();
nextEvent.getLeg().getMarkerLabel());
if (nextEvent.getLeg().getIsFinishingLeg()){
this.finishingOrder.add(nextEvent.getBoat());
}
}
// Wait for 100ms to slow down the while loop
try{
Thread.sleep(100);
}
catch(java.lang.InterruptedException e){
continue;
} }
} }
} }
@@ -185,9 +207,14 @@ public class Race {
generateEvents(); generateEvents();
this.startTime = System.currentTimeMillis(); this.startTime = System.currentTimeMillis();
iterateEvents(); iterateEvents();
}
/*
Print the order in which the boats passed each marker
*/
public void showRaceMarkerResults(){
for (Leg leg : this.legs) { for (Leg leg : this.legs) {
Boat[] boats = this.getShuffledBoats(); Boat[] boats = leg.getMarker().getBoats();
System.out.println("--- " + leg.getMarkerLabel() + " ---"); System.out.println("--- " + leg.getMarkerLabel() + " ---");
-18
View File
@@ -10,24 +10,6 @@ import java.lang.reflect.Array;
*/ */
public class RaceTest public class RaceTest
{ {
/*
Test that all boats that were added to the race also finish the race
*/
@Test
public void testFinishingBoats()
{
Boat boat1 = new Boat("Team 1");
Boat boat2 = new Boat("Team 2");
Boat boat3 = new Boat("Team 3");
Race race = new Race();
race.addBoat(boat1);
race.addBoat(boat2);
race.addBoat(boat3);
assertEquals(Array.getLength(race.getFinishedBoats()), 3);
}
/* /*
Test that all boats were added to the race Test that all boats were added to the race
*/ */