mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Removed unneeded files, also fixed heading calculation
Tags #story[829]
This commit is contained in:
@@ -6,7 +6,6 @@ import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import seng302.server.ServerThread;
|
||||
import seng302.server.simulator.Simulator;
|
||||
|
||||
public class App extends Application
|
||||
{
|
||||
@@ -15,13 +14,9 @@ public class App extends Application
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
||||
primaryStage.setTitle("RaceVision");
|
||||
primaryStage.setScene(new Scene(root));
|
||||
|
||||
// primaryStage.show();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new ServerThread("Racevision Test Server");
|
||||
//new Thread(new Simulator(1000)).run();
|
||||
//launch(args);
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.paint.Color;
|
||||
import seng302.models.Boat;
|
||||
import seng302.models.Course;
|
||||
import seng302.models.Race;
|
||||
import seng302.models.mark.Mark;
|
||||
import seng302.models.mark.MarkType;
|
||||
import seng302.models.parsers.ConfigParser;
|
||||
import seng302.models.parsers.CourseParser;
|
||||
import seng302.models.parsers.TeamsParser;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Controller for main window for RaceVision
|
||||
* Created by Kusal on 3/22/2017.
|
||||
*/
|
||||
public class Controller implements Initializable {
|
||||
|
||||
private static final int MARKER_WIDTH = 10;
|
||||
private static final int MARKER_HEIGHT = 10;
|
||||
private static final double ORIGINAL_LAT = 32.321504;
|
||||
private static final double ORIGINAL_LON = -64.857063;
|
||||
|
||||
|
||||
@FXML
|
||||
private Canvas courseCanvas;
|
||||
|
||||
@FXML
|
||||
private Group boatGroup;
|
||||
|
||||
@FXML
|
||||
private Button playPauseButton;
|
||||
|
||||
|
||||
private Course thisCourse;
|
||||
private ArrayList<Boat> startingBoats;
|
||||
private int raceDuration;
|
||||
private Race race;
|
||||
private boolean raceRunning = false;
|
||||
|
||||
private CourseParser cp;
|
||||
private TeamsParser tp;
|
||||
private ConfigParser cop;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
cp = new CourseParser("/config/course.xml");
|
||||
tp = new TeamsParser("/config/teams.xml");
|
||||
cop = new ConfigParser("/config/config.xml");
|
||||
|
||||
thisCourse = new Course(cp.getCourse());
|
||||
startingBoats = tp.getBoats();
|
||||
race = new Race(thisCourse.getMarks(), startingBoats, cop.getTimeScale(), this);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises a race on the screen after it has been loaded
|
||||
*/
|
||||
private void init() {
|
||||
initMap();
|
||||
initBoats();
|
||||
playPauseButton.setDisable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the map by drawing it onto courseCanvas.
|
||||
*/
|
||||
private void initMap() {
|
||||
//Create the boundary of the course displayed on the map
|
||||
drawCourse();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw the markers and gates onto the courseCanvas.
|
||||
*/
|
||||
private void drawCourse() {
|
||||
GraphicsContext gc = courseCanvas.getGraphicsContext2D();
|
||||
gc.save();
|
||||
|
||||
for(Mark rp : thisCourse.getMarks()) {
|
||||
if (rp.getMarkType().equals(MarkType.SINGLE_MARK)) {
|
||||
gc.setFill(Color.GRAY);
|
||||
gc.fillOval(convertLongToX(rp.getLongitude()), convertLatToY(rp.getLatitude()), MARKER_WIDTH, MARKER_HEIGHT);
|
||||
} else if (rp.getMarkType().equals(MarkType.GATE_MARK)) {
|
||||
gc.setFill(Color.GRAY);
|
||||
gc.fillOval(convertLongToX(rp.getLongitude()), convertLatToY(rp.getLatitude()), MARKER_WIDTH, MARKER_HEIGHT);
|
||||
// gc.fillOval(((OpenGate) rp).getDrawX2(), ((OpenGate) rp).getDrawY2(), MARKER_WIDTH, MARKER_HEIGHT);
|
||||
|
||||
gc.setLineWidth(2);
|
||||
gc.setFill(Color.GREEN);
|
||||
gc.setStroke(Color.GREEN);
|
||||
}
|
||||
gc.fillOval(convertLongToX(rp.getLongitude()), convertLatToY(rp.getLatitude()), MARKER_WIDTH, MARKER_HEIGHT);
|
||||
// gc.fillOval(((ClosedGate) rp).getDrawX2(), ((ClosedGate) rp).getDrawY2(), MARKER_WIDTH, MARKER_HEIGHT);
|
||||
// gc.strokeLine(convertLongToX(rp.getLongitude()) + 5, convertLatToY(rp.getLatitude()) + 5, ((ClosedGate) rp).getDrawX2() + 5, ((ClosedGate) rp).getDrawY2() + 5);
|
||||
}
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Places boats at starting line
|
||||
*/
|
||||
private void initBoats() {
|
||||
|
||||
// int startingX = (convertLongToX(thisCourse.getMarks().get(0).getLongitude())).intValue();
|
||||
// int startingY = (convertLatToY(thisCourse.getMarks().get(0).getLongitude())).intValue();
|
||||
|
||||
int startingX = 50;
|
||||
int startingY = 100;
|
||||
|
||||
for(Boat boat : startingBoats) {
|
||||
boat.moveBoatTo(startingX, startingY);
|
||||
boatGroup.getChildren().add(boat.getBoatObject());
|
||||
boat.setCurrentLeg(race.getRaceLegs().get(0));
|
||||
boat.setHeading(race.getRaceLegs().get(0).getHeading());
|
||||
boat.setLegDistance(0d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts and stops the race depending on whether or not it is already running
|
||||
*/
|
||||
public void playPause() {
|
||||
if (!raceRunning) {
|
||||
play();
|
||||
} else {
|
||||
pause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the race and updates the play / pause button
|
||||
*/
|
||||
private void play() {
|
||||
race.run();
|
||||
raceRunning = true;
|
||||
playPauseButton.setText("Pause");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses the race and updates the play / pause button
|
||||
*/
|
||||
private void pause() {
|
||||
race.pause();
|
||||
raceRunning = false;
|
||||
playPauseButton.setText("Play");
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Double convertLongToX(Double lon) {
|
||||
return (lon - ORIGINAL_LON) * thisCourse.getDistanceScaleFactor();
|
||||
}
|
||||
|
||||
private Double convertLatToY(Double lat) {
|
||||
return (ORIGINAL_LAT - lat) * thisCourse.getDistanceScaleFactor();
|
||||
}
|
||||
|
||||
public Button getPlayPauseButton() {
|
||||
return playPauseButton;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
/**
|
||||
* Represents a boat in the race.
|
||||
*/
|
||||
public class Boat {
|
||||
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
private static final double VELOCITY_WAKE_RATIO = 1/2d; //Ratio for deciding how long the wake will be wrt velocity
|
||||
|
||||
private String teamName; // The name of the team, this is also the name of the boat
|
||||
private Double velocity; // In meters/second
|
||||
private Double lat; // Boats position
|
||||
private Double lon; // -
|
||||
private Double legDistance;
|
||||
private Color color;
|
||||
private Leg currentLeg;
|
||||
private Double heading;
|
||||
private String shortName;
|
||||
|
||||
private Polygon boatObject = new Polygon();
|
||||
|
||||
public Boat(String teamName) {
|
||||
this.teamName = teamName;
|
||||
this.velocity = 10d; // Default velocity
|
||||
this.lat = 0.0;
|
||||
this.lon = 0.0;
|
||||
this.legDistance = 0.0;
|
||||
this.shortName = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a boat in the race.
|
||||
*
|
||||
* @param teamName The name of the team sailing the boat
|
||||
* @param boatVelocity The speed of the boat in meters/second
|
||||
* @param shortName A shorter version of the teams name
|
||||
*/
|
||||
public Boat(String teamName, double boatVelocity, String shortName) {
|
||||
this.teamName = teamName;
|
||||
this.velocity = boatVelocity;
|
||||
this.legDistance = 0.0;
|
||||
this.color = Colors.getColor();
|
||||
this.shortName = shortName;
|
||||
this.boatObject.getPoints().addAll(BOAT_WIDTH /2,0.0,
|
||||
BOAT_WIDTH, BOAT_HEIGHT,
|
||||
0.0, BOAT_HEIGHT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the team sailing the boat
|
||||
*
|
||||
* @return The name of the team
|
||||
*/
|
||||
public String getTeamName() {
|
||||
return this.teamName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the team sailing the boat
|
||||
*
|
||||
* @param teamName The name of the team
|
||||
*/
|
||||
public void setTeamName(String teamName) {
|
||||
this.teamName = teamName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets velocity of the boat
|
||||
*
|
||||
* @return a float number of the boat velocity
|
||||
*/
|
||||
public double getVelocity() {
|
||||
return this.velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets velocity of the boat
|
||||
*
|
||||
* @param velocity The velocity of boat
|
||||
*/
|
||||
public void setVelocity(double velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the boats location
|
||||
*
|
||||
* @param lat, the boats latitude
|
||||
* @param lon, the boats longitude
|
||||
*/
|
||||
public void setLocation(double lat, double lon) {
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public Double getLegDistance() {
|
||||
return legDistance;
|
||||
}
|
||||
|
||||
public void setLegDistance(double legDistance){
|
||||
this.legDistance = legDistance;
|
||||
}
|
||||
|
||||
public double getLatitude(){
|
||||
return this.lat;
|
||||
}
|
||||
|
||||
public double getLongitude(){
|
||||
return this.lon;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public double getSpeedInKnots(){
|
||||
return Math.round((this.velocity * 1.94384) * 100d) / 100d;
|
||||
}
|
||||
|
||||
public Leg getCurrentLeg() {
|
||||
return currentLeg;
|
||||
}
|
||||
|
||||
public void setCurrentLeg(Leg currentLeg) {
|
||||
this.currentLeg = currentLeg;
|
||||
}
|
||||
|
||||
public void setHeading(double heading){
|
||||
this.heading = heading;
|
||||
}
|
||||
|
||||
public double getHeading(){
|
||||
return this.heading;
|
||||
}
|
||||
|
||||
public String getShortName(){
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves the boat and its children annotations from its current coordinates by specified amounts.
|
||||
* @param x The amount to move the X coordinate by
|
||||
* @param y The amount to move the Y coordinate by
|
||||
*/
|
||||
void moveBoatBy(Double x, Double y) {
|
||||
boatObject.setLayoutX(boatObject.getLayoutX() + x);
|
||||
boatObject.setLayoutY(boatObject.getLayoutY() + y);
|
||||
boatObject.relocate(boatObject.getLayoutX(), boatObject.getLayoutY());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the boat and its children annotations to coordinates specified
|
||||
* @param x The X coordinate to move the boat to
|
||||
* @param y The Y coordinate to move the boat to
|
||||
*/
|
||||
public void moveBoatTo(int x, int y) {
|
||||
boatObject.setLayoutX(x);
|
||||
boatObject.setLayoutY(y);
|
||||
boatObject.relocate(boatObject.getLayoutX(), boatObject.getLayoutY());
|
||||
|
||||
}
|
||||
|
||||
public Polygon getBoatObject() {
|
||||
return boatObject;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* Created by ryan_ on 16/03/2017.
|
||||
*/
|
||||
public enum Colors {
|
||||
RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE;
|
||||
|
||||
static Integer index = 0;
|
||||
|
||||
public static Color getColor() {
|
||||
index++;
|
||||
if (index > 6) {
|
||||
index = 1;
|
||||
}
|
||||
return Color.valueOf(values()[index-1].toString());
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
/**
|
||||
* Created by wmu16 on 4/8/17.
|
||||
*/
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.util.Pair;
|
||||
import seng302.models.mark.Mark;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Class for describing the course information for the canvas
|
||||
* Created by wmu16 on 22/03/17.
|
||||
*/
|
||||
public class Course {
|
||||
|
||||
private ArrayList<Leg> Legs;
|
||||
private ArrayList<Mark> marks;
|
||||
public static final Integer SCALE = 160000;
|
||||
|
||||
|
||||
public Course(ArrayList<Mark> marks) {
|
||||
this.marks = marks;
|
||||
this.Legs = makeLegs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the race legs out of all the marker marks for the course
|
||||
* @return ArrayList of Legs
|
||||
*/
|
||||
private ArrayList<Leg> makeLegs() {
|
||||
ArrayList<Leg> Legs = new ArrayList<>();
|
||||
for (int i = 0; i < marks.size()-1; i++) {
|
||||
Legs.add(new Leg(marks.get(i), marks.get(i+1)));
|
||||
}
|
||||
return Legs;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<Mark> getMarks() {
|
||||
return marks;
|
||||
}
|
||||
|
||||
public double getDistanceScaleFactor() {
|
||||
return SCALE;
|
||||
}
|
||||
|
||||
public ArrayList<Leg> getLegs() {
|
||||
return Legs;
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
|
||||
import seng302.models.mark.Mark;
|
||||
|
||||
/**
|
||||
* Class for defining the leg of a race between two markers
|
||||
* Created by cir27 on 3/03/17.
|
||||
*/
|
||||
public class Leg {
|
||||
|
||||
private final double ORIGIN_LAT = 32.320504;
|
||||
private final double ORIGIN_LON = -64.857063;
|
||||
private final double SCALE = 16000;
|
||||
|
||||
private Double distance;
|
||||
private Double heading;
|
||||
private Mark end;
|
||||
private Mark start;
|
||||
|
||||
Leg(Mark start, Mark end) {
|
||||
this.distance = calculateMarkerDistance(start, end);
|
||||
this.heading = angleFromCoordinate(start, end);
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the euclidian distance between two markers on the canvas using xy coordinates
|
||||
*
|
||||
* @param geoPointOne first geographical point
|
||||
* @param geoPointTwo second geographical point
|
||||
* @return the distance between two points in meters
|
||||
*/
|
||||
private Double calculateMarkerDistance(Mark geoPointOne, Mark geoPointTwo) {
|
||||
|
||||
double earth_radius = 6378.137;
|
||||
double dLat = geoPointTwo.getLatitude() * Math.PI / 180 - geoPointOne.getLatitude() * Math.PI / 180;
|
||||
double dLon = geoPointTwo.getLongitude() * Math.PI / 180 - geoPointOne.getLongitude() * Math.PI / 180;
|
||||
|
||||
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(geoPointOne.getLatitude() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
|
||||
|
||||
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
double d = earth_radius * c;
|
||||
|
||||
return d * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the angle between to angular co-ordinates on a sphere.
|
||||
*
|
||||
* @param geoPointOne first geographical location
|
||||
* @param geoPointTwo second geographical location
|
||||
* @return the angle from point one to point two
|
||||
*/
|
||||
private Double angleFromCoordinate(Mark geoPointOne, Mark geoPointTwo) {
|
||||
|
||||
if (geoPointTwo == null){
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double x1 = (geoPointOne.getLongitude() - ORIGIN_LON) * SCALE;
|
||||
double y1 = (ORIGIN_LAT - geoPointOne.getLatitude()) * SCALE;
|
||||
double x2 = (geoPointTwo.getLongitude() - ORIGIN_LON) * SCALE;
|
||||
double y2 = (ORIGIN_LAT - geoPointTwo.getLatitude()) * SCALE;
|
||||
|
||||
double headingRadians = Math.atan2(y2-y1, x2-x1);
|
||||
|
||||
if (headingRadians < 0){
|
||||
headingRadians += 2 * Math.PI;
|
||||
}
|
||||
|
||||
// Convert back to degrees, and flip 180 degrees
|
||||
// return ((headingRadians) * 180) / Math.PI;
|
||||
return (Math.toDegrees(headingRadians) + 90) % 360;
|
||||
|
||||
}
|
||||
|
||||
Double getDistance()
|
||||
{
|
||||
return this.distance;
|
||||
}
|
||||
|
||||
Mark getEnd()
|
||||
{
|
||||
return this.end;
|
||||
}
|
||||
|
||||
public Mark getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public Double getHeading()
|
||||
{
|
||||
return this.heading;
|
||||
}
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
package seng302.models;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import seng302.controllers.Controller;
|
||||
import seng302.models.mark.Mark;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Race class containing the boats and legs in the race
|
||||
* Created by mra106 on 8/3/2017.
|
||||
*/
|
||||
public class Race extends Thread {
|
||||
|
||||
private static final double UPDATE_TIME = 0.016666; // 1 / 60 ie 60fps
|
||||
|
||||
|
||||
private ArrayList<Boat> boats; // The boats in the race
|
||||
private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
|
||||
private List<Mark> markers; // Marks in the race
|
||||
private List<Leg> raceLegs;
|
||||
private boolean raceFinished = false; // Race is finished
|
||||
private int raceTime = -2; // Current time in the race
|
||||
private Double timeScale = null;
|
||||
private boolean raceStarted = false;
|
||||
private Controller controller;
|
||||
|
||||
/**
|
||||
* Race class containing the boats and legs in the race
|
||||
*/
|
||||
public Race(List<Mark> markers, ArrayList<Boat> boats, Double timescale, Controller controller) {
|
||||
this.boats = boats;
|
||||
this.markers = markers;
|
||||
this.raceLegs = makeRaceLegs();
|
||||
this.controller = controller;
|
||||
|
||||
this.timeScale = timescale;
|
||||
this.finishingOrder = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes the race legs out of all the marker points for the course
|
||||
* @return ArrayList of raceLegs
|
||||
*/
|
||||
private ArrayList<Leg> makeRaceLegs() {
|
||||
ArrayList<Leg> raceLegs = new ArrayList<>();
|
||||
for (int i=0; i < markers.size()-1; i++) {
|
||||
raceLegs.add(new Leg(markers.get(i), markers.get(i+1)));
|
||||
}
|
||||
return raceLegs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A timer that is called every frame to call the action of moving the boats
|
||||
*/
|
||||
private AnimationTimer at = new AnimationTimer() {
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
|
||||
//Updating Boat positions
|
||||
if(finishingOrder.size() != boats.size()) {
|
||||
// update the time
|
||||
boats.stream().filter(boat -> !finishingOrder.contains(boat)).forEach(boat -> {
|
||||
updateBoatPosition(boat);
|
||||
});
|
||||
} else {
|
||||
at.stop();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Begins the race simulation
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
if (!raceStarted) {
|
||||
// controller.getPlayPauseButton().setDisable(true);
|
||||
at.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves the coordinates of the boats.
|
||||
* @param boat The boat to update the position of
|
||||
*/
|
||||
private void updateBoatPosition(Boat boat) {
|
||||
Double thisHeading = boat.getHeading();
|
||||
// TODO: 4/8/17 wmu16 - Add a distance scale factor from lat long distance in Metres to xy equivalent
|
||||
Double hypMove = boat.getVelocity() * UPDATE_TIME * timeScale; //* distanceScaleFactor
|
||||
boat.setLegDistance(boat.getLegDistance() + hypMove);
|
||||
moveBoat(boat, thisHeading, hypMove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a boat along coordinates by breaking down the distance moved along the hypotenuse into x and y components
|
||||
* @param boat The Boat to move
|
||||
* @param heading The heading the boat is moving at
|
||||
* @param hypMove The distance moved along the hypotenuse (absolute distance)
|
||||
*/
|
||||
private void moveBoat(Boat boat, Double heading, Double hypMove) {
|
||||
//If the boat has not yet passed the marker at the end of the leg increase its (x,y) as per normal
|
||||
// TODO: 4/8/17 wmu16 - Initialising boat positions and legs and headings etc.
|
||||
if(boat.getLegDistance() <= boat.getCurrentLeg().getDistance()) {
|
||||
Double xMove = hypMove * Math.sin(Math.toRadians(heading));
|
||||
Double yMove = - hypMove * Math.cos(Math.toRadians(heading));
|
||||
boat.moveBoatBy(xMove, yMove);
|
||||
|
||||
//If the boat has finished...
|
||||
} else if (getNextRaceLeg(boat.getCurrentLeg()).equals(boat.getCurrentLeg())) {
|
||||
finishingOrder.add(boat);
|
||||
//Otherwise apply the overflow distance of the leg to the next leg
|
||||
} else {
|
||||
Double overflowDistance = boat.getLegDistance() - boat.getCurrentLeg().getDistance();
|
||||
boat.setCurrentLeg(getNextRaceLeg(boat.getCurrentLeg()));
|
||||
boat.setHeading(boat.getCurrentLeg().getHeading());
|
||||
boat.setLegDistance(overflowDistance);
|
||||
moveBoat(boat, boat.getHeading(), overflowDistance);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next leg in the race
|
||||
* @param currentRaceLeg The leg that you are currently on
|
||||
* @return The next race leg or the same race leg if it has reached the end
|
||||
*/
|
||||
private Leg getNextRaceLeg(Leg currentRaceLeg) {
|
||||
Leg nextRaceLeg = currentRaceLeg;
|
||||
for(int i = 0; i< raceLegs.size() - 1; i++) {
|
||||
if (raceLegs.get(i).equals(currentRaceLeg)) {
|
||||
nextRaceLeg = raceLegs.get(i + 1);
|
||||
}
|
||||
}
|
||||
return nextRaceLeg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of boats in the order that they
|
||||
* finished the race (position 0 is first place)
|
||||
*
|
||||
* @return a list of boats
|
||||
*/
|
||||
public Boat[] getFinishedBoats() {
|
||||
return this.finishingOrder.toArray(new Boat[this.finishingOrder.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of boats in the race
|
||||
*
|
||||
* @return a list of the boats competing in the race
|
||||
*/
|
||||
public Boat[] getBoats() {
|
||||
return boats.toArray(new Boat[boats.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a race and generates all events for the race.
|
||||
*/
|
||||
public void startRace() {
|
||||
// record start time.
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
at.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of marks in the markers
|
||||
* @return
|
||||
*/
|
||||
public List<Mark> getMarkers() {
|
||||
return markers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a boat as finished
|
||||
* @param boat The boat that has finished the race
|
||||
*/
|
||||
public void setBoatFinished(Boat boat){
|
||||
this.finishingOrder.add(boat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race as finished
|
||||
*/
|
||||
public void setRaceFinished(){
|
||||
this.raceFinished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the race is finished
|
||||
* @return true if the race is finished
|
||||
*/
|
||||
public boolean isRaceFinished(){
|
||||
return this.raceFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race time
|
||||
* @param raceTime the race time in seconds
|
||||
*/
|
||||
public void setRaceTime(int raceTime){
|
||||
this.raceTime = raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the race time
|
||||
* @return the race time in seconds
|
||||
*/
|
||||
public int getRaceTime(){
|
||||
return this.raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the race time by one second
|
||||
*/
|
||||
public void incrementRaceTime() {
|
||||
this.raceTime += this.timeScale;
|
||||
}
|
||||
|
||||
public List<Leg> getRaceLegs() {
|
||||
return raceLegs;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package seng302.models.mark;
|
||||
|
||||
/**
|
||||
* To represent a gate mark which contains two single marks.
|
||||
* Created by ptg19 on 16/03/17.
|
||||
* Modified by Haoming Yin (hyi25) on 17/3/2017.
|
||||
*/
|
||||
public class GateMark extends Mark {
|
||||
|
||||
private SingleMark singleMark1;
|
||||
private SingleMark singleMark2;
|
||||
|
||||
/**
|
||||
* Create an instance of Gate Mark which contains two single mark
|
||||
* @param name the name of the gate mark
|
||||
* @param singleMark1 one single mark inside of the gate mark
|
||||
* @param singleMark2 the second mark inside of the gate mark
|
||||
*/
|
||||
public GateMark(String name, SingleMark singleMark1, SingleMark singleMark2, double latitude, double longitude) {
|
||||
super(name, MarkType.GATE_MARK, latitude, longitude);
|
||||
this.singleMark1 = singleMark1;
|
||||
this.singleMark2 = singleMark2;
|
||||
}
|
||||
|
||||
public SingleMark getSingleMark1() {
|
||||
return singleMark1;
|
||||
}
|
||||
|
||||
public void setSingleMark1(SingleMark singleMark1) {
|
||||
this.singleMark1 = singleMark1;
|
||||
}
|
||||
|
||||
public SingleMark getSingleMark2() {
|
||||
return singleMark2;
|
||||
}
|
||||
|
||||
public void setSingleMark2(SingleMark singleMark2) {
|
||||
this.singleMark2 = singleMark2;
|
||||
}
|
||||
|
||||
public double getLatitude(){
|
||||
//return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2;
|
||||
return (this.getSingleMark1().getLatitude());
|
||||
}
|
||||
|
||||
public double getLongitude(){
|
||||
//return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2;
|
||||
return (this.getSingleMark1().getLongitude());
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package seng302.models.mark;
|
||||
|
||||
/**
|
||||
* An abstract class to represent general marks
|
||||
* Created by Haoming Yin (hyi25) on 17/3/17.
|
||||
*/
|
||||
public abstract class Mark {
|
||||
|
||||
private String name;
|
||||
private MarkType markType;
|
||||
private double latitude;
|
||||
private double longitude;
|
||||
|
||||
/**
|
||||
* Create a mark instance by passing its name and type
|
||||
* @param name the name of the mark
|
||||
* @param markType the type of mark. either GATE_MARK or SINGLE_MARK.
|
||||
*/
|
||||
public Mark (String name, MarkType markType) {
|
||||
this.name = name;
|
||||
this.markType = markType;
|
||||
}
|
||||
|
||||
public Mark(String name, MarkType markType, double latitude, double longitude) {
|
||||
this.name = name;
|
||||
this.markType = markType;
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public MarkType getMarkType() {
|
||||
return markType;
|
||||
}
|
||||
|
||||
public void setMarkType(MarkType markType) {
|
||||
this.markType = markType;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package seng302.models.mark;
|
||||
|
||||
/**
|
||||
* To represent two types of mark
|
||||
* Created by Haoming Yin (hyi25) on 17/3/17.
|
||||
*/
|
||||
|
||||
|
||||
public enum MarkType {
|
||||
|
||||
UNKNOWN(0),
|
||||
ROUNDING_MARK(1),
|
||||
GATE_MARK(2),
|
||||
// above mark types are from AC35 spec.
|
||||
|
||||
// more specific types for gate mark
|
||||
WINDWARD(201),
|
||||
LEEWARD(202),
|
||||
START(203),
|
||||
FINISH(204),
|
||||
|
||||
// single_mark is from old team-13 code base, for compatibility, it has not
|
||||
// been removed yet
|
||||
SINGLE_MARK(5);
|
||||
|
||||
private int type;
|
||||
|
||||
MarkType(int markType) {
|
||||
this.type = markType;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package seng302.models.mark;
|
||||
|
||||
/**
|
||||
* Represents the marker as a single mark
|
||||
*
|
||||
* Created by Haoming Yin (hyi25) on 17/3/2017
|
||||
*/
|
||||
public class SingleMark extends Mark {
|
||||
private double lat;
|
||||
private double lon;
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a marker
|
||||
*
|
||||
* @param name, the name of the marker*
|
||||
* @param lat, the latitude of the marker
|
||||
* @param lon, the longitude of the marker
|
||||
*/
|
||||
public SingleMark(String name, double lat, double lon) {
|
||||
super(name, MarkType.SINGLE_MARK);
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the marker at the beginning of a leg
|
||||
*
|
||||
* @param name, the name of the marker
|
||||
*/
|
||||
public SingleMark(String name) {
|
||||
super(name, MarkType.SINGLE_MARK);
|
||||
this.lat = 0;
|
||||
this.lon = 0;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return this.lat;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return this.lon;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import java.util.DoubleSummaryStatistics;
|
||||
|
||||
public class ConfigParser extends FileParser {
|
||||
|
||||
private Document doc;
|
||||
|
||||
public ConfigParser(String path) {
|
||||
super(path);
|
||||
this.doc = this.parseFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets wind direction from config file.
|
||||
*
|
||||
* @return a double type degree, or 0 if no value or invalid value is found
|
||||
*/
|
||||
public double getWindDirection() {
|
||||
return getDoubleByTagName("wind-direction", 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a non negative time scale for the race
|
||||
*
|
||||
* @return a double type scale, or 0 if no scale or invalid scale is found
|
||||
*/
|
||||
public double getTimeScale() {
|
||||
return getDoubleByTagName("time-scale", 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a double type number by given tag name found in xml file
|
||||
*
|
||||
* @param tagName a string of tag name
|
||||
* @param defaultVal value returned if no value or invalid value is found
|
||||
* @return value found
|
||||
*/
|
||||
public double getDoubleByTagName(String tagName, double defaultVal) {
|
||||
double val = defaultVal;
|
||||
try {
|
||||
Node node = this.doc.getElementsByTagName(tagName).item(0);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
val = Double.valueOf(element.getTextContent());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string by given tag name found in xml file
|
||||
*
|
||||
* @param tagName a string of tag name
|
||||
* @param defaultVal a string returned if no value or invalid value is found
|
||||
* @return string found
|
||||
*/
|
||||
public String getStringByTagName(String tagName, String defaultVal) {
|
||||
String string = defaultVal;
|
||||
try {
|
||||
Node node = this.doc.getElementsByTagName(tagName).item(0);
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
string = element.getTextContent();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} finally {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import seng302.models.mark.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* parse a course xml file
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
*/
|
||||
public class CourseParser extends FileParser {
|
||||
|
||||
private Document doc;
|
||||
private HashMap<String, Mark> marks = new HashMap<>();
|
||||
|
||||
public CourseParser(String path) {
|
||||
super(path);
|
||||
this.doc = this.parseFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* create a mark by given node
|
||||
*
|
||||
* @param node
|
||||
* @return a mark, or null if fails to create a mark
|
||||
*/
|
||||
private SingleMark generateSingleMark(Node node) {
|
||||
try {
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getElementsByTagName("name").item(0).getTextContent();
|
||||
double lat = Double.valueOf(element.getElementsByTagName("latitude").item(0).getTextContent());
|
||||
double lon = Double.valueOf(element.getElementsByTagName("longitude").item(0).getTextContent());
|
||||
SingleMark singleMark = new SingleMark(name, lat, lon);
|
||||
return singleMark;
|
||||
} else {
|
||||
throw new NoSuchElementException("Cannot generate a mark by given node.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an arrayList of gates
|
||||
*
|
||||
* @return an arrayList of gates, or null if no gate has been found.
|
||||
*/
|
||||
private void generateGateMarks() {
|
||||
ArrayList<GateMark> gateMarks = new ArrayList<>();
|
||||
|
||||
try {
|
||||
NodeList nodes = doc.getElementsByTagName("gate");
|
||||
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node node = nodes.item(i);
|
||||
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getElementsByTagName("name").item(0).getTextContent();
|
||||
SingleMark mark1 = generateSingleMark(element.getElementsByTagName("mark").item(0));
|
||||
SingleMark mark2 = generateSingleMark(element.getElementsByTagName("mark").item(1));
|
||||
GateMark gateMark = new GateMark(name, mark1, mark2, mark1.getLatitude(), mark1.getLongitude());
|
||||
marks.put(name, gateMark);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate an arrayList of marks
|
||||
*
|
||||
* @return an arrayList of marks, or null if no gate has been found.
|
||||
*/
|
||||
private void generateSingleMarks() {
|
||||
ArrayList<SingleMark> singleMarks = new ArrayList<>();
|
||||
|
||||
try {
|
||||
// find the "marks" tag
|
||||
Node node = doc.getElementsByTagName("marks").item(0);
|
||||
// iterate all "marks"'s children
|
||||
for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling()) {
|
||||
// if node's tag name is "mark"
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) n;
|
||||
if (element.getNodeName() == "mark") {
|
||||
Mark mark = generateSingleMark(n);
|
||||
marks.put(mark.getName(), mark);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the order of all the marks along a course
|
||||
*
|
||||
* @return an arrayList of the names of ordered course marks
|
||||
*/
|
||||
private ArrayList<String> getOrder() {
|
||||
ArrayList<String> markOrder = new ArrayList<>();
|
||||
|
||||
try {
|
||||
Node orderNode = doc.getElementsByTagName("order").item(0);
|
||||
for (Node node = orderNode.getFirstChild(); node != null; node = node.getNextSibling()) {
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getTextContent();
|
||||
markOrder.add(name);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return markOrder;
|
||||
}
|
||||
|
||||
public ArrayList<Mark> getCourse() {
|
||||
generateSingleMarks();
|
||||
generateGateMarks();
|
||||
ArrayList<Mark> course = new ArrayList<>();
|
||||
try {
|
||||
for (String mark : getOrder()) {
|
||||
course.add(marks.get(mark));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return course;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Created by Haoming Yin (hyi25) on 16/3/2017
|
||||
*/
|
||||
public abstract class FileParser {
|
||||
|
||||
private String filePath;
|
||||
|
||||
public FileParser(String path) {
|
||||
this.filePath = path;
|
||||
}
|
||||
|
||||
protected Document parseFile() {
|
||||
try {
|
||||
InputStream is = getClass().getResourceAsStream(this.filePath);
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.parse(is);
|
||||
// optional, in order to recover info from broken line.
|
||||
doc.getDocumentElement().normalize();
|
||||
return doc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package seng302.models.parsers;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import seng302.models.Boat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class TeamsParser extends FileParser {
|
||||
|
||||
private Document doc;
|
||||
|
||||
public TeamsParser(String path) {
|
||||
super(path);
|
||||
this.doc = this.parseFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a boat instance by a given team node
|
||||
* @param node a boat node containing name, alias and velocity
|
||||
* @return an instance of Boat
|
||||
*/
|
||||
private Boat parseBoat(Node node) {
|
||||
try {
|
||||
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
||||
Element element = (Element) node;
|
||||
String name = element.getElementsByTagName("name").item(0).getTextContent();
|
||||
String alias = element.getElementsByTagName("alias").item(0).getTextContent();
|
||||
double velocity = Double.valueOf(element.getElementsByTagName("velocity").item(0).getTextContent());
|
||||
Boat boat = new Boat(name, velocity, alias);
|
||||
return boat;
|
||||
} else {
|
||||
throw new NoSuchElementException("Cannot generate a boat by given node");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an arraylist of boats instance.
|
||||
* @return an arraylist of boats in teams file
|
||||
*/
|
||||
public ArrayList<Boat> getBoats() {
|
||||
ArrayList<Boat> boats = new ArrayList<>();
|
||||
try {
|
||||
NodeList nodes = this.doc.getElementsByTagName("team");
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
Node node = nodes.item(i);
|
||||
|
||||
boats.add(parseBoat(node));
|
||||
}
|
||||
return boats;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,14 +17,13 @@ public class ServerThread implements Runnable, Observer {
|
||||
private StreamingServerSocket server;
|
||||
private long startTime;
|
||||
boolean raceStarted = false;
|
||||
boolean raceFinished = false;
|
||||
Map<Integer,Boolean> boatsFinished = new HashMap<>();
|
||||
private List<Boat> boats;
|
||||
private Simulator raceSimulator;
|
||||
|
||||
private final int HEARTBEAT_PERIOD = 5000;
|
||||
private final int RACE_STATUS_PERIOD = 1000/2;
|
||||
private final int RACE_START_STATUS_PERIOD = 1000/2;
|
||||
private final int RACE_STATUS_PERIOD = 1000;
|
||||
private final int RACE_START_STATUS_PERIOD = 1000;
|
||||
private final int BOAT_LOCATION_PERIOD = 1000/5;
|
||||
private final int PORT_NUMBER = 8085;
|
||||
private final int TIME_TILL_RACE_START = 20*1000;
|
||||
@@ -188,6 +187,7 @@ public class ServerThread implements Runnable, Observer {
|
||||
* Start sending race start status messages until race starts
|
||||
*/
|
||||
private void startSendingRaceStatusMessages(){
|
||||
serverLog("Sending race status messages", 0);
|
||||
Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
@@ -248,9 +248,6 @@ public class ServerThread implements Runnable, Observer {
|
||||
sendXml();
|
||||
startSendingRaceStartStatusMessages();
|
||||
startSendingRaceStatusMessages();
|
||||
|
||||
//serverLog("Sending Race Status Messages", 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,16 +264,15 @@ public class ServerThread implements Runnable, Observer {
|
||||
|
||||
for (Boat b : ((Simulator) o).getBoats()){
|
||||
try {
|
||||
|
||||
Message m = new BoatLocationMessage(b.getSourceID(), 1, b.getLat(),
|
||||
b.getLng(), b.getHeadingCorner().getBearingToNextCorner(),
|
||||
((long) b.getSpeed()));
|
||||
server.send(m);
|
||||
} catch (IOException e) {
|
||||
serverLog("Couldn't send a boat status message", 1);
|
||||
serverLog("Couldn't send a boat status message", 3);
|
||||
return;
|
||||
}
|
||||
catch (NullPointerException e){
|
||||
//raceFinished = true;
|
||||
serverLog("Boat " + b.getSourceID() + " finished the race", 1);
|
||||
boatsFinished.put(b.getSourceID(), true);
|
||||
}
|
||||
|
||||
@@ -16,14 +16,12 @@ import java.util.List;
|
||||
class StreamingServerSocket {
|
||||
private ServerSocketChannel socket;
|
||||
private SocketChannel client;
|
||||
private List<Socket> clients;
|
||||
private short seqNum;
|
||||
private boolean isServerStarted;
|
||||
|
||||
StreamingServerSocket(int port) throws IOException{
|
||||
socket = ServerSocketChannel.open();
|
||||
socket.socket().bind(new InetSocketAddress("localhost", port));
|
||||
clients = new ArrayList<>();
|
||||
//socket.setSoTimeout(10000);
|
||||
seqNum = 0;
|
||||
isServerStarted = false;
|
||||
@@ -50,11 +48,8 @@ class StreamingServerSocket {
|
||||
return;
|
||||
}
|
||||
|
||||
//DataOutputStream outputStream = new DataOutputStream(client.getOutputStream());
|
||||
//System.out.println(client);
|
||||
message.send(client);
|
||||
|
||||
|
||||
seqNum++;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,9 +133,7 @@ public class BoatLocationMessage extends Message {
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
heading = (heading + 180.0) % 360.0;
|
||||
|
||||
long headingToSend = (long)((heading/360.0)*49152.0);
|
||||
long headingToSend = (long)((heading/360.0) * 65535.0);
|
||||
|
||||
putByte((byte) messageVersionNumber);
|
||||
putInt(time, 6);
|
||||
|
||||
@@ -3,6 +3,7 @@ package seng302.server.messages;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.SocketChannel;
|
||||
@@ -170,7 +171,6 @@ public abstract class Message {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewind the buffer to the beginning
|
||||
*/
|
||||
@@ -185,11 +185,13 @@ public abstract class Message {
|
||||
* @return
|
||||
*/
|
||||
public static byte[] intToByteArray(long val, int len){
|
||||
long vor = val;
|
||||
int index = 0;
|
||||
byte[] data = new byte[len];
|
||||
|
||||
for (int i = 0; i < len; i++){
|
||||
data[len - index - 1] = (byte) ((val >>> (8 * index)));
|
||||
data[len - index - 1] = (byte) (val & 0xFF);
|
||||
val >>>= 8;
|
||||
index++;
|
||||
}
|
||||
|
||||
@@ -202,9 +204,9 @@ public abstract class Message {
|
||||
*/
|
||||
public static void reverse(byte[] data) {
|
||||
for (int left = 0, right = data.length - 1; left < right; left++, right--) {
|
||||
byte temp = data[left];
|
||||
data[left] = data[right];
|
||||
data[right] = temp;
|
||||
byte temp = (byte) (data[left] & 0xff);
|
||||
data[left] = (byte) (data[right] & 0xff);
|
||||
data[right] = (byte) (temp & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package seng302.server.messages;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.List;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import seng302.server.simulator.parsers.RaceParser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class Simulator extends Observable implements Runnable {
|
||||
|
||||
@@ -34,7 +35,7 @@ public class Simulator extends Observable implements Runnable {
|
||||
boat.setLng(startLng);
|
||||
boat.setLastPassedCorner(course.get(0));
|
||||
boat.setHeadingCorner(course.get(1));
|
||||
boat.setSpeed(50000);
|
||||
boat.setSpeed(ThreadLocalRandom.current().nextInt(40000, 60000 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user