From 262e652dee9de9d1e425207625215de6933293d2 Mon Sep 17 00:00:00 2001 From: Arthur Bols Date: Thu, 12 Apr 2018 23:41:50 +0200 Subject: [PATCH] fix isPassable --- OGP1718-Worms/src/worms/facade/Facade.java | 14 +++- OGP1718-Worms/src/worms/model/World.java | 79 +++++++++++----------- OGP1718-Worms/src/worms/model/Worm.java | 69 ++++++++++--------- 3 files changed, 88 insertions(+), 74 deletions(-) diff --git a/OGP1718-Worms/src/worms/facade/Facade.java b/OGP1718-Worms/src/worms/facade/Facade.java index 4c8b9ed..f23832b 100644 --- a/OGP1718-Worms/src/worms/facade/Facade.java +++ b/OGP1718-Worms/src/worms/facade/Facade.java @@ -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); + } } /** diff --git a/OGP1718-Worms/src/worms/model/World.java b/OGP1718-Worms/src/worms/model/World.java index 16fdf2b..bdd670a 100644 --- a/OGP1718-Worms/src/worms/model/World.java +++ b/OGP1718-Worms/src/worms/model/World.java @@ -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 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 getCircleList(Coordinate center, double radius) { - double[] pos = {Math.floor(center.getX()), Math.floor(center.getY())}; - ArrayList circle = new ArrayList(); - 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 circle = new ArrayList(); + 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 diff --git a/OGP1718-Worms/src/worms/model/Worm.java b/OGP1718-Worms/src/worms/model/Worm.java index b71406f..ec3ec2c 100644 --- a/OGP1718-Worms/src/worms/model/Worm.java +++ b/OGP1718-Worms/src/worms/model/Worm.java @@ -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) {