Fixes and improvements...

This commit is contained in:
2018-03-09 22:24:06 +01:00
parent 919cb871e3
commit d86e5d542a
2 changed files with 159 additions and 143 deletions

View File

@@ -82,7 +82,12 @@ public class Facade implements IFacade {
@Override
public double getJumpTime(Worm worm) throws ModelException {
return worm.jumpTime();
try {
return worm.jumpTime();
}
catch(IllegalStateException e) {
throw new ModelException(e);
}
}
/**
@@ -96,8 +101,13 @@ public class Facade implements IFacade {
@Override
public double[] getJumpStep(Worm worm, double t) throws ModelException {
Tuple<Double, Double> jumpStep = worm.jumpStep(t);
return new double[] {jumpStep.item1, jumpStep.item2};
try {
Tuple<Double, Double> jumpStep = worm.jumpStep(t);
return new double[]{jumpStep.item1, jumpStep.item2};
}
catch (IllegalArgumentException e) {
throw new ModelException(e);
}
}
/**

View File

@@ -18,69 +18,6 @@ import static java.lang.Math.*;
*/
public class Worm {
// region properties
//===================================================================================
/**
* this variable contains the location of the worm (a tuple)
*/
private Tuple<Double, Double> location;
/**
* this variable contains the old location of the worm (a tuple)
*/
private Tuple<Double, Double> oldLocation;
/**
* this variable contains the velocity of the jump of the worm
*/
private double jumpVelocity;
/**
* this variable contains the duration of the jump of the worm
*/
private double jumpTime;
/**
* this variable contains the orientation of the worm
*/
private double orientation;
/**
* this variable contains the radius of the worm
*/
private double radius;
/**
* this variable contains the minimum value of the radius
*/
private final double minimumRadius;
/**
* this variable contains the mass of the worm
*/
private double mass;
/**
* this variable contains the current action actionPoints of the worm
*/
private long actionPoints;
/**
* this variable contains the maximum actionPoints a worm can have
*/
private long maxActionPoints;
/**
* this variable contains the name of the worm
*/
private String name;
//===================================================================================
// endregion
// region constructor
//===================================================================================
@@ -102,26 +39,26 @@ public class Worm {
* @param orientation ...
* @param name ...
* @param radius ...
* @param minimumRadius ...
* @param minRadius ...
* @throws IllegalArgumentException ...
*/
public Worm(Tuple<Double, Double> location, double orientation, String name, double radius, double minimumRadius)
public Worm(Tuple<Double, Double> location, double orientation, String name, double radius, double minRadius)
throws IllegalArgumentException {
if (!isValidLocation(location))
throw new IllegalArgumentException("Illegal value for location");
this.location = location;
setLocation(location);
setOrientation(orientation);
if (!isValidMinimumRadius(minimumRadius))
throw new IllegalArgumentException("Invalid minimum radius"); // TODO add decent exception msg
if (!isValidMinRadius(minRadius))
throw new IllegalArgumentException("Invalid min radius"); // TODO add decent exception msg
if (!isValidRadius(radius))
throw new IllegalArgumentException("Invalid radius");
setRadius(radius);
this.minimumRadius = minimumRadius;
this.actionPoints = this.maxActionPoints;
this.minRadius = minRadius;
setActionPoints(getMaxActionPoints());
int validName = isValidName(name);
if (validName != -1)
@@ -142,10 +79,30 @@ public class Worm {
* the location of the worm expresses the place of the worm
* in the play area
*/
@Basic
public Tuple<Double, Double> getLocation() {
return this.location;
}
/**
* check whether the given location is a valid location for the worm
*
* @param location
* the location to check
* @return True if and only if the location is not equal to null and the coordinates of
* the worm are numbers
* |result == (location != null) && (!Double.isNaN(location.item1)) && (!Double.isNaN(location.item2))
*/
public static boolean isValidLocation(Tuple<Double, Double>location) {
return location != null && location.item1 != null && location.item2 != null
&& !Double.isNaN(location.item1) && !Double.isNaN(location.item2);
}
/**
* this variable contains the location of the worm (a tuple)
*/
private Tuple<Double, Double> location;
/**
* set the location of the worm to the given location
*
@@ -164,19 +121,6 @@ public class Worm {
this.location = location;
}
/**
* check whether the given location is a valid location for the worm
*
* @param location
* the location to check
* @return True if and only if the location is not equal to null and the coordinates of
* the worm are numbers
* |result == (location != null) && (!Double.isNaN(location.item1)) && (!Double.isNaN(location.item2))
*/
private boolean isValidLocation(Tuple<Double, Double>location) {
return location != null && location.item1 != null && location.item2 != null
&& !Double.isNaN(location.item1) && !Double.isNaN(location.item2);
}
//===================================================================================
// endregion
@@ -185,6 +129,21 @@ public class Worm {
// region Orientation
//===================================================================================
/**
* Return the orientation of the worm
* the orientation of a worm expresses the direction in which
* the worm is looking
*/
@Basic
public double getOrientation() {
return orientation;
}
/**
* this variable contains the orientation of the worm
*/
private double orientation;
/**
* set the orientation of the worm to the given orientation
*
@@ -200,16 +159,6 @@ public class Worm {
this.orientation = orientation;
}
/**
* Return the orientation of the worm
* the orientation of a worm expresses the direction in which
* the worm is looking
*/
@Basic
public double getOrientation() {
return orientation;
}
//===================================================================================
// endregion
@@ -229,6 +178,18 @@ public class Worm {
return this.radius;
}
/**
* check whether the given radius is a valid minimum radius for the worm
*
* @param radius
* the radius to check
* @return True if and only if the radius is a number and the radius is bigger then 0
* |result == ((!Double.isNaN(radius)) && (radius > 0))
*/
public static boolean isValidMinRadius(double radius) {
return !Double.isNaN(radius) && radius > 0;
}
/**
* set the radius of the worm to the given radius
*
@@ -249,47 +210,57 @@ public class Worm {
}
/**
* check whether the given radius is a valid radius for the worm
* Return the minimum radius the worm can have
* the minimum radius of the worm expresses the minimum length
* of half of the width of the worm
*/
public double getMinRadius() {
return this.minRadius;
}
/**
* This variable contains the radius of the worm
*/
private double radius;
/**
* This variable contains the minimum value of the radius
*/
private final double minRadius;
/**
* Check whether the given radius is a valid radius for the worm
*
* @param radius
* the radius to check
* @return True if and only if the radius is bigger then the minimum radius
* (or equal) and the radius is a number
* |result == (radius >= this.minimumRadius && !Double.isNaN(radius))
* |result == (radius >= this.minRadius && !Double.isNaN(radius))
*/
private boolean isValidRadius(double radius) {
return radius >= this.minimumRadius && !Double.isNaN(radius);
return radius >= this.minRadius && !Double.isNaN(radius);
}
/**
* Return the minimum radius the worm can have
* the minimum radius of the worm expresses the minimum length
* of half of the width of the worm
*/
public double getMinimumRadius() {
return this.minimumRadius;
}
/**
* check whether the given radius is a valid minimum radius for the worm
*
* @param radius
* the radius to check
* @return True if and only if the radius is a number and the radius is bigger then 0
* |result == ((!Double.isNaN(radius)) && (radius > 0))
*/
private boolean isValidMinimumRadius(double radius) {
return !Double.isNaN(radius) && radius > 0;
}
/**
* Return the mass of the worm
* the mass of the worm expresses the weight of the worm
*
*/
@Basic
public double getMass() {
return this.mass;
}
/**
* this variable contains the mass of the worm
*/
private double mass;
/**
* set the mass of the worm to the given mass (dependent on the radius)
*
@@ -319,6 +290,7 @@ public class Worm {
* Return the current action points of the worm
* the action points identifies the energy of the worm
*/
@Basic
public long getActionPoints() {
return this.actionPoints;
}
@@ -343,18 +315,38 @@ public class Worm {
* |this.actionPoints = actionPoints
*/
public void setActionPoints(long actionPoints) {
this.actionPoints = toValidActionPoints(actionPoints);
}
private void setMaxActionPoints(double maxActionPoints) {
this.maxActionPoints = round(maxActionPoints);
setActionPoints(this.actionPoints);
}
/**
*
* @param delta
*/
public void decreaseActionPoints (long delta) {
this.actionPoints = toValidActionPoints(this.actionPoints - delta);
}
/**
* this variable contains the current action actionPoints of the worm
*/
private long actionPoints;
/**
* this variable contains the maximum actionPoints a worm can have
*/
private long maxActionPoints;
private void setMaxActionPoints(double maxActionPoints) {
this.maxActionPoints = round(maxActionPoints);
setActionPoints(this.actionPoints);
}
/**
*
* @param actionPoints
* @return
*/
private long toValidActionPoints(long actionPoints) {
if (actionPoints > this.maxActionPoints)
actionPoints = this.maxActionPoints;
@@ -375,7 +367,7 @@ public class Worm {
* |setPoints(this.points)
*/
private void setMaxPoints(double maxPoints) {
this.maxActionPoints = (int) ceil(maxPoints);
this.maxActionPoints = (int) round(maxPoints);
setActionPoints(this.actionPoints);
}
@@ -455,7 +447,7 @@ public class Worm {
* |&& Character.isLetter(name.charAt(i)) &&
* |allowedCharacters.indexOf(name.charAt(i)))
*/
private int isValidName (String name) {
public static int isValidName (String name) {
if (name.length() < 2 || !Character.isUpperCase(name.charAt(0))) {
return 0;
@@ -472,6 +464,12 @@ public class Worm {
return -1;
}
/**
* this variable contains the name of the worm
*/
private String name;
//===================================================================================
// endregion
@@ -511,6 +509,7 @@ public class Worm {
throw new IllegalArgumentException(); // TODO add decent exception msg
long cost = (long) ceil(abs(cos(this.orientation)) + abs(4 * sin(this.orientation)));
if (cost > this.actionPoints)
throw new IllegalArgumentException(); // TODO add decent exception msg
@@ -539,15 +538,25 @@ public class Worm {
* |new.getOrientation() = this.getOrientation() + angle
* @post the resulting angle (= the new orientation) must be between 0 and 2pi (including 0)
* |0 <= new.getOrientation() < 2pi
* @post current actionPoints of action actionPoints schould be reduced, for this there is another
* @post current actionPoints of action actionPoints should be reduced, for this there is another
* method with as parameter the given angle
* |substractActionPoints(angle)
*/
public void turn(double angle) {
assert 0 <= angle && angle < (2 * PI) && !Double.isNaN(angle);
assert canTurn(angle);
setOrientation((getOrientation() + angle) % (2 * PI));
subtractActionPoints(abs(angle));
}
setOrientation((this.orientation + angle) % (2 * PI));
subtractActionPoints(angle);
/**
*
* @param angle
* @return
*/
private boolean canTurn(double angle) {
return 0 <= angle && angle < (2 * PI) &&
!Double.isNaN(angle) &&
this.actionPoints - (long) ceil(toDegrees(angle) / 6) >= 0;
}
//===================================================================================
@@ -558,12 +567,12 @@ public class Worm {
//===================================================================================
/** this constant contains the gravity */
private final double G = 5.0;
public static final double G = 5.0;
/**
* this constant contains the duration of the force
*/
private final double FORCE_TIME = 0.5;
public static final double FORCE_TIME = 0.5;
/**
* let the worm jump
@@ -583,10 +592,7 @@ public class Worm {
if (!canJump())
throw new IllegalStateException();
this.oldLocation = this.location;
this.jumpVelocity = jumpVelocity();
this.jumpTime = jumpTime();
this.location = Tuple.create(location.item1 + jumpDistance(this.jumpVelocity), location.item2);
this.location = Tuple.create(location.item1 + jumpDistance(this.jumpVelocity()), location.item2);
this.actionPoints = 0;
}
@@ -612,7 +618,8 @@ public class Worm {
if (this.orientation >= PI || this.actionPoints == 0)
throw new IllegalStateException();
return jumpDistance(jumpVelocity()) / (jumpVelocity() * cos(this.orientation));
return (jumpDistance(jumpVelocity()) / (jumpVelocity() * cos(this.orientation)));
}
/**
@@ -621,25 +628,24 @@ public class Worm {
* @return Tuple<Double, Double>
*/
public Tuple<Double, Double> jumpStep(double deltaTime) {
if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime || deltaTime < 0) {
if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0)
throw new IllegalArgumentException();
}
return Tuple.create(oldLocation.item1 + this.jumpVelocity * cos(this.orientation) * deltaTime,
oldLocation.item2 + this.jumpVelocity * sin(this.orientation) * deltaTime - 0.5 * G * pow(deltaTime, 2));
return Tuple.create(this.location.item1 + this.jumpVelocity() * cos(this.orientation) * deltaTime,
this.location.item2 + this.jumpVelocity() * sin(this.orientation) * deltaTime - 0.5 * G * pow(deltaTime, 2));
}
/**
* Return the distance the worm will jump
*
* @param v
* the velocity of the jump
* @return the distance the worm will jump. The distance is equal to the velocity powered by 2 multiplied
* The velocity of the jump
* @return The distance the worm will jump. The distance is equal to the velocity powered by 2 multiplied
* with the sinus of 2 times the orientation en this divided with the gravity
* |(Math.pow(v, 2) * Math.sin(2 * this.orientation)) / this.G
*/
private double jumpDistance(double v) {
return (pow(v, 2) * sin(2 * this.orientation)) / this.G;
return (pow(v, 2) * sin(2 * this.orientation)) / G;
}
/**