fix isPassable

This commit is contained in:
2018-04-12 23:41:50 +02:00
parent f9a13b9cfd
commit 262e652dee
3 changed files with 88 additions and 74 deletions

View File

@@ -1,5 +1,6 @@
package worms.facade; package worms.facade;
import com.sun.org.apache.xpath.internal.operations.Mod;
import worms.model.Food; import worms.model.Food;
import worms.model.Team; import worms.model.Team;
import worms.model.World; import worms.model.World;
@@ -102,7 +103,12 @@ public class Facade implements IFacade {
*/ */
@Override @Override
public double[] getFurthestLocationInDirection(Worm worm, double direction, double maxDistance) throws ModelException { public double[] getFurthestLocationInDirection(Worm worm, double direction, double maxDistance) throws ModelException {
return worm.getFurthestLocationInDirection(direction, maxDistance).toArray();
try {
return worm.getFurthestLocationInDirection(direction, maxDistance).toArray();
} catch(Exception e) {
throw new ModelException(e);
}
} }
/** /**
@@ -555,7 +561,11 @@ public class Facade implements IFacade {
*/ */
@Override @Override
public Worm getActiveWorm(World world) throws ModelException { public Worm getActiveWorm(World world) throws ModelException {
return world.getActiveWorm(); try {
return world.getActiveWorm();
} catch(IllegalArgumentException e) {
throw new ModelException(e);
}
} }
/** /**

View File

@@ -47,6 +47,7 @@ public class World {
} }
public Worm getActiveWorm() { public Worm getActiveWorm() {
if (getWormList().size() == 0) return null;
return getWormList().get(this.activeWorm); return getWormList().get(this.activeWorm);
} }
@@ -127,7 +128,7 @@ public class World {
*/ */
public boolean isPassable(double[] location) { public boolean isPassable(double[] location) {
if (location[0] / lengthX >= getMap()[0].length || location[0] < 0.0 || if (Math.floor(location[0] / lengthX) >= getMap()[0].length || location[0] < 0.0 ||
location[1] / lengthY >= getMap().length || location[1] < 0.0) { location[1] / lengthY >= getMap().length || location[1] < 0.0) {
return false; return false;
} }
@@ -138,27 +139,32 @@ public class World {
return this.isPassable(location.toArray()); return this.isPassable(location.toArray());
} }
/**
*
* @param center ...
* @param radius ...
* @return ...
*/
public boolean isPassable(double[] center, double radius) { public boolean isPassable(double[] center, double radius) {
ArrayList<Coordinate> circle = getCircleList(Coordinate.create(center),radius); for (double i = 0; i < 2 * Math.PI; i += Math.PI / 180) {
double lenX = center[0] + radius * Math.cos(i);
double lenY = center[1] + radius * Math.sin(i);
for (Coordinate cord: circle) { if (!isPassable(lenX, lenY)) return false;
if (!isPassable(cord.getX(), cord.getY())) return false;
} }
return true; return true;
} }
private boolean isUnderCircle(Coordinate square, Coordinate center, double radius) { private boolean isUnderCircle(Coordinate square, Coordinate center, double radius) {
double angle = Math.atan2(square.getY() - center.getY(), square.getX() - center.getX()); double angle = Math.atan2(center.getY() - square.getY(), square.getX() - center.getX());
if (angle < Math.PI && angle > Math.PI / 2) {
square = Coordinate.create(square.getX() + 1, square.getY() + 1);
}
else if (angle < Math.PI / 2 && angle > 0) angle = Math.PI / 4;
else if (angle < 0 && angle > -Math.PI / 2) angle = -Math.PI / 4;
else if (angle < 0 && angle > -Math.PI) angle = -3* Math.PI / 4;
if (square.getX() == center.getX() && square.getY() == center.getY()) return true;
double x = Math.abs(radius * Math.cos(angle) + center.getX()); double x = Math.abs(radius * Math.cos(angle) + center.getX());
double y = Math.abs(radius * Math.sin(angle) + center.getY()); double y = Math.abs(radius * Math.sin(angle) + center.getY());
@@ -168,13 +174,15 @@ public class World {
} }
public ArrayList<Coordinate> getCircleList(Coordinate center, double radius) { public ArrayList<Coordinate> getCircleList(Coordinate center, double radius) {
double[] pos = {Math.floor(center.getX()), Math.floor(center.getY())};
ArrayList<Coordinate> circle = new ArrayList<Coordinate>();
int parts = (int) Math.ceil(2 * radius / getLengthX());
for (int x = 0; x <= parts; x++) { double[] pos = {Math.floor(center.getX() - radius), Math.floor(center.getY() - radius)};
for (int y = 0; y <= parts; y++) { ArrayList<Coordinate> circle = new ArrayList<Coordinate>();
Coordinate temp = Coordinate.create(x * getLengthX(), y * getLengthY()); int partsX = (int) Math.ceil(center.getX() + radius / getLengthX()) - (int) Math.floor((center.getX() - radius) / getLengthX());
int partsY = (int) Math.ceil(center.getY() + radius / getLengthY()) - (int) Math.floor((center.getY() - radius) / getLengthY());
for (int x = 0; x < partsX; x++) {
for (int y = 0; y < partsY; y++) {
Coordinate temp = Coordinate.create(pos[0] + x * getLengthX(), pos[1] + y * getLengthY());
if (isUnderCircle(temp, center, radius)) { if (isUnderCircle(temp, center, radius)) {
circle.add(temp); circle.add(temp);
} }
@@ -194,7 +202,7 @@ public class World {
double length = lengthX; double length = lengthX;
if (lengthX > lengthY) length = lengthY; if (lengthX > lengthY) length = lengthY;
return isPassable(center, radius) && !isPassable(center, radius + maxDistance + length); return isPassable(center, radius) && !isPassable(center, radius + maxDistance + 0.001);
} }
public double getLengthX() { public double getLengthX() {
@@ -213,29 +221,22 @@ public class World {
* @return ... * @return ...
*/ */
private boolean isPassable(double x, double y) { private boolean isPassable(double x, double y) {
int xCoord = (int) Math.floor(x / lengthX); int xCoord = (int) Math.floor(x / lengthX);
int yCoord = (int) Math.floor(y / lengthY); int yCoord = map.length - 1 - (int) Math.floor(y / lengthY);
if (yCoord < 0 || yCoord >= map.length) {
return false;
}
if (xCoord < 0 || xCoord >= map[0].length) {
return false;
}
return getMap()[yCoord][xCoord]; return getMap()[yCoord][xCoord];
} }
/**
*
* @param x ...
* @param y ...
* @param center ...
* @return
*/
private boolean canHaveAsPartialCircle(double x, double y, double[] center) {
if (!isPassable(x + center[0], y + center[1])) return false;
x *= -1;
if (!isPassable(x + center[0], y + center[1])) return false;
y *= -1;
if (!isPassable(x + center[0], y + center[1])) return false;
x *= -1;
return isPassable(x + center[0], y + center[1]);
}
// =================================================================================== // ===================================================================================
// endregion // endregion

View File

@@ -467,7 +467,7 @@ public class Worm extends GameObject {
/** /**
* move the worm for the given number of steps * move the worm for the given number of steps
* *
* @param numberSteps * @param numberSteps
* the number of steps the worm should take * the number of steps the worm should take
* *
@@ -504,21 +504,20 @@ public class Worm extends GameObject {
if (cost > getActionPoints()) if (cost > getActionPoints())
throw new IllegalArgumentException(); throw new IllegalArgumentException();
double distanceX = getRadius() * cos(getOrientation());
double distanceY = getRadius() * sin(getOrientation());
setLocation(newLocation); setLocation(newLocation);
subtractActionPoints(cost); subtractActionPoints(cost);
} }
/** /**
* *
* @return * @return
*/ */
public Coordinate getFurthestLocationInDirection(double direction, double maxDistance) { public Coordinate getFurthestLocationInDirection(double direction, double maxDistance) {
Coordinate currentLocation = getLocation(); Coordinate currentLocation = getLocation();
double radius = getRadius(); double radius = getRadius();
World world = getWorld(); World world = getWorld();
double step = Math.sqrt(Math.pow(world.getLengthX(), 2) + Math.pow(world.getLengthY(), 2)); double step = Math.sqrt(Math.pow(world.getLengthX() * cos(direction), 2) + Math.pow(world.getLengthY() * sin(direction), 2));
if (step > radius) step = radius;
Coordinate nextLoc, prevLoc; Coordinate nextLoc, prevLoc;
nextLoc = prevLoc = currentLocation; nextLoc = prevLoc = currentLocation;
@@ -529,8 +528,12 @@ public class Worm extends GameObject {
round((nextLoc.getY() + step * sin(direction)) * 100.0) / 100.0); round((nextLoc.getY() + step * sin(direction)) * 100.0) / 100.0);
if (!world.isPassable(nextLoc.toArray(), radius)) { if (!world.isPassable(nextLoc.toArray(), radius)) {
while (!world.isPassable(nextLoc.toArray(), radius)) { while (!world.isPassable(nextLoc.toArray(), radius)) {
nextLoc = Coordinate.create(nextLoc.getX() - 0.1 * cos(direction), nextLoc = Coordinate.create(round((nextLoc.getX() - 0.1 * cos(direction)) * 10.0) / 10.0,
nextLoc.getY() - 0.1 * sin(direction)); round((nextLoc.getY() - 0.1 * sin(direction)) * 10.0) / 10.0);
if (nextLoc.getX() < 0 || nextLoc.getY() < 0) {
nextLoc = prevLoc;
break;
}
} }
break; break;
} }
@@ -545,10 +548,10 @@ public class Worm extends GameObject {
double minDirection = direction - 0.7875; double minDirection = direction - 0.7875;
double maxDirection = direction + 0.7875; double maxDirection = direction + 0.7875;
double maxLocDirection = maxDirection; double maxLocDirection = maxDirection;
Coordinate maxLoc = getFurthestLocationInDirection(maxDirection, this.getRadius()); Coordinate maxLoc = getFurthestLocationInDirection(direction, this.getRadius());
for (; minDirection < maxDirection; minDirection += 0.0175) { for (; minDirection <= maxDirection; minDirection += 0.0175) {
Coordinate tempLoc = getFurthestLocationInDirection(minDirection, this.getRadius()); Coordinate tempLoc = getFurthestLocationInDirection(minDirection, this.getRadius());
if (getDistance(location, tempLoc) > getDistance(location, maxLoc)) { if (getDistance(location, tempLoc) / Math.abs(direction - minDirection) > getDistance(location, maxLoc) / Math.abs(direction - maxLocDirection)) {
maxLoc = tempLoc; maxLoc = tempLoc;
maxLocDirection = minDirection; maxLocDirection = minDirection;
} }
@@ -560,7 +563,7 @@ public class Worm extends GameObject {
return Math.sqrt(Math.pow(Math.abs(start.getX() - end.getX()), 2) + return Math.sqrt(Math.pow(Math.abs(start.getX() - end.getX()), 2) +
Math.pow(Math.abs(start.getY() - end.getY()), 2)); Math.pow(Math.abs(start.getY() - end.getY()), 2));
} }
public void collision(Worm basicWorm, Worm... worm) { public void collision(Worm basicWorm, Worm... worm) {
Worm largestWorm; Worm largestWorm;
Worm smallestWorm; Worm smallestWorm;
@@ -580,7 +583,7 @@ public class Worm extends GameObject {
largestWorm.incrementHitPoints(loseLargest); largestWorm.incrementHitPoints(loseLargest);
} }
} }
//=================================================================================== //===================================================================================
// endregion // endregion
@@ -590,7 +593,7 @@ public class Worm extends GameObject {
/** /**
* turns the worm with the given angle * turns the worm with the given angle
* *
* @param angle * @param angle
* the angle that must be added to the orientation * the angle that must be added to the orientation
* @pre the angle to add must be between 0 and 2pi (including 0) * @pre the angle to add must be between 0 and 2pi (including 0)
@@ -614,8 +617,8 @@ public class Worm extends GameObject {
* *
* @param angle * @param angle
* the angle to be checked * the angle to be checked
* @return true if and only if the given angle is between 0 (including) and 2pi, * @return true if and only if the given angle is between 0 (including) and 2pi,
* the angle is a number and the current number of action points is high enough to turn * the angle is a number and the current number of action points is high enough to turn
* |result == ( (0 <= angle) && (angle < (2 * PI)) && * |result == ( (0 <= angle) && (angle < (2 * PI)) &&
| (!Double.isNaN(angle)) && | (!Double.isNaN(angle)) &&
| (getActionPoints() - (long) ceil(toDegrees(angle) / 6) >= 0) ) | (getActionPoints() - (long) ceil(toDegrees(angle) / 6) >= 0) )
@@ -646,7 +649,7 @@ public class Worm extends GameObject {
/** /**
* let the worm jump * let the worm jump
* *
* @post the worm jumps to his new place. The new place is the x-coordinate plus the jump distance * @post the worm jumps to his new place. The new place is the x-coordinate plus the jump distance
* with the jump velocity * with the jump velocity
* |setLocation(Coordinate.create(getLocation().getX() + jumpDistance(this.jumpVelocity()), getLocation().getY())) * |setLocation(Coordinate.create(getLocation().getX() + jumpDistance(this.jumpVelocity()), getLocation().getY()))
@@ -708,7 +711,7 @@ public class Worm extends GameObject {
/** /**
* Return a boolean whether the worm can jump or not * Return a boolean whether the worm can jump or not
* *
* @return True if and only if the action actionPoints is bigger then 0 and the orientation * @return True if and only if the action actionPoints is bigger then 0 and the orientation
* is lower then pi * is lower then pi
* |result == getActionPoints() > 0 && getOrientation() < PI * |result == getActionPoints() > 0 && getOrientation() < PI
@@ -719,7 +722,7 @@ public class Worm extends GameObject {
/** /**
* 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
@@ -732,7 +735,7 @@ public class Worm extends GameObject {
/** /**
* Return the velocity of the jump * Return the velocity of the jump
* *
* @return the velocity of the jump. The force of the jump is equal to 5 multiplied with the * @return the velocity of the jump. The force of the jump is equal to 5 multiplied with the
* current action actionPoints plus the mass multiplied with the gravity. Therefrom the velocity * current action actionPoints plus the mass multiplied with the gravity. Therefrom the velocity
* is equal to the force divided with the mass, multiplied with the time te force takes * is equal to the force divided with the mass, multiplied with the time te force takes
@@ -744,7 +747,7 @@ public class Worm extends GameObject {
double force = 5 * getActionPoints() + getMass() * G; double force = 5 * getActionPoints() + getMass() * G;
return force / getMass() * FORCE_TIME; return force / getMass() * FORCE_TIME;
} }
public void fight(Worm worm1, Worm... worm2) { public void fight(Worm worm1, Worm... worm2) {
for (Worm wormB: worm2) { for (Worm wormB: worm2) {
Worm attackedWorm; Worm attackedWorm;
@@ -763,13 +766,13 @@ public class Worm extends GameObject {
long loseAttackedWorm = (long) rand.nextInt((((int) N) - 1) + 1) + 1; long loseAttackedWorm = (long) rand.nextInt((((int) N) - 1) + 1) + 1;
attackedWorm.incrementHitPoints(loseAttackedWorm); attackedWorm.incrementHitPoints(loseAttackedWorm);
} }
} }
//=================================================================================== //===================================================================================
// endregion // endregion
// region hitPoints // region hitPoints
//=================================================================================== //===================================================================================
@@ -781,13 +784,13 @@ public class Worm extends GameObject {
public long getHitPoints() { public long getHitPoints() {
return this.hitPoints; return this.hitPoints;
} }
/** /**
* set the current hit points of the worm to the given points * set the current hit points of the worm to the given points
* *
* @param hitPoints * @param hitPoints
* the new points for the worm * the new points for the worm
* @post if the given points are equal or lower then zero, the worm should be dead. * @post if the given points are equal or lower then zero, the worm should be dead.
* Otherwise the current hit points are set to the given points. * Otherwise the current hit points are set to the given points.
* |if (hitpoints <= 0) * |if (hitpoints <= 0)
* | terminate(); * | terminate();
@@ -800,15 +803,15 @@ public class Worm extends GameObject {
terminate(); terminate();
this.hitPoints = hitPoints; this.hitPoints = hitPoints;
} }
/** /**
* this variable contains the current hitpoints of the worm * this variable contains the current hitpoints of the worm
*/ */
private long hitPoints; private long hitPoints;
/** /**
* increment the hit points with the given value * increment the hit points with the given value
* *
* @param value * @param value
* the value that should be substracted * the value that should be substracted
* @post the current hit points should be substracted with the given value. * @post the current hit points should be substracted with the given value.
@@ -817,17 +820,17 @@ public class Worm extends GameObject {
public void decreaseHitPoints(long value) { public void decreaseHitPoints(long value) {
setHitPoints(getHitPoints() - value); setHitPoints(getHitPoints() - value);
} }
public void incrementHitPoints(long value) { public void incrementHitPoints(long value) {
setHitPoints(getHitPoints() + value); setHitPoints(getHitPoints() + value);
} }
//=================================================================================== //===================================================================================
// endregion // endregion
// region falling // region falling
//=================================================================================== //===================================================================================
public void fall() { public void fall() {
double[] center = {getLocation().getX(), getLocation().getY()}; double[] center = {getLocation().getX(), getLocation().getY()};
Coordinate oldLocation = getLocation(); Coordinate oldLocation = getLocation();
@@ -850,10 +853,10 @@ public class Worm extends GameObject {
long cost = 3 * (long) Math.floor(oldLocation.getY() - endY); long cost = 3 * (long) Math.floor(oldLocation.getY() - endY);
decreaseHitPoints(cost); decreaseHitPoints(cost);
} }
public boolean canFall() { public boolean canFall() {
double[] center = {getLocation().getX(), getLocation().getY()}; double[] center = {getLocation().getX(), getLocation().getY()};
return ! getWorld().isAdjacent(center, minRadius); return ! getWorld().isAdjacent(center, getRadius());
} }
public void collisionFall(Worm fallingWorm, Worm... worm) { public void collisionFall(Worm fallingWorm, Worm... worm) {