From 5236d4f0d6ba2803c6e2dcb66e3ed570298f98ba Mon Sep 17 00:00:00 2001 From: Arthur Bols Date: Sun, 20 May 2018 04:23:22 +0200 Subject: [PATCH] 80% :D --- OGP1718-Worms/src/worms/facade/Facade.java | 18 ++- OGP1718-Worms/src/worms/model/GameObject.java | 24 ++- OGP1718-Worms/src/worms/model/Program.java | 149 +++++++++++------- OGP1718-Worms/src/worms/model/Team.java | 10 +- OGP1718-Worms/src/worms/model/World.java | 40 ++--- OGP1718-Worms/src/worms/model/Worm.java | 47 ++++-- .../worms/programs/ArgumentExpression.java | 22 --- .../src/worms/programs/BinaryExpression.java | 6 +- .../src/worms/programs/Expression.java | 2 +- .../src/worms/programs/ProgramFactory.java | 45 +++--- .../src/worms/programs/Statement.java | 32 ++-- .../src/worms/util/TeamComparator.java | 1 + .../worms/model/Part3_FullFacadeTest.java | 2 +- 13 files changed, 225 insertions(+), 173 deletions(-) delete mode 100644 OGP1718-Worms/src/worms/programs/ArgumentExpression.java diff --git a/OGP1718-Worms/src/worms/facade/Facade.java b/OGP1718-Worms/src/worms/facade/Facade.java index 13aae1a..0554aea 100644 --- a/OGP1718-Worms/src/worms/facade/Facade.java +++ b/OGP1718-Worms/src/worms/facade/Facade.java @@ -76,7 +76,7 @@ public class Facade implements IFacade { try { worm.move(); - } catch(IllegalArgumentException e) { + } catch(IllegalArgumentException | IllegalStateException e) { throw new ModelException(e); } } @@ -192,7 +192,11 @@ public class Facade implements IFacade { */ @Override public void jump(Worm worm, double timeStep) throws ModelException { - worm.jump(); + try { + worm.jump(); + } catch (IllegalStateException e) { + throw new ModelException(e); + } } /** @@ -898,7 +902,7 @@ public class Facade implements IFacade { try { worm.setName(newName); } - catch(IllegalNameException e) { + catch(IllegalNameException | IllegalArgumentException e) { throw new ModelException(e); } } @@ -992,7 +996,7 @@ public class Facade implements IFacade { public void addWormsToTeam(Team team, Worm... worms) throws ModelException, MustNotImplementException { try { team.addWorm(worms); - } catch(IllegalArgumentException e) { + } catch(IllegalArgumentException | IllegalStateException e) { throw new ModelException(e); } } @@ -1090,6 +1094,10 @@ public class Facade implements IFacade { */ @Override public void castSpell(World world) throws ModelException { - world.castSpell(); + try { + world.castSpell(); + } catch (IllegalStateException e) { + throw new ModelException(e); + } } } diff --git a/OGP1718-Worms/src/worms/model/GameObject.java b/OGP1718-Worms/src/worms/model/GameObject.java index f7a8121..63e005b 100644 --- a/OGP1718-Worms/src/worms/model/GameObject.java +++ b/OGP1718-Worms/src/worms/model/GameObject.java @@ -42,10 +42,12 @@ public abstract class GameObject { * |setRadius(radius) */ protected GameObject(World world, double[] location, double radius) { + if (!isValidLocation(Coordinate.create(location))) throw new IllegalArgumentException("Illegal location"); setLocation(location); setRadius(radius); - setWorld(world); if (isValidWorld(world)) world.add(this); + setWorld(world); + } /** @@ -62,8 +64,8 @@ public abstract class GameObject { * |setRadius(radius) */ protected GameObject(World world, Coordinate location, double radius) { - setWorld(world); world.add(this); + setWorld(world); setLocation(location); setRadius(radius); } @@ -139,7 +141,14 @@ public abstract class GameObject { */ protected void setLocation(Coordinate location) throws IllegalArgumentException { - if (!isValidLocation(location)) throw new IllegalArgumentException(); + if (!isValidLocation(location)) { + if (!(location.getX() - radius < 0) || + !(location.getX() + radius > getWorld().getWidth()) || + !(location.getY() + radius > getWorld().getHeight()) || + !(location.getY() - radius < 0)) { + world.remove(this); + } else throw new IllegalArgumentException(); + } this.location = location; } @@ -223,8 +232,7 @@ public abstract class GameObject { !(location.getX() - radius < 0) && !(location.getX() + radius > getWorld().getWidth()) && !(location.getY() + radius > getWorld().getHeight()) && - !(location.getY() - radius < 0 && - !getWorld().isPassable(location)); + !(location.getY() - radius < 0) && getWorld().isPassable(location); } /** @@ -252,16 +260,18 @@ public abstract class GameObject { Coordinate otherLocation = o.getLocation(); - return Math.sqrt(Math.pow((otherLocation.getX() - location.getX()), 2) + Math.pow((otherLocation.getY() - location.getY()), 2)); + return Math.sqrt(Math.pow((otherLocation.getX() - location.getX()), 2) + Math.pow((otherLocation.getY() - location.getY()), 2)) - o.getRadius() - getRadius(); } public double getAngle(GameObject o) { + if (o.equals(this)) return Double.NaN; + double x1 = getLocation().getX(); double y1 = getLocation().getY(); double x2 = o.getLocation().getX(); double y2 = o.getLocation().getY(); - return Math.atan(Math.abs(x1 - x2) / Math.abs(y1 - y2)); + return Math.abs(Math.atan(Math.abs(x1 - x2) / Math.abs(y1 - y2)) - Math.PI / 2.0); } } \ No newline at end of file diff --git a/OGP1718-Worms/src/worms/model/Program.java b/OGP1718-Worms/src/worms/model/Program.java index ef66a42..215b166 100644 --- a/OGP1718-Worms/src/worms/model/Program.java +++ b/OGP1718-Worms/src/worms/model/Program.java @@ -1,7 +1,6 @@ package worms.model; import worms.internal.gui.game.IActionHandler; -import worms.programs.ArgumentExpression; import worms.programs.Expression; import worms.programs.Procedure; import worms.programs.Statement; @@ -14,9 +13,15 @@ import static java.lang.Math.toDegrees; public class Program { private final Map procMap; - private final Map varMap = new HashMap<>(); + private final Map varMap = new HashMap<>(); private final List printList = new ArrayList<>(); + private Stack currentType = new Stack<>(); + + private int inLoop = 0; + private int inProcedure = 0; + private boolean breakProcedure = false; + private boolean enoughAP = true; private IActionHandler actionHandler; @@ -36,18 +41,34 @@ public class Program { // reset everything enoughAP = true; - if (iteratorStack.empty()) { + if (callStack.empty()) { executeStatement(main); } else { - executeStatement(lastStatement); - while (!iteratorStack.empty()) { - Iterator it = iteratorStack.pop(); - while (it.hasNext()) { - executeStatement(it.next()); - if (!enoughAP) { - iteratorStack.push(it); - break; + while (!callStack.empty()) { + CallStackNode node = callStack.pop(); + + while(node.statementIterator == null && !callStack.empty()) { + executeStatement(node.lastStatement); + if (!enoughAP) break; + node = callStack.pop(); + } + callStack.push(node); + + if (node.statementIterator == null) { + executeStatement(node.lastStatement); + } else { + Iterator it = node.statementIterator; + + if (!enoughAP) break; + while (it.hasNext()) { + Statement current = it.next(); + executeStatement(current); + if (!enoughAP) { + node.lastStatement = current; + break; + } } + if (!it.hasNext() && enoughAP) callStack.pop(); } if (!enoughAP) break; } @@ -59,13 +80,13 @@ public class Program { execute(worm); if (!enoughAP) return null; - iteratorStack.clear(); + callStack.clear(); return printList; } private boolean breakLoop = false; - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "SuspiciousMethodCalls"}) private void executeStatement(Statement s) { if (!enoughAP) return; @@ -79,38 +100,39 @@ public class Program { case ASSIGN: Statement.Assign data = (Statement.Assign) s.getData(); if (procMap.containsKey(data.getVariableName())) throw new IllegalArgumentException("Already a procedure with same name."); - varMap.put(data.getVariableName(), data.getValue()); + varMap.put(data.getVariableName(), data.getValue().execute(this)); break; case PRINT: - printList.add(processExpression((Expression) s.getData())); + + printList.add(((Expression) s.getData()).execute(this)); break; case ACTION: Statement.Action action = (Statement.Action) s.getData(); switch (action.getType()) { case TURN: - Double val = (Double) processExpression(action.getValue()); + Double val = action.getValue().execute(this); if (val == null) throw new IllegalArgumentException("Turn cannot be null"); if (worm.getActionPoints() - (long) Math.abs(ceil(toDegrees(val) / 6)) < 0) { enoughAP = false; - lastStatement = s; + callStack.push(new CallStackNode(null, s)); return; } else if (!worm.canTurn(val)) throw new IllegalArgumentException("Invalid turn value"); - actionHandler.turn(worm, (double) processExpression(action.getValue())); + actionHandler.turn(worm, action.getValue().execute(this)); break; case MOVE: try { actionHandler.move(worm); } catch (IllegalArgumentException e) { enoughAP = false; - lastStatement = s; + callStack.push(new CallStackNode(null, s)); return; } break; case JUMP: - if (worm.getActionPoints() < 0) { + if (worm.getActionPoints() <= 0) { enoughAP = false; - lastStatement = s; + callStack.push(new CallStackNode(null, s)); return; } actionHandler.jump(worm); @@ -118,7 +140,7 @@ public class Program { case EAT: if (!worm.canEat()) { enoughAP = false; - lastStatement = s; + callStack.push(new CallStackNode(null, s)); return; } actionHandler.eat(worm); @@ -126,7 +148,7 @@ public class Program { case FIRE: if (!worm.canFire()) { enoughAP = false; - lastStatement = s; + callStack.push(new CallStackNode(null, s)); return; } actionHandler.fire(worm); @@ -134,20 +156,29 @@ public class Program { } break; case WHILE: - - Boolean condition = (Boolean) processExpression(((Statement.While) s.getData()).getCondition()); + inLoop++; + currentType.push(Statement.Type.WHILE); + CallStackNode whileNode = new CallStackNode(null, s); + callStack.push(whileNode); + Boolean condition = (Boolean) ((Statement.While) s.getData()).getCondition().execute(this); if (condition == null) throw new IllegalArgumentException("Condition has to be a boolean"); while(condition) { executeStatement(((Statement.While) s.getData()).getBody()); - if (breakLoop) { + if (breakLoop || !enoughAP) { breakLoop = false; break; } - condition = (Boolean) processExpression(((Statement.While) s.getData()).getCondition()); + condition = (Boolean) ((Statement.While) s.getData()).getCondition().execute(this); if (condition == null) throw new IllegalArgumentException("Condition has to be a boolean"); } + if (enoughAP) { + callStack.remove(whileNode); + } + inLoop--; + currentType.pop(); + break; case IF: - if ((Boolean) processExpression(((Statement.If) s.getData()).getCondition())) { + if ((Boolean) ((Statement.If) s.getData()).getCondition().execute(this)) { executeStatement(((Statement.If) s.getData()).getIfBody()); } else { Statement elseBody = ((Statement.If) s.getData()).getElseBody(); @@ -157,48 +188,47 @@ public class Program { } break; case INVOKE: - executeStatement(procMap.get((String) s.getData())); + currentType.push(Statement.Type.ASSIGN); + inProcedure++; + Statement proc = procMap.get(s.getData()); + if (proc == null) throw new IllegalArgumentException("Procedure not defined"); + executeStatement(proc); + inProcedure--; + currentType.pop(); break; case BREAK: - breakLoop = true; + if (inLoop == 0 && inProcedure == 0) { + throw new IllegalArgumentException("BREAK out of scope."); + } + if (currentType.peek() == Statement.Type.WHILE) { + breakLoop = true; + } else { + breakProcedure = true; + } break; } } - private Stack> iteratorStack = new Stack<>(); - private Statement lastStatement = null; + private Stack callStack = new Stack<>(); private void executeStatementBlock(List list) { Iterator it = list.iterator(); - iteratorStack.push(it); + CallStackNode node = new CallStackNode(it, null); + callStack.push(node); while(it.hasNext()) { - executeStatement(it.next()); - if (!enoughAP) { + Statement current = it.next(); + node.lastStatement = current; + executeStatement(current); + if (!enoughAP || breakLoop || breakProcedure) { + breakProcedure = false; break; } } - } + if (!it.hasNext() && enoughAP) callStack.pop(); - @SuppressWarnings("unchecked") - private Object processExpression(Expression e) { - - if (e instanceof ArgumentExpression) { - switch (((ArgumentExpression) e).getType()) { - - case WORM: - return ((ArgumentExpression) e).execute(worm); - case VAR: - return ((ArgumentExpression) e).execute(varMap); - case GOBJECTS: - return ((ArgumentExpression) e).execute(worm.getWorld().getGameObjects()); - } - } else { - return e.execute(this); - } - throw new UnsupportedOperationException(); } public void setActionHandler(IActionHandler actionHandler) { @@ -213,7 +243,18 @@ public class Program { this.worm = worm; } - public Map getVariables() { + public Map getVariables() { return this.varMap; } + + private class CallStackNode { + public Iterator statementIterator; + public Statement lastStatement; + + public CallStackNode(Iterator st, Statement ls) { + statementIterator = st; + lastStatement = ls; + } + } } + diff --git a/OGP1718-Worms/src/worms/model/Team.java b/OGP1718-Worms/src/worms/model/Team.java index 8f68550..9f7c571 100644 --- a/OGP1718-Worms/src/worms/model/Team.java +++ b/OGP1718-Worms/src/worms/model/Team.java @@ -1,6 +1,7 @@ package worms.model; import java.util.*; +import java.util.function.BiFunction; import worms.util.IllegalNameException; import worms.util.TeamComparator; @@ -82,7 +83,7 @@ public class Team { Collection worms = getAllWormsOfTeam(); for (Worm w : worm) { - if (w == null) return false; + if (w == null || w.getTeam() != null) return false; if (!names.add(w.getName())) return false; if (worms.contains(w)) return false; if (worms.size() == 0 && !w.isTerminated()) continue; @@ -109,9 +110,9 @@ public class Team { */ public void removeWormsFromTeam(Worm... worm) throws IllegalArgumentException { - if (worm == null) throw new IllegalArgumentException(); + + if (worm == null || Arrays.stream(worm).anyMatch(w -> Objects.isNull(w) || !getAllWormsOfTeam().contains(w))) throw new IllegalArgumentException(); for (Worm w: worm) { - if (w == null) throw new IllegalArgumentException(); getAllWormsOfTeam().remove(w); w.setTeam(null); } @@ -169,7 +170,8 @@ public class Team { */ public static void mergeTeams(Team receivingTeam, Team supplyingTeam) throws IllegalArgumentException { - if (receivingTeam == null || supplyingTeam == null || receivingTeam.equals(supplyingTeam) ) { + if (receivingTeam == null || supplyingTeam == null || receivingTeam.equals(supplyingTeam) || + supplyingTeam.getAllWormsOfTeam().stream().anyMatch(s -> receivingTeam.getAllWormsOfTeam().contains(s))) { throw new IllegalArgumentException(); } diff --git a/OGP1718-Worms/src/worms/model/World.java b/OGP1718-Worms/src/worms/model/World.java index aa34549..ab5e267 100644 --- a/OGP1718-Worms/src/worms/model/World.java +++ b/OGP1718-Worms/src/worms/model/World.java @@ -30,7 +30,7 @@ public class World { */ public World(double width, double height, boolean[][] map) { - if (!isValidDimension(width) || !isValidDimension(height) || map == null || map.length != height || map[0].length != height) throw new IllegalArgumentException(); + if (!isValidDimension(width) || !isValidDimension(height) || map == null || map.length == 0) throw new IllegalArgumentException(); this.width = width; this.height = height; @@ -69,7 +69,7 @@ public class World { public void activateNextWorm() throws IllegalStateException { if (getWormList().size() == 0) { - throw new IllegalStateException("No worms"); + return; } this.activeWorm++; @@ -97,6 +97,9 @@ public class World { Team lastTeam = getWormList().get(0).getTeam(); for(Worm worm: getWormList()) { + if (worm.getTeam() == null) { + return null; + } if (!lastTeam.equals(worm.getTeam())) { return null; } @@ -228,7 +231,7 @@ public class World { if (Math.floor(location[0] / lengthX) >= getMap()[0].length || location[0] < 0.0 || location[1] / lengthY >= getMap().length || location[1] < 0.0) { - return false; + return true; } return this.map[map.length - 1 - (int) Math.floor(location[1] / lengthY)][(int) Math.floor(location[0] / lengthX)]; @@ -444,9 +447,16 @@ public class World { */ public void add(GameObject obj) throws IllegalStateException, IllegalArgumentException { if (hasActiveGame()) throw new IllegalStateException(); - if (obj == null || !getGameObjects().add(obj) || obj.isTerminated()) throw new IllegalArgumentException(); + if (obj == null || !getGameObjects().add(obj) || obj.isTerminated() || obj.getWorld() != null) throw new IllegalArgumentException(); + + obj.setWorld(this); if (obj.getClass().equals(Food.class) && !((Food) obj).isValidLocation(obj.getLocation(), this)) { + obj.setWorld(null); + throw new IllegalArgumentException(); + } + else if(Worm.class.isInstance(obj) && (!obj.isValidLocation(obj.getLocation()) || !isAdjacent(obj.getLocation(), obj.getRadius()) )) { + obj.setWorld(null); throw new IllegalArgumentException(); } obj.setWorld(this); @@ -503,28 +513,9 @@ public class World { return getGameObjectsByClass(Food.class); } - /** - * - * @param cl - * - * @return ... - * |list.add(gameObject) for each gameObject - * |result == list (ArrayList<>()) - */ - public List getGameObjectList(Class cl) { - List list = new ArrayList<>(); - for (GameObject x : getGameObjects()) { - if (x.getClass().equals(cl)) { - list.add(x); - } - } - return list; - } - @SuppressWarnings("unchecked") public List getGameObjectsByClass(Class cl) { - - return (List) getGameObjects().stream().filter(x -> x.getClass().equals(cl)).collect(Collectors.toList()); + return getGameObjects().stream().filter(cl::isInstance).map(cl::cast).collect(Collectors.toList()); } /** @@ -544,6 +535,7 @@ public class World { Set gameObjects = getGameObjects(); int size = gameObjects.size(); + if (size < 2) throw new IllegalStateException("Less than 2 objects"); int nb1 = new Random().nextInt(size); int nb2 = new Random().nextInt(size); while (nb2 == nb1) { diff --git a/OGP1718-Worms/src/worms/model/Worm.java b/OGP1718-Worms/src/worms/model/Worm.java index a145caa..bee43d4 100644 --- a/OGP1718-Worms/src/worms/model/Worm.java +++ b/OGP1718-Worms/src/worms/model/Worm.java @@ -109,7 +109,6 @@ public class Worm extends GameObject { public Worm(World world, double[] location, double orientation, String name, double radius, double minRadius, Team team) throws IllegalArgumentException { super(world, location, radius); - setTeam(team); setOrientation(orientation); @@ -117,7 +116,7 @@ public class Worm extends GameObject { throw new IllegalArgumentException("Invalid min radius"); this.minRadius = minRadius; - if (this.radius < this.minRadius) throw new IllegalArgumentException("Invalid radius"); + if (!canHaveAsRadius(radius)) throw new IllegalArgumentException("Invalid radius"); setActionPoints(getMaxActionPoints()); @@ -132,6 +131,7 @@ public class Worm extends GameObject { if (team != null) { team.addWorm(this); } + setTeam(team); } //=================================================================================== @@ -168,7 +168,7 @@ public class Worm extends GameObject { */ @Raw private void setOrientation(double orientation) { - assert isValidOrientation(orientation); + if (!isValidOrientation(orientation)) throw new IllegalArgumentException(); this.orientation = orientation; } @@ -248,7 +248,7 @@ public class Worm extends GameObject { */ @Raw private boolean canHaveAsRadius(double radius) { - return !Double.isNaN(radius) && radius >= getMinRadius(); + return !Double.isNaN(radius) && radius >= getMinRadius() && !Double.isInfinite(radius); } /** @@ -410,6 +410,8 @@ public class Worm extends GameObject { */ public static int isValidName(String name) { + if (name == null) throw new IllegalArgumentException("Name must not be null"); + if (name.length() < 2 || !Character.isUpperCase(name.charAt(0))) { return 0; } @@ -473,15 +475,16 @@ public class Worm extends GameObject { */ public void move() throws IllegalArgumentException { + if (getWorld() == null) throw new IllegalStateException(); + double newDirection = getFurthestLocationDirection(); Coordinate newLocation = getFurthestLocationInDirection(newDirection, this.getRadius()); double distance = getDistance(this.getLocation(), newLocation); - long cost = (long) ceil(abs(distance * cos(newDirection)) + abs(4 * distance * sin(newDirection))); + long cost = (long) round(abs(distance * cos(newDirection)) + abs(4 * distance * sin(newDirection))); if (cost > getActionPoints()) throw new IllegalArgumentException(); - setLocation(newLocation); subtractActionPoints(cost); } @@ -501,6 +504,10 @@ public class Worm extends GameObject { double radius = getRadius(); World world = getWorld(); + if (direction < 0 || direction > 2 * Math.PI || Double.isNaN(direction) || maxDistance < 0 || + Double.isNaN(maxDistance) || Double.isInfinite(maxDistance)) + throw new IllegalArgumentException("Invalid direction/distance"); + if (getWorld() == null) { return Coordinate.create(currentLocation.getX() + maxDistance * cos(direction), currentLocation.getY() + maxDistance * sin(direction)); } @@ -550,6 +557,7 @@ public class Worm extends GameObject { double maxLocDirection = minDirection; Coordinate maxLoc = location; for (; minDirection <= maxDirection; minDirection += 0.0175) { + if (minDirection < 0) minDirection = 0.0; Coordinate tempLoc = getFurthestLocationInDirection(minDirection, this.getRadius()); if (!getWorld().isAdjacent(tempLoc, getRadius())) tempLoc = location; if (getDistance(location, tempLoc) / Math.abs(direction - minDirection) > getDistance(location, maxLoc) / Math.abs(direction - maxLocDirection)) { @@ -708,8 +716,6 @@ public class Worm extends GameObject { } setLocation(newLocation); setActionPoints(0); - - checkEat(); } /** @@ -740,7 +746,7 @@ public class Worm extends GameObject { * |if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0) */ public Coordinate jumpStep(double deltaTime) { - if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0) + if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0 || getActionPoints() == 0) throw new IllegalArgumentException(); double velocity = this.jumpVelocity(); @@ -766,12 +772,14 @@ public class Worm extends GameObject { * |result == t */ private double calcJumpTime() { - double v = jumpVelocity(); + World world = getWorld(); + if (world == null) throw new IllegalStateException("World cannot be null"); + double v = jumpVelocity(); double t = 0; double a = getOrientation(); Coordinate loc = getLocation(); - World world = getWorld(); + double radius = getRadius(); Coordinate newLoc; @@ -1113,19 +1121,18 @@ public class Worm extends GameObject { if (terminate) food.terminate(); - System.out.println(getWorld().isAdjacent(getLocation(), getRadius())); - double radius = getRadius(); double changeRadius = radius * 0.1; if (food.isPoisonous()) { changeRadius *= -1; radius *= 0.9; + if (radius < getMinRadius()) radius = getMinRadius(); } else { radius *= 1.1; } - + decreaseActionPoints(8); setRadius(radius); World world = getWorld(); @@ -1183,7 +1190,7 @@ public class Worm extends GameObject { */ public void checkEat() { - if (!canEat()) throw new IllegalStateException(); + if (!canEat()) return; World world = getWorld(); if (world != null) { @@ -1191,6 +1198,7 @@ public class Worm extends GameObject { for (Food food : foodList) { if (getDistance(food.getLocation(), this.getLocation()) < this.getRadius() + food.getRadius()) { eat(food); + break; } } } @@ -1272,4 +1280,13 @@ public class Worm extends GameObject { // =================================================================================== // endregion + + @Override + public void terminate() { + super.terminate(); + if (team != null) { + team.removeWormsFromTeam(this); + setTeam(null); + } + } } diff --git a/OGP1718-Worms/src/worms/programs/ArgumentExpression.java b/OGP1718-Worms/src/worms/programs/ArgumentExpression.java deleted file mode 100644 index 4b9327c..0000000 --- a/OGP1718-Worms/src/worms/programs/ArgumentExpression.java +++ /dev/null @@ -1,22 +0,0 @@ -package worms.programs; - -public abstract class ArgumentExpression implements Expression { - - public final Type type; - - protected ArgumentExpression(Type type) { - this.type = type; - } - - public abstract R execute(O o); - - - public Type getType() { - return this.type; - } - public enum Type { - WORM, - VAR, - GOBJECTS - } -} diff --git a/OGP1718-Worms/src/worms/programs/BinaryExpression.java b/OGP1718-Worms/src/worms/programs/BinaryExpression.java index 199ce3f..47664d4 100644 --- a/OGP1718-Worms/src/worms/programs/BinaryExpression.java +++ b/OGP1718-Worms/src/worms/programs/BinaryExpression.java @@ -19,10 +19,6 @@ public class BinaryExpression implements Expression { @Override @SuppressWarnings("unchecked") public R execute(Program program) { - try { - return function.apply(left.execute(program), right.execute(program)); - } catch (ClassCastException e) { - throw new IllegalArgumentException(); - } + return function.apply(left.execute(program), right.execute(program)); } } diff --git a/OGP1718-Worms/src/worms/programs/Expression.java b/OGP1718-Worms/src/worms/programs/Expression.java index ba21b55..4b89f45 100644 --- a/OGP1718-Worms/src/worms/programs/Expression.java +++ b/OGP1718-Worms/src/worms/programs/Expression.java @@ -1,7 +1,7 @@ package worms.programs; import worms.model.Program; - +@FunctionalInterface public interface Expression { R execute(Program program); diff --git a/OGP1718-Worms/src/worms/programs/ProgramFactory.java b/OGP1718-Worms/src/worms/programs/ProgramFactory.java index f73df94..0d9f6cf 100644 --- a/OGP1718-Worms/src/worms/programs/ProgramFactory.java +++ b/OGP1718-Worms/src/worms/programs/ProgramFactory.java @@ -8,6 +8,7 @@ import worms.util.MustNotImplementException; import java.util.Comparator; import java.util.List; +import java.util.Objects; public class ProgramFactory implements IProgramFactory { /** @@ -58,7 +59,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ASSIGN, new Statement.Assign(variableName, value)); } /** @@ -70,7 +71,7 @@ public class ProgramFactory implements IProgramFactory>(Statement.Type.PRINT, value); } /** @@ -82,7 +83,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.TURN, angle)); } /** @@ -93,7 +94,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.MOVE, null)); } /** @@ -103,7 +104,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.JUMP, null)); } /** @@ -113,7 +114,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.EAT, null)); } /** @@ -124,7 +125,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.FIRE, null)); } /** @@ -135,7 +136,7 @@ public class ProgramFactory implements IProgramFactory statements, SourceLocation sourceLocation) throws ModelException { - return new Statement(Statement.Type.BLOCK, statements); + return new Statement<>(Statement.Type.BLOCK, statements); } /** @@ -150,7 +151,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.IF, new Statement.If(condition, ifBody, elseBody)); } /** @@ -162,7 +163,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.WHILE, new Statement.While(condition, body)); } /** @@ -172,7 +173,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.BREAK, null); } /** @@ -183,7 +184,7 @@ public class ProgramFactory implements IProgramFactory(Statement.Type.INVOKE, procedureName); } /** @@ -195,7 +196,10 @@ public class ProgramFactory implements IProgramFactory) program -> program.getVariables().get(variableName).execute(program); + return (Expression) program -> { + if (!program.getVariables().containsKey(variableName)) throw new IllegalArgumentException("Variable not declared"); + return program.getVariables().get(variableName); + }; } /** @@ -239,7 +243,7 @@ public class ProgramFactory implements IProgramFactory(w -> w.getWorm()); + return new UnaryArgumentExpression(Program::getWorm); } /** @@ -295,7 +299,7 @@ public class ProgramFactory implements IProgramFactory(left, right, (l, r) -> l.equals(r)); + return new BinaryExpression(left, right, Objects::equals); } /** @@ -321,7 +325,7 @@ public class ProgramFactory implements IProgramFactory g.getAngle(p.getWorm()) == p.getWorm().getOrientation()) + .filter(g -> g.getAngle(p.getWorm()) == p.getWorm().getOrientation() + a) .min(Comparator.comparingDouble(gameObject -> gameObject.getDistance(p.getWorm()))) .orElse(null)); } @@ -337,7 +341,7 @@ public class ProgramFactory implements IProgramFactory(entity, (w, p) -> w.getTeam().equals(p.getWorm().getTeam())); + return new BinaryArgumentExpression(entity, (w, p) -> {if (w == null) return false; return Objects.equals(w.getTeam(), p.getWorm().getTeam());}); } /** @@ -350,7 +354,10 @@ public class ProgramFactory implements IProgramFactory(entity, (e, p) -> e.getDistance(p.getWorm())); + return new BinaryArgumentExpression(entity, (e, p) -> { + if (e == null) throw new IllegalArgumentException(); + return e.getDistance(p.getWorm()); + }); } /** @@ -363,6 +370,6 @@ public class ProgramFactory implements IProgramFactory(entity, w -> w instanceof Worm); + return new UnaryExpression(entity, e -> e instanceof Worm); } } diff --git a/OGP1718-Worms/src/worms/programs/Statement.java b/OGP1718-Worms/src/worms/programs/Statement.java index 089af84..714690f 100644 --- a/OGP1718-Worms/src/worms/programs/Statement.java +++ b/OGP1718-Worms/src/worms/programs/Statement.java @@ -1,11 +1,11 @@ package worms.programs; -public class Statement { +public class Statement { private final Type type; - private final Object data; + private final T data; - public Statement(Type type, Object data) { + public Statement(Type type, T data) { this.type = type; this.data = data; } @@ -14,7 +14,7 @@ public class Statement { return this.type; } - public Object getData() { + public T getData() { return data; } @@ -29,13 +29,13 @@ public class Statement { BREAK } - public static class If { + public static class If { private final Statement ifBody; private final Statement elseBody; - private final Expression condition; + private final Expression condition; - public If(Expression condition, Statement ifBody, Statement elseBody) { + public If(Expression condition, Statement ifBody, Statement elseBody) { this.ifBody = ifBody; this.elseBody = elseBody; this.condition = condition; @@ -49,17 +49,17 @@ public class Statement { return elseBody; } - public Expression getCondition() { + public Expression getCondition() { return condition; } } - public static class While { + public static class While { - private final Expression condition; + private final Expression condition; private final Statement body; - public While(Expression condition, Statement body) { + public While(Expression condition, Statement body) { this.condition = condition; this.body = body; } @@ -68,7 +68,7 @@ public class Statement { return body; } - public Expression getCondition() { + public Expression getCondition() { return condition; } } @@ -106,17 +106,17 @@ public class Statement { } } - public static class Assign { + public static class Assign { private final String variableName; - private final Expression value; + private final Expression value; - public Assign(String variableName, Expression value) { + public Assign(String variableName, Expression value) { this.variableName = variableName; this.value = value; } - public Expression getValue() { + public Expression getValue() { return value; } diff --git a/OGP1718-Worms/src/worms/util/TeamComparator.java b/OGP1718-Worms/src/worms/util/TeamComparator.java index 3bc3554..bd53b14 100644 --- a/OGP1718-Worms/src/worms/util/TeamComparator.java +++ b/OGP1718-Worms/src/worms/util/TeamComparator.java @@ -7,6 +7,7 @@ import java.util.Comparator; public class TeamComparator implements Comparator { @Override public int compare(Worm t1, Worm t2) { + if (t1.equals(t2)) return 0; return t1.getName().compareTo(t2.getName()); } } diff --git a/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java b/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java index 39a4440..795f9e8 100755 --- a/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java +++ b/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java @@ -976,7 +976,7 @@ public class Part3_FullFacadeTest { @Test public void createWorm_IllegalWorld() { max_score += 2; - World someWorld = facade.createWorld(10.0, 20.0, map10x10); + World someWorld = facade.createWorld(10.0, 10.0, map10x10); facade.terminate(someWorld); try { facade.createWorm(someWorld, new double[] { 8.68, 8.68 }, 0.3, 0.3, "Worm", null);