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

@@ -504,8 +504,6 @@ 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);
}
@@ -518,7 +516,8 @@ public class Worm extends GameObject {
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;
}
@@ -853,7 +856,7 @@ public class Worm extends GameObject {
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) {