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 @Override
public double getJumpTime(Worm worm) throws ModelException { 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 @Override
public double[] getJumpStep(Worm worm, double t) throws ModelException { public double[] getJumpStep(Worm worm, double t) throws ModelException {
Tuple<Double, Double> jumpStep = worm.jumpStep(t); try {
return new double[] {jumpStep.item1, jumpStep.item2}; 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 { 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 // region constructor
//=================================================================================== //===================================================================================
@@ -102,26 +39,26 @@ public class Worm {
* @param orientation ... * @param orientation ...
* @param name ... * @param name ...
* @param radius ... * @param radius ...
* @param minimumRadius ... * @param minRadius ...
* @throws IllegalArgumentException ... * @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 { throws IllegalArgumentException {
if (!isValidLocation(location)) if (!isValidLocation(location))
throw new IllegalArgumentException("Illegal value for location"); throw new IllegalArgumentException("Illegal value for location");
this.location = location; setLocation(location);
setOrientation(orientation); setOrientation(orientation);
if (!isValidMinimumRadius(minimumRadius)) if (!isValidMinRadius(minRadius))
throw new IllegalArgumentException("Invalid minimum radius"); // TODO add decent exception msg throw new IllegalArgumentException("Invalid min radius"); // TODO add decent exception msg
if (!isValidRadius(radius)) if (!isValidRadius(radius))
throw new IllegalArgumentException("Invalid radius"); throw new IllegalArgumentException("Invalid radius");
setRadius(radius); setRadius(radius);
this.minimumRadius = minimumRadius; this.minRadius = minRadius;
this.actionPoints = this.maxActionPoints; setActionPoints(getMaxActionPoints());
int validName = isValidName(name); int validName = isValidName(name);
if (validName != -1) if (validName != -1)
@@ -142,10 +79,30 @@ public class Worm {
* the location of the worm expresses the place of the worm * the location of the worm expresses the place of the worm
* in the play area * in the play area
*/ */
@Basic
public Tuple<Double, Double> getLocation() { public Tuple<Double, Double> getLocation() {
return this.location; 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 * set the location of the worm to the given location
* *
@@ -164,19 +121,6 @@ public class Worm {
this.location = location; 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 // endregion
@@ -185,6 +129,21 @@ public class Worm {
// region Orientation // 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 * set the orientation of the worm to the given orientation
* *
@@ -200,16 +159,6 @@ public class Worm {
this.orientation = orientation; 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 // endregion
@@ -229,6 +178,18 @@ public class Worm {
return this.radius; 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 * 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 * @param radius
* the radius to check * the radius to check
* @return True if and only if the radius is bigger then the minimum radius * @return True if and only if the radius is bigger then the minimum radius
* (or equal) and the radius is a number * (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) { 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 * Return the mass of the worm
* the mass of the worm expresses the weight of the worm * the mass of the worm expresses the weight of the worm
*
*/ */
@Basic
public double getMass() { public double getMass() {
return this.mass; 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) * 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 * Return the current action points of the worm
* the action points identifies the energy of the worm * the action points identifies the energy of the worm
*/ */
@Basic
public long getActionPoints() { public long getActionPoints() {
return this.actionPoints; return this.actionPoints;
} }
@@ -343,18 +315,38 @@ public class Worm {
* |this.actionPoints = actionPoints * |this.actionPoints = actionPoints
*/ */
public void setActionPoints(long actionPoints) { public void setActionPoints(long actionPoints) {
this.actionPoints = toValidActionPoints(actionPoints); this.actionPoints = toValidActionPoints(actionPoints);
} }
private void setMaxActionPoints(double maxActionPoints) {
this.maxActionPoints = round(maxActionPoints); /**
setActionPoints(this.actionPoints); *
} * @param delta
*/
public void decreaseActionPoints (long delta) { public void decreaseActionPoints (long delta) {
this.actionPoints = toValidActionPoints(this.actionPoints - 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) { private long toValidActionPoints(long actionPoints) {
if (actionPoints > this.maxActionPoints) if (actionPoints > this.maxActionPoints)
actionPoints = this.maxActionPoints; actionPoints = this.maxActionPoints;
@@ -375,7 +367,7 @@ public class Worm {
* |setPoints(this.points) * |setPoints(this.points)
*/ */
private void setMaxPoints(double maxPoints) { private void setMaxPoints(double maxPoints) {
this.maxActionPoints = (int) ceil(maxPoints); this.maxActionPoints = (int) round(maxPoints);
setActionPoints(this.actionPoints); setActionPoints(this.actionPoints);
} }
@@ -455,7 +447,7 @@ public class Worm {
* |&& Character.isLetter(name.charAt(i)) && * |&& Character.isLetter(name.charAt(i)) &&
* |allowedCharacters.indexOf(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))) { if (name.length() < 2 || !Character.isUpperCase(name.charAt(0))) {
return 0; return 0;
@@ -472,6 +464,12 @@ public class Worm {
return -1; return -1;
} }
/**
* this variable contains the name of the worm
*/
private String name;
//=================================================================================== //===================================================================================
// endregion // endregion
@@ -511,6 +509,7 @@ public class Worm {
throw new IllegalArgumentException(); // TODO add decent exception msg throw new IllegalArgumentException(); // TODO add decent exception msg
long cost = (long) ceil(abs(cos(this.orientation)) + abs(4 * sin(this.orientation))); long cost = (long) ceil(abs(cos(this.orientation)) + abs(4 * sin(this.orientation)));
if (cost > this.actionPoints) if (cost > this.actionPoints)
throw new IllegalArgumentException(); // TODO add decent exception msg throw new IllegalArgumentException(); // TODO add decent exception msg
@@ -539,15 +538,25 @@ public class Worm {
* |new.getOrientation() = this.getOrientation() + angle * |new.getOrientation() = this.getOrientation() + angle
* @post the resulting angle (= the new orientation) must be between 0 and 2pi (including 0) * @post the resulting angle (= the new orientation) must be between 0 and 2pi (including 0)
* |0 <= new.getOrientation() < 2pi * |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 * method with as parameter the given angle
* |substractActionPoints(angle) * |substractActionPoints(angle)
*/ */
public void turn(double 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 */ /** 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 * 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 * let the worm jump
@@ -583,10 +592,7 @@ public class Worm {
if (!canJump()) if (!canJump())
throw new IllegalStateException(); throw new IllegalStateException();
this.oldLocation = this.location; this.location = Tuple.create(location.item1 + jumpDistance(this.jumpVelocity()), location.item2);
this.jumpVelocity = jumpVelocity();
this.jumpTime = jumpTime();
this.location = Tuple.create(location.item1 + jumpDistance(this.jumpVelocity), location.item2);
this.actionPoints = 0; this.actionPoints = 0;
} }
@@ -612,7 +618,8 @@ public class Worm {
if (this.orientation >= PI || this.actionPoints == 0) if (this.orientation >= PI || this.actionPoints == 0)
throw new IllegalStateException(); 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> * @return Tuple<Double, Double>
*/ */
public Tuple<Double, Double> jumpStep(double deltaTime) { 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(); throw new IllegalArgumentException();
}
return Tuple.create(oldLocation.item1 + this.jumpVelocity * cos(this.orientation) * deltaTime, return Tuple.create(this.location.item1 + this.jumpVelocity() * cos(this.orientation) * deltaTime,
oldLocation.item2 + this.jumpVelocity * sin(this.orientation) * deltaTime - 0.5 * G * pow(deltaTime, 2)); this.location.item2 + this.jumpVelocity() * sin(this.orientation) * deltaTime - 0.5 * G * pow(deltaTime, 2));
} }
/** /**
* Return the distance the worm will jump * Return the distance the worm will jump
* *
* @param v * @param v
* the velocity of the jump * The velocity of the jump
* @return the distance the worm will jump. The distance is equal to the velocity powered by 2 multiplied * @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 * 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 * |(Math.pow(v, 2) * Math.sin(2 * this.orientation)) / this.G
*/ */
private double jumpDistance(double v) { private double jumpDistance(double v) {
return (pow(v, 2) * sin(2 * this.orientation)) / this.G; return (pow(v, 2) * sin(2 * this.orientation)) / G;
} }
/** /**