Wind (story53) AC: Note: "Back" means that the wind shifts counterclockwise while "veer" means clockwise. Shifts should follow the following patterns: 1. The wind should usually oscillate regularly around a mean (several minutes per oscillation and no more than 5 degrees either way.) 2. Occasionally it will either "back" or "veer" (a few degrees a minute, up to 180 degrees shift), and then return to oscillations. Acceptance criteria: - The wind direction follows the above patterns during a race. * Test wind works at 0 to small degree amounts. See merge request !36main
commit
ba13713ba1
@ -1,11 +1,9 @@
|
|||||||
package mock.model;
|
package mock.model.wind;
|
||||||
|
|
||||||
|
|
||||||
import shared.model.Bearing;
|
import shared.model.Bearing;
|
||||||
import shared.model.Wind;
|
import shared.model.Wind;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class generates Wind objects for use in a MockRace.
|
* This class generates Wind objects for use in a MockRace.
|
||||||
* Initialised with a baseline wind speed and direction, and keeps it constant.
|
* Initialised with a baseline wind speed and direction, and keeps it constant.
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package mock.model;
|
package mock.model.wind;
|
||||||
|
|
||||||
|
|
||||||
import shared.model.Bearing;
|
import shared.model.Bearing;
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
package mock.model.wind;
|
||||||
|
|
||||||
|
import shared.model.Bearing;
|
||||||
|
import shared.model.Wind;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class ShiftingWindGenerator implements WindGenerator {
|
||||||
|
private Bearing baselineBearing;
|
||||||
|
private double baseLineSpeed;
|
||||||
|
private double windSpeedVariance = 5;
|
||||||
|
private double bearingVariance = 5; // In degrees
|
||||||
|
private double oscillationVariance = 0.25;
|
||||||
|
private double oscillationPeriod = 1e3 * 60 * 1; // In milliseconds
|
||||||
|
private double shiftTime = 1e3 * 60;
|
||||||
|
private double shiftedSoFar = 0;
|
||||||
|
|
||||||
|
private double timeOfLastOscillationReset = 0;
|
||||||
|
private double timeOfLastChange = 0;
|
||||||
|
private double timeOfLastShift = 0; // Back / veer
|
||||||
|
|
||||||
|
private boolean anticlockwise = false;
|
||||||
|
private boolean shiftAnticlockwise = false;//true for Back, false for veer
|
||||||
|
private boolean shiftThisRace = Math.random() > 0.5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param baselineBearing baseline bearing for wind
|
||||||
|
* @param baseLineSpeed base line speed for wind
|
||||||
|
*/
|
||||||
|
public ShiftingWindGenerator(Bearing baselineBearing, double baseLineSpeed) {
|
||||||
|
this.baselineBearing = baselineBearing;
|
||||||
|
this.baseLineSpeed = baseLineSpeed;
|
||||||
|
initialiseOscillationDirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wind generateBaselineWind() {
|
||||||
|
return new Wind(baselineBearing, baseLineSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Wind generateNextWind(Wind currentWind) {
|
||||||
|
return changeWind(currentWind);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param wind the wind to change
|
||||||
|
* @return the changed wind
|
||||||
|
*/
|
||||||
|
private Wind changeWind(Wind wind) {
|
||||||
|
Wind newWind = new Wind(wind.getWindDirection(), wind.getWindSpeed());
|
||||||
|
oscillateWind(newWind);
|
||||||
|
if (shiftThisRace){shiftWind(newWind);}
|
||||||
|
changeWindSpeed(newWind);
|
||||||
|
timeOfLastChange = System.currentTimeMillis();
|
||||||
|
return newWind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* moves the wind 5 degrees up and down
|
||||||
|
* @param wind the wind to oscillate
|
||||||
|
*/
|
||||||
|
private void oscillateWind(Wind wind) {
|
||||||
|
double timeSinceLastOscillationReset = System.currentTimeMillis() - timeOfLastOscillationReset;
|
||||||
|
double timeSinceLastChange = System.currentTimeMillis() - timeOfLastChange;
|
||||||
|
double newBearing = wind.getWindDirection().degrees();
|
||||||
|
double degreeChange = timeSinceLastChange * 2 * bearingVariance / oscillationPeriod;
|
||||||
|
degreeChange = (1 - oscillationVariance) * degreeChange + (2 * oscillationVariance) * degreeChange * Math.random();
|
||||||
|
|
||||||
|
if (timeSinceLastOscillationReset >= oscillationPeriod) {
|
||||||
|
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||||
|
anticlockwise = !anticlockwise;
|
||||||
|
}
|
||||||
|
if (anticlockwise) {
|
||||||
|
newBearing -= degreeChange;
|
||||||
|
if (newBearing < baselineBearing.degrees() - bearingVariance) {
|
||||||
|
anticlockwise = !anticlockwise;
|
||||||
|
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||||
|
} else {
|
||||||
|
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newBearing += degreeChange;
|
||||||
|
if (newBearing > baselineBearing.degrees() + bearingVariance) {
|
||||||
|
anticlockwise = !anticlockwise;
|
||||||
|
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||||
|
} else {
|
||||||
|
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slowly shifts the wind up to 180 degrees from where it started
|
||||||
|
* @param wind the wind to change
|
||||||
|
*/
|
||||||
|
private void shiftWind(Wind wind) {
|
||||||
|
double timeSinceLastShift = System.currentTimeMillis() - timeOfLastShift;
|
||||||
|
double newBearing = wind.getWindDirection().degrees();
|
||||||
|
double degreeChange = 7;
|
||||||
|
|
||||||
|
if (timeSinceLastShift >= shiftTime){
|
||||||
|
shiftedSoFar += degreeChange;
|
||||||
|
if (shiftedSoFar >= 180){
|
||||||
|
shiftAnticlockwise = Math.random() > 0.5;
|
||||||
|
shiftedSoFar = 0;
|
||||||
|
System.out.println("Swapping");
|
||||||
|
}
|
||||||
|
|
||||||
|
timeOfLastShift = System.currentTimeMillis();
|
||||||
|
if (shiftAnticlockwise){
|
||||||
|
newBearing -= degreeChange;
|
||||||
|
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||||
|
} else {
|
||||||
|
newBearing += degreeChange;
|
||||||
|
wind.setWindDirection(Bearing.fromDegrees(newBearing % 360));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the wind speed
|
||||||
|
* @param wind the wind to change
|
||||||
|
*/
|
||||||
|
private void changeWindSpeed(Wind wind) {
|
||||||
|
double offsetAngle = (wind.getWindDirection().radians() - baselineBearing.radians());
|
||||||
|
double offset = Math.sin(offsetAngle) * windSpeedVariance;
|
||||||
|
double newWindSpeed = baseLineSpeed + offset;
|
||||||
|
wind.setWindSpeed(newWindSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* starts the wind oscillation direction
|
||||||
|
*/
|
||||||
|
private void initialiseOscillationDirection() {
|
||||||
|
anticlockwise = new Random().nextBoolean();
|
||||||
|
timeOfLastOscillationReset = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBearingVariance(double maxBearingVariance) {
|
||||||
|
this.bearingVariance = maxBearingVariance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindSpeedVariance(double windSpeedVariance) {
|
||||||
|
this.windSpeedVariance = windSpeedVariance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOscillationPeriod(double oscillationPeriod) {
|
||||||
|
this.oscillationPeriod = oscillationPeriod;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package mock.model;
|
package mock.model.wind;
|
||||||
|
|
||||||
import shared.model.Wind;
|
import shared.model.Wind;
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 9.2 KiB |
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<java version="1.8.0_111" class="java.beans.XMLDecoder">
|
||||||
|
<object class="java.util.HashMap">
|
||||||
|
<void method="put">
|
||||||
|
<string>SPACE</string>
|
||||||
|
<object class="visualiser.gameController.Keys.VMGKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>SHIFT</string>
|
||||||
|
<object class="visualiser.gameController.Keys.SailsToggleKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>DOWN</string>
|
||||||
|
<object class="visualiser.gameController.Keys.DownWindKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>X</string>
|
||||||
|
<object class="visualiser.gameController.Keys.ZoomOutKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>ENTER</string>
|
||||||
|
<object class="visualiser.gameController.Keys.TackGybeKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>Z</string>
|
||||||
|
<object class="visualiser.gameController.Keys.ZoomInKey"/>
|
||||||
|
</void>
|
||||||
|
<void method="put">
|
||||||
|
<string>UP</string>
|
||||||
|
<object class="visualiser.gameController.Keys.UpWindKey"/>
|
||||||
|
</void>
|
||||||
|
</object>
|
||||||
|
</java>
|
||||||
Loading…
Reference in new issue