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;
import com.sun.org.apache.xpath.internal.operations.Mod;
import worms.model.Food;
import worms.model.Team;
import worms.model.World;
@@ -102,7 +103,12 @@ public class Facade implements IFacade {
*/
@Override
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
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() {
if (getWormList().size() == 0) return null;
return getWormList().get(this.activeWorm);
}
@@ -127,7 +128,7 @@ public class World {
*/
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) {
return false;
}
@@ -138,27 +139,32 @@ public class World {
return this.isPassable(location.toArray());
}
/**
*
* @param center ...
* @param radius ...
* @return ...
*/
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(cord.getX(), cord.getY())) return false;
if (!isPassable(lenX, lenY)) return false;
}
return true;
}
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 y = Math.abs(radius * Math.sin(angle) + center.getY());
@@ -168,13 +174,15 @@ public class World {
}
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++) {
for (int y = 0; y <= parts; y++) {
Coordinate temp = Coordinate.create(x * getLengthX(), y * getLengthY());
double[] pos = {Math.floor(center.getX() - radius), Math.floor(center.getY() - radius)};
ArrayList<Coordinate> circle = new ArrayList<Coordinate>();
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)) {
circle.add(temp);
}
@@ -194,7 +202,7 @@ public class World {
double length = lengthX;
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() {
@@ -213,29 +221,22 @@ public class World {
* @return ...
*/
private boolean isPassable(double x, double y) {
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];
}
/**
*
* @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

View File

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