80% :D
This commit is contained in:
@@ -76,7 +76,7 @@ public class Facade implements IFacade {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
worm.move();
|
worm.move();
|
||||||
} catch(IllegalArgumentException e) {
|
} catch(IllegalArgumentException | IllegalStateException e) {
|
||||||
throw new ModelException(e);
|
throw new ModelException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,11 @@ public class Facade implements IFacade {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void jump(Worm worm, double timeStep) throws ModelException {
|
public void jump(Worm worm, double timeStep) throws ModelException {
|
||||||
|
try {
|
||||||
worm.jump();
|
worm.jump();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new ModelException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -898,7 +902,7 @@ public class Facade implements IFacade {
|
|||||||
try {
|
try {
|
||||||
worm.setName(newName);
|
worm.setName(newName);
|
||||||
}
|
}
|
||||||
catch(IllegalNameException e) {
|
catch(IllegalNameException | IllegalArgumentException e) {
|
||||||
throw new ModelException(e);
|
throw new ModelException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -992,7 +996,7 @@ public class Facade implements IFacade {
|
|||||||
public void addWormsToTeam(Team team, Worm... worms) throws ModelException, MustNotImplementException {
|
public void addWormsToTeam(Team team, Worm... worms) throws ModelException, MustNotImplementException {
|
||||||
try {
|
try {
|
||||||
team.addWorm(worms);
|
team.addWorm(worms);
|
||||||
} catch(IllegalArgumentException e) {
|
} catch(IllegalArgumentException | IllegalStateException e) {
|
||||||
throw new ModelException(e);
|
throw new ModelException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1090,6 +1094,10 @@ public class Facade implements IFacade {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void castSpell(World world) throws ModelException {
|
public void castSpell(World world) throws ModelException {
|
||||||
|
try {
|
||||||
world.castSpell();
|
world.castSpell();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new ModelException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,10 +42,12 @@ public abstract class GameObject {
|
|||||||
* |setRadius(radius)
|
* |setRadius(radius)
|
||||||
*/
|
*/
|
||||||
protected GameObject(World world, double[] location, double radius) {
|
protected GameObject(World world, double[] location, double radius) {
|
||||||
|
if (!isValidLocation(Coordinate.create(location))) throw new IllegalArgumentException("Illegal location");
|
||||||
setLocation(location);
|
setLocation(location);
|
||||||
setRadius(radius);
|
setRadius(radius);
|
||||||
setWorld(world);
|
|
||||||
if (isValidWorld(world)) world.add(this);
|
if (isValidWorld(world)) world.add(this);
|
||||||
|
setWorld(world);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,8 +64,8 @@ public abstract class GameObject {
|
|||||||
* |setRadius(radius)
|
* |setRadius(radius)
|
||||||
*/
|
*/
|
||||||
protected GameObject(World world, Coordinate location, double radius) {
|
protected GameObject(World world, Coordinate location, double radius) {
|
||||||
setWorld(world);
|
|
||||||
world.add(this);
|
world.add(this);
|
||||||
|
setWorld(world);
|
||||||
setLocation(location);
|
setLocation(location);
|
||||||
setRadius(radius);
|
setRadius(radius);
|
||||||
}
|
}
|
||||||
@@ -139,7 +141,14 @@ public abstract class GameObject {
|
|||||||
*/
|
*/
|
||||||
protected void setLocation(Coordinate location) throws IllegalArgumentException {
|
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;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,8 +232,7 @@ public abstract class GameObject {
|
|||||||
!(location.getX() - radius < 0) &&
|
!(location.getX() - radius < 0) &&
|
||||||
!(location.getX() + radius > getWorld().getWidth()) &&
|
!(location.getX() + radius > getWorld().getWidth()) &&
|
||||||
!(location.getY() + radius > getWorld().getHeight()) &&
|
!(location.getY() + radius > getWorld().getHeight()) &&
|
||||||
!(location.getY() - radius < 0 &&
|
!(location.getY() - radius < 0) && getWorld().isPassable(location);
|
||||||
!getWorld().isPassable(location));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,16 +260,18 @@ public abstract class GameObject {
|
|||||||
|
|
||||||
Coordinate otherLocation = o.getLocation();
|
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) {
|
public double getAngle(GameObject o) {
|
||||||
|
|
||||||
|
if (o.equals(this)) return Double.NaN;
|
||||||
|
|
||||||
double x1 = getLocation().getX();
|
double x1 = getLocation().getX();
|
||||||
double y1 = getLocation().getY();
|
double y1 = getLocation().getY();
|
||||||
double x2 = o.getLocation().getX();
|
double x2 = o.getLocation().getX();
|
||||||
double y2 = o.getLocation().getY();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
package worms.model;
|
package worms.model;
|
||||||
|
|
||||||
import worms.internal.gui.game.IActionHandler;
|
import worms.internal.gui.game.IActionHandler;
|
||||||
import worms.programs.ArgumentExpression;
|
|
||||||
import worms.programs.Expression;
|
import worms.programs.Expression;
|
||||||
import worms.programs.Procedure;
|
import worms.programs.Procedure;
|
||||||
import worms.programs.Statement;
|
import worms.programs.Statement;
|
||||||
@@ -14,9 +13,15 @@ import static java.lang.Math.toDegrees;
|
|||||||
public class Program {
|
public class Program {
|
||||||
|
|
||||||
private final Map<String, Statement> procMap;
|
private final Map<String, Statement> procMap;
|
||||||
private final Map<String, Expression> varMap = new HashMap<>();
|
private final Map<String, Object> varMap = new HashMap<>();
|
||||||
private final List<Object> printList = new ArrayList<>();
|
private final List<Object> printList = new ArrayList<>();
|
||||||
|
|
||||||
|
private Stack<Statement.Type> currentType = new Stack<>();
|
||||||
|
|
||||||
|
private int inLoop = 0;
|
||||||
|
private int inProcedure = 0;
|
||||||
|
private boolean breakProcedure = false;
|
||||||
|
|
||||||
private boolean enoughAP = true;
|
private boolean enoughAP = true;
|
||||||
|
|
||||||
private IActionHandler actionHandler;
|
private IActionHandler actionHandler;
|
||||||
@@ -36,19 +41,35 @@ public class Program {
|
|||||||
// reset everything
|
// reset everything
|
||||||
enoughAP = true;
|
enoughAP = true;
|
||||||
|
|
||||||
if (iteratorStack.empty()) {
|
if (callStack.empty()) {
|
||||||
executeStatement(main);
|
executeStatement(main);
|
||||||
} else {
|
} else {
|
||||||
executeStatement(lastStatement);
|
while (!callStack.empty()) {
|
||||||
while (!iteratorStack.empty()) {
|
CallStackNode node = callStack.pop();
|
||||||
Iterator<Statement> it = iteratorStack.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<Statement> it = node.statementIterator;
|
||||||
|
|
||||||
|
if (!enoughAP) break;
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
executeStatement(it.next());
|
Statement current = it.next();
|
||||||
|
executeStatement(current);
|
||||||
if (!enoughAP) {
|
if (!enoughAP) {
|
||||||
iteratorStack.push(it);
|
node.lastStatement = current;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!it.hasNext() && enoughAP) callStack.pop();
|
||||||
|
}
|
||||||
if (!enoughAP) break;
|
if (!enoughAP) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,13 +80,13 @@ public class Program {
|
|||||||
execute(worm);
|
execute(worm);
|
||||||
|
|
||||||
if (!enoughAP) return null;
|
if (!enoughAP) return null;
|
||||||
iteratorStack.clear();
|
callStack.clear();
|
||||||
return printList;
|
return printList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean breakLoop = false;
|
private boolean breakLoop = false;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({"unchecked", "SuspiciousMethodCalls"})
|
||||||
private void executeStatement(Statement s) {
|
private void executeStatement(Statement s) {
|
||||||
|
|
||||||
if (!enoughAP) return;
|
if (!enoughAP) return;
|
||||||
@@ -79,38 +100,39 @@ public class Program {
|
|||||||
case ASSIGN:
|
case ASSIGN:
|
||||||
Statement.Assign data = (Statement.Assign) s.getData();
|
Statement.Assign data = (Statement.Assign) s.getData();
|
||||||
if (procMap.containsKey(data.getVariableName())) throw new IllegalArgumentException("Already a procedure with same name.");
|
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;
|
break;
|
||||||
case PRINT:
|
case PRINT:
|
||||||
printList.add(processExpression((Expression) s.getData()));
|
|
||||||
|
printList.add(((Expression) s.getData()).execute(this));
|
||||||
break;
|
break;
|
||||||
case ACTION:
|
case ACTION:
|
||||||
Statement.Action action = (Statement.Action) s.getData();
|
Statement.Action action = (Statement.Action) s.getData();
|
||||||
switch (action.getType()) {
|
switch (action.getType()) {
|
||||||
case TURN:
|
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 (val == null) throw new IllegalArgumentException("Turn cannot be null");
|
||||||
if (worm.getActionPoints() - (long) Math.abs(ceil(toDegrees(val) / 6)) < 0) {
|
if (worm.getActionPoints() - (long) Math.abs(ceil(toDegrees(val) / 6)) < 0) {
|
||||||
enoughAP = false;
|
enoughAP = false;
|
||||||
lastStatement = s;
|
callStack.push(new CallStackNode(null, s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!worm.canTurn(val)) throw new IllegalArgumentException("Invalid turn value");
|
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;
|
break;
|
||||||
case MOVE:
|
case MOVE:
|
||||||
try {
|
try {
|
||||||
actionHandler.move(worm);
|
actionHandler.move(worm);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
enoughAP = false;
|
enoughAP = false;
|
||||||
lastStatement = s;
|
callStack.push(new CallStackNode(null, s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case JUMP:
|
case JUMP:
|
||||||
if (worm.getActionPoints() < 0) {
|
if (worm.getActionPoints() <= 0) {
|
||||||
enoughAP = false;
|
enoughAP = false;
|
||||||
lastStatement = s;
|
callStack.push(new CallStackNode(null, s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.jump(worm);
|
actionHandler.jump(worm);
|
||||||
@@ -118,7 +140,7 @@ public class Program {
|
|||||||
case EAT:
|
case EAT:
|
||||||
if (!worm.canEat()) {
|
if (!worm.canEat()) {
|
||||||
enoughAP = false;
|
enoughAP = false;
|
||||||
lastStatement = s;
|
callStack.push(new CallStackNode(null, s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.eat(worm);
|
actionHandler.eat(worm);
|
||||||
@@ -126,7 +148,7 @@ public class Program {
|
|||||||
case FIRE:
|
case FIRE:
|
||||||
if (!worm.canFire()) {
|
if (!worm.canFire()) {
|
||||||
enoughAP = false;
|
enoughAP = false;
|
||||||
lastStatement = s;
|
callStack.push(new CallStackNode(null, s));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actionHandler.fire(worm);
|
actionHandler.fire(worm);
|
||||||
@@ -134,20 +156,29 @@ public class Program {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WHILE:
|
case WHILE:
|
||||||
|
inLoop++;
|
||||||
Boolean condition = (Boolean) processExpression(((Statement.While) s.getData()).getCondition());
|
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");
|
if (condition == null) throw new IllegalArgumentException("Condition has to be a boolean");
|
||||||
while(condition) {
|
while(condition) {
|
||||||
executeStatement(((Statement.While) s.getData()).getBody());
|
executeStatement(((Statement.While) s.getData()).getBody());
|
||||||
if (breakLoop) {
|
if (breakLoop || !enoughAP) {
|
||||||
breakLoop = false;
|
breakLoop = false;
|
||||||
break;
|
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 (condition == null) throw new IllegalArgumentException("Condition has to be a boolean");
|
||||||
}
|
}
|
||||||
|
if (enoughAP) {
|
||||||
|
callStack.remove(whileNode);
|
||||||
|
}
|
||||||
|
inLoop--;
|
||||||
|
currentType.pop();
|
||||||
|
break;
|
||||||
case IF:
|
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());
|
executeStatement(((Statement.If) s.getData()).getIfBody());
|
||||||
} else {
|
} else {
|
||||||
Statement elseBody = ((Statement.If) s.getData()).getElseBody();
|
Statement elseBody = ((Statement.If) s.getData()).getElseBody();
|
||||||
@@ -157,48 +188,47 @@ public class Program {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INVOKE:
|
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;
|
break;
|
||||||
case BREAK:
|
case BREAK:
|
||||||
|
if (inLoop == 0 && inProcedure == 0) {
|
||||||
|
throw new IllegalArgumentException("BREAK out of scope.");
|
||||||
|
}
|
||||||
|
if (currentType.peek() == Statement.Type.WHILE) {
|
||||||
breakLoop = true;
|
breakLoop = true;
|
||||||
|
} else {
|
||||||
|
breakProcedure = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stack<Iterator<Statement>> iteratorStack = new Stack<>();
|
private Stack<CallStackNode> callStack = new Stack<>();
|
||||||
private Statement lastStatement = null;
|
|
||||||
|
|
||||||
private void executeStatementBlock(List<Statement> list) {
|
private void executeStatementBlock(List<Statement> list) {
|
||||||
|
|
||||||
Iterator<Statement> it = list.iterator();
|
Iterator<Statement> it = list.iterator();
|
||||||
|
|
||||||
iteratorStack.push(it);
|
CallStackNode node = new CallStackNode(it, null);
|
||||||
|
callStack.push(node);
|
||||||
|
|
||||||
while(it.hasNext()) {
|
while(it.hasNext()) {
|
||||||
executeStatement(it.next());
|
Statement current = it.next();
|
||||||
if (!enoughAP) {
|
node.lastStatement = current;
|
||||||
|
executeStatement(current);
|
||||||
|
if (!enoughAP || breakLoop || breakProcedure) {
|
||||||
|
breakProcedure = false;
|
||||||
break;
|
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) {
|
public void setActionHandler(IActionHandler actionHandler) {
|
||||||
@@ -213,7 +243,18 @@ public class Program {
|
|||||||
this.worm = worm;
|
this.worm = worm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Expression> getVariables() {
|
public Map<String, Object> getVariables() {
|
||||||
return this.varMap;
|
return this.varMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CallStackNode {
|
||||||
|
public Iterator<Statement> statementIterator;
|
||||||
|
public Statement lastStatement;
|
||||||
|
|
||||||
|
public CallStackNode(Iterator<Statement> st, Statement ls) {
|
||||||
|
statementIterator = st;
|
||||||
|
lastStatement = ls;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package worms.model;
|
package worms.model;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import worms.util.IllegalNameException;
|
import worms.util.IllegalNameException;
|
||||||
import worms.util.TeamComparator;
|
import worms.util.TeamComparator;
|
||||||
@@ -82,7 +83,7 @@ public class Team {
|
|||||||
Collection<Worm> worms = getAllWormsOfTeam();
|
Collection<Worm> worms = getAllWormsOfTeam();
|
||||||
|
|
||||||
for (Worm w : worm) {
|
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 (!names.add(w.getName())) return false;
|
||||||
if (worms.contains(w)) return false;
|
if (worms.contains(w)) return false;
|
||||||
if (worms.size() == 0 && !w.isTerminated()) continue;
|
if (worms.size() == 0 && !w.isTerminated()) continue;
|
||||||
@@ -109,9 +110,9 @@ public class Team {
|
|||||||
*/
|
*/
|
||||||
public void removeWormsFromTeam(Worm... worm) throws IllegalArgumentException {
|
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) {
|
for (Worm w: worm) {
|
||||||
if (w == null) throw new IllegalArgumentException();
|
|
||||||
getAllWormsOfTeam().remove(w);
|
getAllWormsOfTeam().remove(w);
|
||||||
w.setTeam(null);
|
w.setTeam(null);
|
||||||
}
|
}
|
||||||
@@ -169,7 +170,8 @@ public class Team {
|
|||||||
*/
|
*/
|
||||||
public static void mergeTeams(Team receivingTeam, Team supplyingTeam) throws IllegalArgumentException {
|
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();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ public class World {
|
|||||||
*/
|
*/
|
||||||
public World(double width, double height, boolean[][] map) {
|
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.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@@ -69,7 +69,7 @@ public class World {
|
|||||||
public void activateNextWorm() throws IllegalStateException {
|
public void activateNextWorm() throws IllegalStateException {
|
||||||
|
|
||||||
if (getWormList().size() == 0) {
|
if (getWormList().size() == 0) {
|
||||||
throw new IllegalStateException("No worms");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.activeWorm++;
|
this.activeWorm++;
|
||||||
@@ -97,6 +97,9 @@ public class World {
|
|||||||
|
|
||||||
Team lastTeam = getWormList().get(0).getTeam();
|
Team lastTeam = getWormList().get(0).getTeam();
|
||||||
for(Worm worm: getWormList()) {
|
for(Worm worm: getWormList()) {
|
||||||
|
if (worm.getTeam() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (!lastTeam.equals(worm.getTeam())) {
|
if (!lastTeam.equals(worm.getTeam())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -228,7 +231,7 @@ public class World {
|
|||||||
|
|
||||||
if (Math.floor(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 true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.map[map.length - 1 - (int) Math.floor(location[1] / lengthY)][(int) Math.floor(location[0] / lengthX)];
|
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 {
|
public void add(GameObject obj) throws IllegalStateException, IllegalArgumentException {
|
||||||
if (hasActiveGame()) throw new IllegalStateException();
|
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)) {
|
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();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
obj.setWorld(this);
|
obj.setWorld(this);
|
||||||
@@ -503,28 +513,9 @@ public class World {
|
|||||||
return getGameObjectsByClass(Food.class);
|
return getGameObjectsByClass(Food.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param cl
|
|
||||||
*
|
|
||||||
* @return ...
|
|
||||||
* |list.add(gameObject) for each gameObject
|
|
||||||
* |result == list (ArrayList<>())
|
|
||||||
*/
|
|
||||||
public List<GameObject> getGameObjectList(Class cl) {
|
|
||||||
List<GameObject> list = new ArrayList<>();
|
|
||||||
for (GameObject x : getGameObjects()) {
|
|
||||||
if (x.getClass().equals(cl)) {
|
|
||||||
list.add(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <T extends GameObject> List<T> getGameObjectsByClass(Class<T> cl) {
|
public <T extends GameObject> List<T> getGameObjectsByClass(Class<T> cl) {
|
||||||
|
return getGameObjects().stream().filter(cl::isInstance).map(cl::cast).collect(Collectors.toList());
|
||||||
return (List<T>) getGameObjects().stream().filter(x -> x.getClass().equals(cl)).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -544,6 +535,7 @@ public class World {
|
|||||||
|
|
||||||
Set<GameObject> gameObjects = getGameObjects();
|
Set<GameObject> gameObjects = getGameObjects();
|
||||||
int size = gameObjects.size();
|
int size = gameObjects.size();
|
||||||
|
if (size < 2) throw new IllegalStateException("Less than 2 objects");
|
||||||
int nb1 = new Random().nextInt(size);
|
int nb1 = new Random().nextInt(size);
|
||||||
int nb2 = new Random().nextInt(size);
|
int nb2 = new Random().nextInt(size);
|
||||||
while (nb2 == nb1) {
|
while (nb2 == nb1) {
|
||||||
|
@@ -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)
|
public Worm(World world, double[] location, double orientation, String name, double radius, double minRadius, Team team)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
super(world, location, radius);
|
super(world, location, radius);
|
||||||
setTeam(team);
|
|
||||||
|
|
||||||
setOrientation(orientation);
|
setOrientation(orientation);
|
||||||
|
|
||||||
@@ -117,7 +116,7 @@ public class Worm extends GameObject {
|
|||||||
throw new IllegalArgumentException("Invalid min radius");
|
throw new IllegalArgumentException("Invalid min radius");
|
||||||
this.minRadius = minRadius;
|
this.minRadius = minRadius;
|
||||||
|
|
||||||
if (this.radius < this.minRadius) throw new IllegalArgumentException("Invalid radius");
|
if (!canHaveAsRadius(radius)) throw new IllegalArgumentException("Invalid radius");
|
||||||
|
|
||||||
setActionPoints(getMaxActionPoints());
|
setActionPoints(getMaxActionPoints());
|
||||||
|
|
||||||
@@ -132,6 +131,7 @@ public class Worm extends GameObject {
|
|||||||
if (team != null) {
|
if (team != null) {
|
||||||
team.addWorm(this);
|
team.addWorm(this);
|
||||||
}
|
}
|
||||||
|
setTeam(team);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===================================================================================
|
//===================================================================================
|
||||||
@@ -168,7 +168,7 @@ public class Worm extends GameObject {
|
|||||||
*/
|
*/
|
||||||
@Raw
|
@Raw
|
||||||
private void setOrientation(double orientation) {
|
private void setOrientation(double orientation) {
|
||||||
assert isValidOrientation(orientation);
|
if (!isValidOrientation(orientation)) throw new IllegalArgumentException();
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ public class Worm extends GameObject {
|
|||||||
*/
|
*/
|
||||||
@Raw
|
@Raw
|
||||||
private boolean canHaveAsRadius(double radius) {
|
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) {
|
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))) {
|
if (name.length() < 2 || !Character.isUpperCase(name.charAt(0))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -473,15 +475,16 @@ public class Worm extends GameObject {
|
|||||||
*/
|
*/
|
||||||
public void move() throws IllegalArgumentException {
|
public void move() throws IllegalArgumentException {
|
||||||
|
|
||||||
|
if (getWorld() == null) throw new IllegalStateException();
|
||||||
|
|
||||||
double newDirection = getFurthestLocationDirection();
|
double newDirection = getFurthestLocationDirection();
|
||||||
Coordinate newLocation = getFurthestLocationInDirection(newDirection, this.getRadius());
|
Coordinate newLocation = getFurthestLocationInDirection(newDirection, this.getRadius());
|
||||||
double distance = getDistance(this.getLocation(), newLocation);
|
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())
|
if (cost > getActionPoints())
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
setLocation(newLocation);
|
setLocation(newLocation);
|
||||||
subtractActionPoints(cost);
|
subtractActionPoints(cost);
|
||||||
}
|
}
|
||||||
@@ -501,6 +504,10 @@ public class Worm extends GameObject {
|
|||||||
double radius = getRadius();
|
double radius = getRadius();
|
||||||
World world = getWorld();
|
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) {
|
if (getWorld() == null) {
|
||||||
return Coordinate.create(currentLocation.getX() + maxDistance * cos(direction), currentLocation.getY() + maxDistance * sin(direction));
|
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;
|
double maxLocDirection = minDirection;
|
||||||
Coordinate maxLoc = location;
|
Coordinate maxLoc = location;
|
||||||
for (; minDirection <= maxDirection; minDirection += 0.0175) {
|
for (; minDirection <= maxDirection; minDirection += 0.0175) {
|
||||||
|
if (minDirection < 0) minDirection = 0.0;
|
||||||
Coordinate tempLoc = getFurthestLocationInDirection(minDirection, this.getRadius());
|
Coordinate tempLoc = getFurthestLocationInDirection(minDirection, this.getRadius());
|
||||||
if (!getWorld().isAdjacent(tempLoc, getRadius())) tempLoc = location;
|
if (!getWorld().isAdjacent(tempLoc, getRadius())) tempLoc = location;
|
||||||
if (getDistance(location, tempLoc) / Math.abs(direction - minDirection) > getDistance(location, maxLoc) / Math.abs(direction - maxLocDirection)) {
|
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);
|
setLocation(newLocation);
|
||||||
setActionPoints(0);
|
setActionPoints(0);
|
||||||
|
|
||||||
checkEat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -740,7 +746,7 @@ public class Worm extends GameObject {
|
|||||||
* |if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0)
|
* |if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0)
|
||||||
*/
|
*/
|
||||||
public Coordinate jumpStep(double deltaTime) {
|
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();
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
double velocity = this.jumpVelocity();
|
double velocity = this.jumpVelocity();
|
||||||
@@ -766,12 +772,14 @@ public class Worm extends GameObject {
|
|||||||
* |result == t
|
* |result == t
|
||||||
*/
|
*/
|
||||||
private double calcJumpTime() {
|
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 t = 0;
|
||||||
double a = getOrientation();
|
double a = getOrientation();
|
||||||
Coordinate loc = getLocation();
|
Coordinate loc = getLocation();
|
||||||
World world = getWorld();
|
|
||||||
double radius = getRadius();
|
double radius = getRadius();
|
||||||
Coordinate newLoc;
|
Coordinate newLoc;
|
||||||
|
|
||||||
@@ -1113,19 +1121,18 @@ public class Worm extends GameObject {
|
|||||||
|
|
||||||
if (terminate) food.terminate();
|
if (terminate) food.terminate();
|
||||||
|
|
||||||
System.out.println(getWorld().isAdjacent(getLocation(), getRadius()));
|
|
||||||
|
|
||||||
double radius = getRadius();
|
double radius = getRadius();
|
||||||
double changeRadius = radius * 0.1;
|
double changeRadius = radius * 0.1;
|
||||||
|
|
||||||
if (food.isPoisonous()) {
|
if (food.isPoisonous()) {
|
||||||
changeRadius *= -1;
|
changeRadius *= -1;
|
||||||
radius *= 0.9;
|
radius *= 0.9;
|
||||||
|
if (radius < getMinRadius()) radius = getMinRadius();
|
||||||
} else {
|
} else {
|
||||||
radius *= 1.1;
|
radius *= 1.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decreaseActionPoints(8);
|
||||||
setRadius(radius);
|
setRadius(radius);
|
||||||
|
|
||||||
World world = getWorld();
|
World world = getWorld();
|
||||||
@@ -1183,7 +1190,7 @@ public class Worm extends GameObject {
|
|||||||
*/
|
*/
|
||||||
public void checkEat() {
|
public void checkEat() {
|
||||||
|
|
||||||
if (!canEat()) throw new IllegalStateException();
|
if (!canEat()) return;
|
||||||
|
|
||||||
World world = getWorld();
|
World world = getWorld();
|
||||||
if (world != null) {
|
if (world != null) {
|
||||||
@@ -1191,6 +1198,7 @@ public class Worm extends GameObject {
|
|||||||
for (Food food : foodList) {
|
for (Food food : foodList) {
|
||||||
if (getDistance(food.getLocation(), this.getLocation()) < this.getRadius() + food.getRadius()) {
|
if (getDistance(food.getLocation(), this.getLocation()) < this.getRadius() + food.getRadius()) {
|
||||||
eat(food);
|
eat(food);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1272,4 +1280,13 @@ public class Worm extends GameObject {
|
|||||||
// ===================================================================================
|
// ===================================================================================
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void terminate() {
|
||||||
|
super.terminate();
|
||||||
|
if (team != null) {
|
||||||
|
team.removeWormsFromTeam(this);
|
||||||
|
setTeam(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
package worms.programs;
|
|
||||||
|
|
||||||
public abstract class ArgumentExpression<R, O> implements Expression<R> {
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@@ -19,10 +19,6 @@ public class BinaryExpression<T, R> implements Expression<R> {
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public R execute(Program program) {
|
public R execute(Program program) {
|
||||||
try {
|
|
||||||
return function.apply(left.execute(program), right.execute(program));
|
return function.apply(left.execute(program), right.execute(program));
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
package worms.programs;
|
package worms.programs;
|
||||||
|
|
||||||
import worms.model.Program;
|
import worms.model.Program;
|
||||||
|
@FunctionalInterface
|
||||||
public interface Expression<R> {
|
public interface Expression<R> {
|
||||||
|
|
||||||
R execute(Program program);
|
R execute(Program program);
|
||||||
|
@@ -8,6 +8,7 @@ import worms.util.MustNotImplementException;
|
|||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ProgramFactory implements IProgramFactory<Expression, Statement, Procedure, Program> {
|
public class ProgramFactory implements IProgramFactory<Expression, Statement, Procedure, Program> {
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +59,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createAssignmentStatement(String variableName, Expression value, SourceLocation sourceLocation) throws ModelException {
|
public Statement createAssignmentStatement(String variableName, Expression value, SourceLocation sourceLocation) throws ModelException {
|
||||||
return new Statement(Statement.Type.ASSIGN, new Statement.Assign(variableName, value));
|
return new Statement<>(Statement.Type.ASSIGN, new Statement.Assign<Object>(variableName, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,7 +71,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createPrintStatement(Expression value, SourceLocation sourceLocation) throws ModelException {
|
public Statement createPrintStatement(Expression value, SourceLocation sourceLocation) throws ModelException {
|
||||||
return new Statement(Statement.Type.PRINT, value);
|
return new Statement<Expression<Object>>(Statement.Type.PRINT, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +83,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createTurnStatement(Expression angle, SourceLocation location) throws ModelException {
|
public Statement createTurnStatement(Expression angle, SourceLocation location) throws ModelException {
|
||||||
return new Statement(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.TURN, angle));
|
return new Statement<>(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.TURN, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,7 +94,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createMoveStatement(SourceLocation location) throws ModelException {
|
public Statement createMoveStatement(SourceLocation location) throws ModelException {
|
||||||
return new Statement(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.MOVE, null));
|
return new Statement<>(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.MOVE, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,7 +104,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createJumpStatement(SourceLocation location) throws ModelException {
|
public Statement createJumpStatement(SourceLocation location) throws ModelException {
|
||||||
return new Statement(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.JUMP, null));
|
return new Statement<>(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.JUMP, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,7 +114,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createEatStatement(SourceLocation location) {
|
public Statement createEatStatement(SourceLocation location) {
|
||||||
return new Statement(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.EAT, null));
|
return new Statement<>(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.EAT, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,7 +125,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createFireStatement(SourceLocation location) throws ModelException {
|
public Statement createFireStatement(SourceLocation location) throws ModelException {
|
||||||
return new Statement(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.FIRE, null));
|
return new Statement<>(Statement.Type.ACTION, new Statement.Action(Statement.Action.Type.FIRE, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +136,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createSequenceStatement(List<Statement> statements, SourceLocation sourceLocation) throws ModelException {
|
public Statement createSequenceStatement(List<Statement> 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<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createIfStatement(Expression condition, Statement ifBody, Statement elseBody, SourceLocation sourceLocation) throws ModelException {
|
public Statement createIfStatement(Expression condition, Statement ifBody, Statement elseBody, SourceLocation sourceLocation) throws ModelException {
|
||||||
return new Statement(Statement.Type.IF, new Statement.If(condition, ifBody, elseBody));
|
return new Statement<>(Statement.Type.IF, new Statement.If<Boolean>(condition, ifBody, elseBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,7 +163,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createWhileStatement(Expression condition, Statement body, SourceLocation sourceLocation) throws ModelException {
|
public Statement createWhileStatement(Expression condition, Statement body, SourceLocation sourceLocation) throws ModelException {
|
||||||
return new Statement(Statement.Type.WHILE, new Statement.While(condition, body));
|
return new Statement<>(Statement.Type.WHILE, new Statement.While<Boolean>(condition, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,7 +173,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createBreakStatement(SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
public Statement createBreakStatement(SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
||||||
return new Statement(Statement.Type.BREAK, null);
|
return new Statement<>(Statement.Type.BREAK, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,7 +184,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Statement createInvokeStatement(String procedureName, SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
public Statement createInvokeStatement(String procedureName, SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
||||||
return new Statement(Statement.Type.INVOKE, procedureName);
|
return new Statement<String>(Statement.Type.INVOKE, procedureName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -195,7 +196,10 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Expression createReadVariableExpression(String variableName, SourceLocation sourceLocation) throws ModelException {
|
public Expression createReadVariableExpression(String variableName, SourceLocation sourceLocation) throws ModelException {
|
||||||
return (Expression<Object>) program -> program.getVariables().get(variableName).execute(program);
|
return (Expression<Object>) 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<Expression, Statement, Pr
|
|||||||
@Override
|
@Override
|
||||||
public Expression createSelfExpression(SourceLocation location) throws ModelException {
|
public Expression createSelfExpression(SourceLocation location) throws ModelException {
|
||||||
|
|
||||||
return new UnaryArgumentExpression<Worm>(w -> w.getWorm());
|
return new UnaryArgumentExpression<Worm>(Program::getWorm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,7 +299,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
@Override
|
@Override
|
||||||
public Expression createEqualityExpression(Expression left, Expression right, SourceLocation location) throws ModelException {
|
public Expression createEqualityExpression(Expression left, Expression right, SourceLocation location) throws ModelException {
|
||||||
|
|
||||||
return new BinaryExpression<Object, Boolean>(left, right, (l, r) -> l.equals(r));
|
return new BinaryExpression<Object, Boolean>(left, right, Objects::equals);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,7 +325,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
.getWorld()
|
.getWorld()
|
||||||
.getGameObjects()
|
.getGameObjects()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(g -> 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())))
|
.min(Comparator.comparingDouble(gameObject -> gameObject.getDistance(p.getWorm())))
|
||||||
.orElse(null));
|
.orElse(null));
|
||||||
}
|
}
|
||||||
@@ -337,7 +341,7 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
@Override
|
@Override
|
||||||
public Expression createSameTeamExpression(Expression entity, SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
public Expression createSameTeamExpression(Expression entity, SourceLocation sourceLocation) throws ModelException, MustNotImplementException {
|
||||||
|
|
||||||
return new BinaryArgumentExpression<Worm, Boolean>(entity, (w, p) -> w.getTeam().equals(p.getWorm().getTeam()));
|
return new BinaryArgumentExpression<Worm, Boolean>(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<Expression, Statement, Pr
|
|||||||
@Override
|
@Override
|
||||||
public Expression createDistanceExpression(Expression entity, SourceLocation sourceLocation) throws ModelException {
|
public Expression createDistanceExpression(Expression entity, SourceLocation sourceLocation) throws ModelException {
|
||||||
|
|
||||||
return new BinaryArgumentExpression<GameObject, Double>(entity, (e, p) -> e.getDistance(p.getWorm()));
|
return new BinaryArgumentExpression<GameObject, Double>(entity, (e, p) -> {
|
||||||
|
if (e == null) throw new IllegalArgumentException();
|
||||||
|
return e.getDistance(p.getWorm());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,6 +370,6 @@ public class ProgramFactory implements IProgramFactory<Expression, Statement, Pr
|
|||||||
@Override
|
@Override
|
||||||
public Expression createIsWormExpression(Expression entity, SourceLocation sourceLocation) throws ModelException {
|
public Expression createIsWormExpression(Expression entity, SourceLocation sourceLocation) throws ModelException {
|
||||||
|
|
||||||
return new UnaryExpression<GameObject, Boolean>(entity, w -> w instanceof Worm);
|
return new UnaryExpression<Object, Boolean>(entity, e -> e instanceof Worm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
package worms.programs;
|
package worms.programs;
|
||||||
|
|
||||||
public class Statement {
|
public class Statement<T> {
|
||||||
|
|
||||||
private final Type type;
|
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.type = type;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ public class Statement {
|
|||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getData() {
|
public T getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,13 +29,13 @@ public class Statement {
|
|||||||
BREAK
|
BREAK
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class If {
|
public static class If<T> {
|
||||||
|
|
||||||
private final Statement ifBody;
|
private final Statement ifBody;
|
||||||
private final Statement elseBody;
|
private final Statement elseBody;
|
||||||
private final Expression condition;
|
private final Expression<T> condition;
|
||||||
|
|
||||||
public If(Expression condition, Statement ifBody, Statement elseBody) {
|
public If(Expression<T> condition, Statement ifBody, Statement elseBody) {
|
||||||
this.ifBody = ifBody;
|
this.ifBody = ifBody;
|
||||||
this.elseBody = elseBody;
|
this.elseBody = elseBody;
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
@@ -49,17 +49,17 @@ public class Statement {
|
|||||||
return elseBody;
|
return elseBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression getCondition() {
|
public Expression<T> getCondition() {
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class While {
|
public static class While<T> {
|
||||||
|
|
||||||
private final Expression condition;
|
private final Expression<T> condition;
|
||||||
private final Statement body;
|
private final Statement body;
|
||||||
|
|
||||||
public While(Expression condition, Statement body) {
|
public While(Expression<T> condition, Statement body) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,7 @@ public class Statement {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression getCondition() {
|
public Expression<T> getCondition() {
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,17 +106,17 @@ public class Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Assign {
|
public static class Assign<T> {
|
||||||
|
|
||||||
private final String variableName;
|
private final String variableName;
|
||||||
private final Expression value;
|
private final Expression<T> value;
|
||||||
|
|
||||||
public Assign(String variableName, Expression value) {
|
public Assign(String variableName, Expression<T> value) {
|
||||||
this.variableName = variableName;
|
this.variableName = variableName;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression getValue() {
|
public Expression<T> getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ import java.util.Comparator;
|
|||||||
public class TeamComparator implements Comparator<Worm> {
|
public class TeamComparator implements Comparator<Worm> {
|
||||||
@Override
|
@Override
|
||||||
public int compare(Worm t1, Worm t2) {
|
public int compare(Worm t1, Worm t2) {
|
||||||
|
if (t1.equals(t2)) return 0;
|
||||||
return t1.getName().compareTo(t2.getName());
|
return t1.getName().compareTo(t2.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -976,7 +976,7 @@ public class Part3_FullFacadeTest {
|
|||||||
@Test
|
@Test
|
||||||
public void createWorm_IllegalWorld() {
|
public void createWorm_IllegalWorld() {
|
||||||
max_score += 2;
|
max_score += 2;
|
||||||
World someWorld = facade.createWorld(10.0, 20.0, map10x10);
|
World someWorld = facade.createWorld(10.0, 10.0, map10x10);
|
||||||
facade.terminate(someWorld);
|
facade.terminate(someWorld);
|
||||||
try {
|
try {
|
||||||
facade.createWorm(someWorld, new double[] { 8.68, 8.68 }, 0.3, 0.3, "Worm", null);
|
facade.createWorm(someWorld, new double[] { 8.68, 8.68 }, 0.3, 0.3, "Worm", null);
|
||||||
|
Reference in New Issue
Block a user