(
+ NB_HISTORY));
+ private boolean moving;
+
+ public ProjectileSprite(PlayGameScreen screen, Projectile projectile) {
+ super(screen);
+ this.projectile = projectile;
+ this.moving = true;
+ }
+
+ @Override
+ public synchronized void draw(Graphics2D g) {
+ if (moving) {
+ for (int i = 0; i < lastLocations.size(); i++) {
+ double[] loc = lastLocations.get(i);
+ g.setColor(colors[i]);
+ double t = (double) (i + 1) / lastLocations.size();
+ double size = sizeInPixels * t * t * t;
+ g.fill(GUIUtils.circleAt(loc[0], loc[1], size));
+ }
+ } else {
+ g.setColor(colors[NB_HISTORY-1]);
+ g.fill(GUIUtils.circleAt(getCenterX(), getCenterY(), sizeInPixels));
+ }
+ }
+
+ @Override
+ public Projectile getObject() {
+ return getProjectile();
+ }
+
+ public Projectile getProjectile() {
+ return projectile;
+ }
+
+ public synchronized void setSize(double sizeInPixels) {
+ this.sizeInPixels = Math.min(MAX_DISPLAY_SIZE,
+ Math.max(MIN_DISPLAY_SIZE, DISPLAY_SCALE * sizeInPixels));
+ }
+
+ @Override
+ public double getHeight(Graphics2D g) {
+ return sizeInPixels;
+ }
+
+ @Override
+ public double getWidth(Graphics2D g) {
+ return sizeInPixels;
+ }
+
+ @Override
+ public boolean isObjectAlive() {
+ return !getFacade().isTerminated(getProjectile());
+ }
+
+ @Override
+ public synchronized void update() {
+ setSize(getScreen().worldToScreenDistance(getFacade().getRadius(getProjectile())));
+ double[] loc = getFacade().getLocation(getProjectile());
+ setCenterLocation(getScreen().getScreenX(loc[0]), getScreen().getScreenY(loc[1]));
+ }
+
+ @Override
+ public synchronized void setCenterLocation(double x, double y) {
+ super.setCenterLocation(x, y);
+ if (moving && !lastLocations.isEmpty()) {
+ // do some averaving to show some intermediate positions for
+ // fast-moving object (rifle projectiles)
+
+ if (lastLocations.size() > 1) {
+ double[] c1 = lastLocations.get(lastLocations.size() - 1);
+ double[] c2 = lastLocations.get(0);
+ lastLocations.add(new double[] { (c1[0] + c2[0]) / 2,
+ (c1[1] + c2[1]) / 2 });
+ }
+ double[] prev = lastLocations.get(lastLocations.size() - 1);
+ lastLocations.remove(prev);
+
+ for (int i = 0; i < NB_HISTORY; i++) {
+ if (prev != null) {
+ double t = (double) i / (NB_HISTORY);
+ lastLocations.add(new double[] { t * x + (1 - t) * prev[0],
+ t * y + (1 - t) * prev[1] });
+ }
+ }
+ }
+ lastLocations.add(new double[] { x, y });
+ }
+
+ public synchronized void setDoneMoving() {
+ this.moving = false;
+ }
+}
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/WormSprite.java b/OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/WormSprite.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/menu/AbstractMenuScreen.java b/OGP1718-Worms/src-provided/worms/internal/gui/menu/AbstractMenuScreen.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/menu/ChooseLevelScreen.java b/OGP1718-Worms/src-provided/worms/internal/gui/menu/ChooseLevelScreen.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/menu/MainMenuScreen.java b/OGP1718-Worms/src-provided/worms/internal/gui/menu/MainMenuScreen.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/menu/MenuInputMode.java b/OGP1718-Worms/src-provided/worms/internal/gui/menu/MenuInputMode.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/messages/Message.java b/OGP1718-Worms/src-provided/worms/internal/gui/messages/Message.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageDisplay.java b/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageDisplay.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessagePainter.java b/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessagePainter.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageType.java b/OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageType.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/programs/IProgramFactory.java b/OGP1718-Worms/src-provided/worms/programs/IProgramFactory.java
new file mode 100755
index 0000000..c2b4acf
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/IProgramFactory.java
@@ -0,0 +1,443 @@
+package worms.programs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import worms.util.ModelException;
+import worms.util.MustNotImplementException;
+
+/**
+ * A program factory is used by the parser ({@link ProgramParser}) to construct
+ * an in-memory representation of your program. For example, when reading the
+ * program source code
+ *
+ *
+ * print 2.0
+ *
+ *
+ * the parser will create a Program object by (conceptually) executing the
+ * following code:
+ *
+ *
+ * factory.createProgram(Collections.emptyList(),
+ * factory.createPrintStatement(factory.createDoubleLiteral(2.0)));
+ *
+ *
+ * on the returned factory object.
+ *
+ *
+ * For testing, you may use the methods from {@link ProgramParser} yourself.
+ *
+ *
+ *
+ * You should declare your class as follows:
+ * public class ProgramFactory implements IProgramFactory<MyExpression, MyStatement, MyProc, Program>
+ *
where MyExpression, MyStatement, MyProc, and Program are your classes
+ * for representing expressions, statements, procedure definitions, and programs,
+ * respectively.
+ *
+ *
+ * The SourceLocation object in the methods defined by this factory refers to
+ * the location (line and column) in the text file where the statement or
+ * expression begins.
+ *
+ * @param
+ * Your class for representing an expression.
+ * @param
+ * Your class for representing a statement.
+ * @param
+ * Your class for representing a procedure.
+ * @param
+ * Your class for representing a program (should be Program).
+ *
+ *
+ */
+public interface IProgramFactory {
+
+ /* PROGRAM */
+
+ /**
+ * Create a program from the given arguments.
+ *
+ * @param procs
+ * The procedure definitions for the program.
+ * @param main
+ * The main statement of the program. Most likely this is a
+ * sequence statement.
+ * @return A new program.
+ */
+ public Program createProgram(List procs, S main) throws ModelException;
+
+ /**
+ * Create a program from the given argument.
+ *
+ * @param main
+ * The main statement of the program. Most likely this is a
+ * sequence statement.
+ * @return A new program without procedure definitions.
+ */
+ public default Program createProgram(S main) throws ModelException {
+ return createProgram(new ArrayList
(), main);
+ }
+
+ /* PROCEDURE DEFINITIONS */
+
+ /**
+ * Create a procedure definition with the given name and body.
+ *
+ * @param procedureName
+ * The name of the procedure
+ * @param body
+ * The body of the procedure.
+ */
+ public P createProcedureDefinition(String procedureName, S body, SourceLocation sourceLocation);
+
+ /* STATEMENTS */
+
+ /**
+ * Create a statement that assigns the value obtained by evaluating the
+ * given expression to a variable with the given name.
+ */
+ public S createAssignmentStatement(String variableName, E value, SourceLocation sourceLocation)
+ throws ModelException;
+
+ /**
+ * Create a print statement that prints the value obtained by evaluating the
+ * given expression.
+ */
+ public S createPrintStatement(E value, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Create a turn statement that makes the worm that is executing the program
+ * turn by the amount obtained by evaluating the given expression.
+ */
+ public S createTurnStatement(E angle, SourceLocation location) throws ModelException;
+
+ /**
+ * Create a statement that makes the worm that is executing the program move
+ * one step.
+ */
+ public S createMoveStatement(SourceLocation location) throws ModelException;
+
+ /**
+ * Returns a statement that makes the worm that is executing the program jump.
+ */
+ public S createJumpStatement(SourceLocation location) throws ModelException;
+
+ /**
+ * Returns a statement that makes the worm that is executing the program eat.
+ */
+ public S createEatStatement(SourceLocation location);
+
+ /**
+ * Returns a statement that makes the worm that is executing the program fire
+ * a weapon.
+ */
+ public S createFireStatement(SourceLocation location) throws ModelException;
+
+ /**
+ * Create a sequence of statements involving the given list of statements.
+ */
+ public S createSequenceStatement(List statements, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Create an if-then-else statement involving the given condition and the
+ * given then-part and else-part.
+ * The else-part may be null.
+ */
+ public S createIfStatement(E condition, S ifBody, S elseBody, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Create a while statement involving the given condition and given body.
+ */
+ public S createWhileStatement(E condition, S body, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Create a break statement.
+ */
+ public default S createBreakStatement(SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ // Individual students must not work out this method.
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Create an invoke statement that invokes the procedure with the given name.
+ */
+ public default S createInvokeStatement(String procedureName, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ // Individual students must not work out this method.
+ throw new MustNotImplementException();
+ }
+
+ /* EXPRESSIONS */
+
+ /**
+ * Create an expression that evaluates to the current value of the given
+ * variable.
+ */
+ public E createReadVariableExpression(String variableName, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Creates an expression that represents a literal double value.
+ */
+ public E createDoubleLiteralExpression(double value, SourceLocation location) throws ModelException;
+
+ /**
+ * Creates an expression that represents a literal boolean value.
+ */
+ public E createBooleanLiteralExpression(boolean value, SourceLocation location) throws ModelException;
+
+ /**
+ * Creates an expression that represents the null value.
+ */
+ public E createNullExpression(SourceLocation location) throws ModelException;
+
+ /**
+ * Creates an expression that represents the self value, evaluating to the
+ * worm that executes the program.
+ */
+ public E createSelfExpression(SourceLocation location) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to the addition of the values
+ * obtained by evaluating the given left and second expressions.
+ */
+ public E createAdditionExpression(E left, E right, SourceLocation location) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to the subtraction of the values
+ * obtained by evaluating the first and second given expressions.
+ */
+ public default E createSubtractionExpression(E left, E right, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the multiplication of the values
+ * obtained by evaluating the first and second given expressions.
+ */
+ public default E createMultiplicationExpression(E left, E right, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the division of the values
+ * obtained by evaluating the first and second given expressions.
+ */
+ public default E createDivisionExpression(E left, E right, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the square root of the value
+ * obtained by evaluating the given expression.
+ */
+ public default E createSqrtExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the sine of the value
+ * obtained by evaluating the given expression.
+ */
+ public default E createSinExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the cosine of the value
+ * obtained by evaluating the given expression.
+ */
+ public default E createCosExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the conjunction of the values
+ * obtained by evaluating the given left and right expressions.
+ */
+ public E createAndExpression(E left, E right, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to the disjunction of the values
+ * obtained by evaluating the given left and right expressions.
+ */
+ public default E createOrExpression(E left, E right, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to true when the given expression
+ * evaluates to false, and vice versa.
+ */
+ public E createNotExpression(E expression, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is equal to the value obtained by
+ * evaluating the right expression.
+ */
+ public E createEqualityExpression(E left, E right, SourceLocation location) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is different from the value obtained by
+ * evaluating the right expression.
+ */
+ public default E createInequalityExpression(E left, E right, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is less than the value obtained by
+ * evaluating the right expression.
+ */
+ public E createLessThanExpression(E left, E right, SourceLocation location);
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is less than or equal to the value obtained by
+ * evaluating the right expression.
+ */
+ public default E createLessThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is greater than the value obtained by
+ * evaluating the right expression.
+ */
+ public default E createGreaterThanExpression(E left, E right, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to true if the evaluation of the
+ * left expression yields a value that is greater than or equal to the value obtained by
+ * evaluating the right expression.
+ */
+ public default E createGreaterThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the position along the x-axis of
+ * the game object to which the given expression evaluates.
+ */
+ public default E createGetXExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the position along the y-axis of
+ * the game object to which the given expression evaluates.
+ */
+ public default E createGetYExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the radius of the game object to which
+ * the given expression evaluates.
+ */
+ public default E createGetRadiusExpression(E e, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the direction of the game object to which
+ * the given expression evaluates.
+ */
+ public default E createGetDirectionExpression(E entity, SourceLocation location)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the number of action points of the worm to which
+ * the given expression evaluates.
+ */
+ public default E createGetActionPointsExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the maximum number of action points of the worm to which
+ * the given expression evaluates.
+ */
+ public default E createGetMaxActionPointsExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the number of hit points of the game object to which
+ * the given expression evaluates.
+ */
+ public default E createHitPointsExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ public E createSearchObjectExpression(E angleDelta, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Returns an expression that evaluates to a boolean reflecting whether or not
+ * the executing worm belongs to the same team as the worm to which the given
+ * expression evaluates.
+ */
+ public default E createSameTeamExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ // Individual students must not work out this method.
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns an expression that evaluates to the distance between the executing worm
+ * and the game object to which the given expression evaluates.
+ */
+ public E createDistanceExpression(E entity, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Returns a boolean indicating whether or not the object to which the given
+ * expression evaluates is a worm.
+ */
+ public E createIsWormExpression(E entity, SourceLocation sourceLocation) throws ModelException;
+
+ /**
+ * Returns a boolean indicating whether or not the object to which the given
+ * expression evaluates is a portion of food.
+ */
+ public default E createIsFoodExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+ /**
+ * Returns a boolean indicating whether or not the object to which the given
+ * expression evaluates is a projectile.
+ */
+ public default E createIsProjectileExpression(E entity, SourceLocation sourceLocation)
+ throws ModelException, MustNotImplementException {
+ throw new MustNotImplementException();
+ }
+
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/ParseOutcome.java b/OGP1718-Worms/src-provided/worms/programs/ParseOutcome.java
new file mode 100755
index 0000000..ec6d287
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/ParseOutcome.java
@@ -0,0 +1,20 @@
+package worms.programs;
+
+import java.util.List;
+
+import worms.programs.SuccessOrFail.WrappedSuccessOrFail;
+
+public class ParseOutcome
extends WrappedSuccessOrFail
> {
+
+ private ParseOutcome(SuccessOrFail
> outcome) {
+ super(outcome);
+ }
+
+ public static
ParseOutcome
success(P p) {
+ return new ParseOutcome<>(DefaultSuccessOrFail.success(p));
+ }
+
+ public static
ParseOutcome
failure(List errors) {
+ return new ParseOutcome<>(DefaultSuccessOrFail.failure(errors));
+ }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/ProgramParser.java b/OGP1718-Worms/src-provided/worms/programs/ProgramParser.java
new file mode 100755
index 0000000..877b01c
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/ProgramParser.java
@@ -0,0 +1,245 @@
+package worms.programs;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+
+import worms.programs.IProgramFactory;
+import worms.programs.internal.parser.ParserVisitor;
+import worms.programs.internal.parser.generated.WormsProgramLexer;
+import worms.programs.internal.parser.generated.WormsProgramParser;
+import worms.internal.gui.GUIUtils;
+import worms.model.Program;
+
+/**
+ * Parser for Worms programs.
+ *
+ * To use this class, first create an implementation of {@link IProgramFactory}:
+ *
+ *
+ *
+ * IProgramFactory<MyExpression, MyStatement, MyProcedure, Program> factory = new ProgramFactory();
+ *
+ *
+ *
+ * The easiest way to use this class for parsing a Program given as a String is
+ * via the {@link #parseProgramFromString(String, IProgramFactory)} method:
+ *
+ *
+ *
+ * Program program = ProgramParser.parseProgram(text, factory);
+ *
+ *
+ *
+ * For more control, create an instance of this class:
+ *
+ *
+ *
+ * ProgramParser<MyExpression, MyStatement, Task> parser = new ProgramParser<>(factory);
+ *
+ *
+ *
+ * Finally, parse a string or file:
+ * ParseOurcome<Program> parseResult = parser.parse(textToParse);
+ *
+ *
+ * If parsing is successful, parseResult.isSuccess()
returns true
+ * and parseResult.getSuccessValue()
returns the created program.
+ *
+ * If parsing was not successful, parseResult.ifSuccess()
returns
+ * false and parseResult.getFailValue()
returns the list of errors
+ * during parsing.
+ *
+ *
+ * @param E
+ * The type of expressions
+ * @param S
+ * The type of statements
+ * @param P
+ * The type of procedures
+ * @param Prg
+ * The type of program that is created; should be your
+ * worms.model.Program class
+ */
+public class ProgramParser {
+
+ private final IProgramFactory factory;
+
+ private final List errors = new ArrayList<>();
+
+ protected ProgramParser(IProgramFactory factory) {
+ if (factory == null) {
+ throw new NullPointerException("Factory must be effective.");
+ }
+ this.factory = factory;
+ }
+
+ public IProgramFactory getFactory() {
+ return factory;
+ }
+
+ /**
+ * Returns the program that results from parsing the given string, or
+ * Optional.empty() if parsing has failed.
+ *
+ * When parsing has failed, the error messages can be retrieved with the
+ * getErrors() method.
+ *
+ */
+ public ParseOutcome parseString(String string) {
+ return parse(CharStreams.fromString(string));
+ }
+
+ /**
+ * Returns the program that results from parsing the file with the given name,
+ * or Optional.empty() if parsing has failed.
+ *
+ * When parsing has failed, the error messages can be retrieved with the
+ * getErrors() method.
+ */
+ public ParseOutcome parseFile(String filename) throws IOException {
+ return parse(CharStreams.fromStream(GUIUtils.openResource(filename)));
+ }
+
+ /**
+ * Returns the program that results from parsing the file with the given URL, or
+ * Optional.empty() if parsing has failed.
+ *
+ * When parsing has failed, the error messages can be retrieved with the
+ * getErrors() method.
+ */
+ public ParseOutcome parseFile(URL url) throws IOException {
+ return parse(CharStreams.fromStream(GUIUtils.openResource(url)));
+ }
+
+ /**
+ * Returns the program that results from parsing the given CharStream, or
+ * Optional.empty() if parsing has failed.
+ *
+ * When parsing has failed, the error messages can be retrieved with the
+ * getErrors() method.
+ *
+ * @note For more convenient methods, see the
+ * {@link #parseProgramFromString(String, ITaskFactory, List)},
+ * {@link #parseProgramFromFile(String, ITaskFactory, List)},
+ * {@link #parseString(String, List)} and {@link #parseFile(String, List)}
+ * methods.
+ */
+ protected ParseOutcome parse(CharStream input) {
+ reset();
+
+ WormsProgramLexer lexer = new WormsProgramLexer(input);
+ WormsProgramParser parser = new WormsProgramParser(new CommonTokenStream(lexer));
+ parser.addErrorListener(new BaseErrorListener() {
+ @Override
+ public void syntaxError(Recognizer, ?> recognizer, Object offendingSymbol, int line,
+ int charPositionInLine, String msg, RecognitionException e) {
+ errors.add(msg + " (" + line + ", " + charPositionInLine + ")");
+ }
+ });
+ ParserVisitor visitor = new ParserVisitor<>(factory);
+ try {
+ visitor.visitProgram(parser.program());
+ if (errors.isEmpty()) {
+ assert visitor.getMain() != null;
+ Prg program = factory.createProgram(visitor.getProcedures(), visitor.getMain());
+ if (program != null) {
+ return ParseOutcome.success(program);
+ }
+ errors.add("Factory did not return a Program object");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors.add(e.toString());
+ }
+ return ParseOutcome.failure(errors);
+ }
+
+ protected void reset() {
+ this.errors.clear();
+ }
+
+ public List getErrors() {
+ return Collections.unmodifiableList(errors);
+ }
+
+ /**
+ * Create a new parser from the given factory.
+ *
+ * @param factory
+ * @return
+ */
+ public static ProgramParser create(IProgramFactory factory) {
+ return new ProgramParser<>(factory);
+ }
+
+ /**
+ * Parse program text using the given factory.
+ *
+ * @param text
+ * The text to parse
+ * @param factory
+ * The factory to use
+ * @return The parsed program, if any, or null if an error occurred during
+ * parsing.
+ */
+ public static Program parseProgramFromString(String text, IProgramFactory, ?, ?, ? extends Program> factory) {
+ ProgramParser, ?, ?, ? extends Program> parser = create(factory);
+ ParseOutcome extends Program> outcome = parser.parseString(text);
+ if (outcome.isFail()) {
+ System.out.println("Parsing failed: " + outcome.getFailValue());
+ return null;
+ }
+ return outcome.getSuccessValue();
+ }
+
+ /**
+ * Parse program from a file using the given factory.
+ *
+ * @param filename
+ * The filename from which to read the program text
+ * @param factory
+ * The factory to use
+ * @return The parsed program, if any, or null if an error occurred during
+ * parsing.
+ */
+ public static Program parseProgramFromFile(String filename, IProgramFactory, ?, ?, ? extends Program> factory)
+ throws IOException {
+ ProgramParser, ?, ?, ? extends Program> parser = create(factory);
+ ParseOutcome extends Program> outcome = parser.parseFile(filename);
+ if (outcome.isFail()) {
+ System.out.println("Parsing failed: " + outcome.getFailValue());
+ return null;
+ }
+ return outcome.getSuccessValue();
+ }
+
+ /**
+ * Parse program from a file using the given factory.
+ *
+ * @param filename
+ * The filename from which to read the program text
+ * @param factory
+ * The factory to use
+ * @return The parsed program, if any, or null if an error occurred during
+ * parsing.
+ */
+ public static Program parseProgramFromURL(URL url, IProgramFactory, ?, ?, Program> factory) throws IOException {
+ ProgramParser, ?, ?, Program> parser = create(factory);
+ ParseOutcome outcome = parser.parseFile(url);
+ if (outcome.isFail()) {
+ System.out.println("Parsing failed: " + outcome.getFailValue());
+ return null;
+ }
+ return outcome.getSuccessValue();
+ }
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/SourceLocation.java b/OGP1718-Worms/src-provided/worms/programs/SourceLocation.java
new file mode 100755
index 0000000..9ab882f
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/SourceLocation.java
@@ -0,0 +1,61 @@
+package worms.programs;
+
+import be.kuleuven.cs.som.annotate.Value;
+
+/**
+ * A source location represents a position in a source file,
+ * denoted by the line and column (position in the line) of
+ * a certain character in the file.
+ *
+ * This class is a value class.
+ */
+@Value
+public final class SourceLocation {
+
+ private final int line;
+ private final int column;
+
+ public SourceLocation(int line, int column) {
+ this.line = line;
+ this.column = column;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + column;
+ result = prime * result + line;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ SourceLocation other = (SourceLocation) obj;
+ if (column != other.column)
+ return false;
+ if (line != other.line)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("@%d,%d", line, column);
+ }
+
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/SuccessOrFail.java b/OGP1718-Worms/src-provided/worms/programs/SuccessOrFail.java
new file mode 100755
index 0000000..211b391
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/SuccessOrFail.java
@@ -0,0 +1,100 @@
+package worms.programs;
+
+/**
+ * An interface that holds either a success value of type S or a failure value of type F.
+ */
+public interface SuccessOrFail {
+
+ public boolean isSuccess();
+
+ public S getSuccessValue();
+
+ public F getFailValue();
+
+ public default boolean isFail() {
+ return !isSuccess();
+ }
+
+ public static class DefaultSuccessOrFail implements SuccessOrFail {
+ private final boolean success;
+ private final F failValue;
+ private final S successValue;
+
+ private DefaultSuccessOrFail(boolean success, S successValue, F failValue) {
+ if (success && failValue != null) {
+ throw new IllegalArgumentException();
+ }
+ if (!success && successValue != null) {
+ throw new IllegalArgumentException();
+ }
+ this.success = success;
+ this.successValue = successValue;
+ this.failValue = failValue;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return success;
+ }
+
+ @Override
+ public F getFailValue() {
+ return failValue;
+ }
+
+ @Override
+ public S getSuccessValue() {
+ return successValue;
+ }
+
+ public static SuccessOrFail success(S successValue) {
+ return new DefaultSuccessOrFail<>(true, successValue, null);
+ }
+
+ public static SuccessOrFail failure(F failValue) {
+ return new DefaultSuccessOrFail<>(false, null, failValue);
+ }
+
+ @Override
+ public String toString() {
+ if (isSuccess()) {
+ return "SUCCESS value: " + getSuccessValue();
+ } else {
+ return "FAIL value: " + getFailValue();
+ }
+ }
+
+ }
+
+ public static class WrappedSuccessOrFail implements SuccessOrFail {
+ private final SuccessOrFail wrapped;
+
+ protected WrappedSuccessOrFail(SuccessOrFail wrapped) {
+ if (wrapped == null) {
+ throw new NullPointerException();
+ }
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public boolean isSuccess() {
+ return wrapped.isSuccess();
+ }
+
+ @Override
+ public S getSuccessValue() {
+ return wrapped.getSuccessValue();
+ }
+
+ @Override
+ public F getFailValue() {
+ return wrapped.getFailValue();
+ }
+
+ @Override
+ public String toString() {
+ return wrapped.toString();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/ParserVisitor.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/ParserVisitor.java
new file mode 100755
index 0000000..55fc02c
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/ParserVisitor.java
@@ -0,0 +1,392 @@
+package worms.programs.internal.parser;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.Token;
+
+import worms.programs.IProgramFactory;
+import worms.programs.SourceLocation;
+import worms.programs.internal.parser.generated.WormsProgramBaseVisitor;
+import worms.programs.internal.parser.generated.WormsProgramLexer;
+import worms.programs.internal.parser.generated.WormsProgramParser.AddSubExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.AndOrExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.AssignmentStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.BreakStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ComparisonExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ConstantExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.CosExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.DistanceExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.EatActionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.FalseLiteralExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.FireActionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetAPExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetDirectionExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetHPExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetMaxAPExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetRadiusExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetXExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.GetYExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.IfStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.InvokeStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.IsFoodExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.IsProjectileExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.IsWormExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.JumpActionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.MoveActionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.MulDivExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.NotExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.NullExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ParenExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.PrintStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ProceduredefContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ProgramContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.ReadVariableExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SameTeamExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SearchObjExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SelfExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SequenceStatementContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SinExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.SqrtExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.TrueLiteralExpressionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.TurnActionContext;
+import worms.programs.internal.parser.generated.WormsProgramParser.WhileStatementContext;
+
+public class ParserVisitor extends WormsProgramBaseVisitor {
+
+ @Override
+ public Void visitProgram(ProgramContext ctx) {
+ procedures = ctx.procdef.stream().map(procdef -> procDefVisitor.visit(procdef)).collect(Collectors.toList());
+ List mainStmts = ctx.programBody.stream().map(stmt -> statementVisitor.visit(stmt))
+ .collect(Collectors.toList());
+ if (mainStmts.size() == 1) {
+ main = mainStmts.get(0);
+ } else {
+ main = factory.createSequenceStatement(mainStmts, toSourceLocation(ctx));
+ }
+ assert main != null;
+ return null;
+ }
+
+ private class ProcedureDefinitionVisitor extends WormsProgramBaseVisitor {
+
+ @Override
+ public P visitProceduredef(ProceduredefContext ctx) {
+ return getFactory().createProcedureDefinition(ctx.procname.getText(), statementVisitor.visit(ctx.body),
+ toSourceLocation(ctx));
+ }
+ }
+
+ private class StatementVisitor extends WormsProgramBaseVisitor {
+
+ @Override
+ public S visitAssignmentStatement(AssignmentStatementContext ctx) {
+ return getFactory().createAssignmentStatement(ctx.variableName.getText(),
+ expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitWhileStatement(WhileStatementContext ctx) {
+ return getFactory().createWhileStatement(expressionVisitor.visit(ctx.condition),
+ statementVisitor.visit(ctx.body), toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitIfStatement(IfStatementContext ctx) {
+ S ifBody = statementVisitor.visit(ctx.ifbody);
+ S elseBody = null;
+ if (ctx.elsebody != null)
+ elseBody = statementVisitor.visit(ctx.elsebody);
+ return getFactory().createIfStatement(expressionVisitor.visit(ctx.condition), ifBody, elseBody,
+ toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitPrintStatement(PrintStatementContext ctx) {
+ return getFactory().createPrintStatement(expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitSequenceStatement(SequenceStatementContext ctx) {
+ if (ctx.stmts.size() != 1) {
+ return getFactory().createSequenceStatement(
+ ctx.stmts.stream().map(this::visit).collect(Collectors.toList()), toSourceLocation(ctx));
+ } else {
+ return visit(ctx.stmts.get(0));
+ }
+ }
+
+ @Override
+ public S visitInvokeStatement(InvokeStatementContext ctx) {
+ return getFactory().createInvokeStatement(ctx.procName.getText(), toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitBreakStatement(BreakStatementContext ctx) {
+ return getFactory().createBreakStatement(toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitTurnAction(TurnActionContext ctx) {
+ return getFactory().createTurnStatement(expressionVisitor.visit(ctx.angle), toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitMoveAction(MoveActionContext ctx) {
+ return getFactory().createMoveStatement(toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitJumpAction(JumpActionContext ctx) {
+ return getFactory().createJumpStatement(toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitEatAction(EatActionContext ctx) {
+ return getFactory().createEatStatement(toSourceLocation(ctx));
+ }
+
+ @Override
+ public S visitFireAction(FireActionContext ctx) {
+ return getFactory().createFireStatement(toSourceLocation(ctx));
+ }
+
+ }
+
+ private class ExpressionVisitor extends WormsProgramBaseVisitor {
+
+ @Override
+ public E visitReadVariableExpression(ReadVariableExpressionContext ctx) {
+ return getFactory().createReadVariableExpression(ctx.variable.getText(), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitConstantExpression(ConstantExpressionContext ctx) {
+ return getFactory().createDoubleLiteralExpression(Double.parseDouble(ctx.value.getText()),
+ toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitTrueLiteralExpression(TrueLiteralExpressionContext ctx) {
+ return getFactory().createBooleanLiteralExpression(true, toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitFalseLiteralExpression(FalseLiteralExpressionContext ctx) {
+ return getFactory().createBooleanLiteralExpression(false, toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitNullExpression(NullExpressionContext ctx) {
+ return getFactory().createNullExpression(toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitSelfExpression(SelfExpressionContext ctx) {
+ return getFactory().createSelfExpression(toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitParenExpression(ParenExpressionContext ctx) {
+ return expressionVisitor.visit(ctx.subExpr);
+ }
+
+ @Override
+ public E visitAddSubExpression(AddSubExpressionContext ctx) {
+ switch (ctx.op.getType()) {
+ case WormsProgramLexer.ADD:
+ return getFactory().createAdditionExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.SUB:
+ return getFactory().createSubtractionExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ default:
+ throw new IllegalArgumentException("Unknown operator: " + ctx.op);
+ }
+ }
+
+ @Override
+ public E visitMulDivExpression(MulDivExpressionContext ctx) {
+ switch (ctx.op.getType()) {
+ case WormsProgramLexer.MUL:
+ return getFactory().createMultiplicationExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.DIV:
+ return getFactory().createDivisionExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ default:
+ throw new IllegalArgumentException("Unknown operator: " + ctx.op);
+ }
+ }
+
+ @Override
+ public E visitSqrtExpression(SqrtExpressionContext ctx) {
+ return getFactory().createSqrtExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitSinExpression(SinExpressionContext ctx) {
+ return getFactory().createSinExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitCosExpression(CosExpressionContext ctx) {
+ return getFactory().createCosExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitAndOrExpression(AndOrExpressionContext ctx) {
+ switch (ctx.op.getType()) {
+ case WormsProgramLexer.AND:
+ return getFactory().createAndExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.OR:
+ return getFactory().createOrExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ default:
+ throw new IllegalArgumentException("Unknown operator: " + ctx.op);
+ }
+ }
+
+ @Override
+ public E visitNotExpression(NotExpressionContext ctx) {
+ return getFactory().createNotExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitComparisonExpression(ComparisonExpressionContext ctx) {
+ switch (ctx.op.getType()) {
+ case WormsProgramLexer.LT:
+ return getFactory().createLessThanExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.LTE:
+ return getFactory().createLessThanOrEqualExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.GT:
+ return getFactory().createGreaterThanExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.GTE:
+ return getFactory().createGreaterThanOrEqualExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.EQ:
+ return getFactory().createEqualityExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ case WormsProgramLexer.NEQ:
+ return getFactory().createInequalityExpression(expressionVisitor.visit(ctx.left),
+ expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
+ default:
+ throw new IllegalArgumentException("Unknown operand: " + ctx.op);
+ }
+
+ }
+
+ @Override
+ public E visitGetXExpression(GetXExpressionContext ctx) {
+ return getFactory().createGetXExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetYExpression(GetYExpressionContext ctx) {
+ return getFactory().createGetYExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetRadiusExpression(GetRadiusExpressionContext ctx) {
+ return getFactory().createGetRadiusExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetDirectionExpression(GetDirectionExpressionContext ctx) {
+ return getFactory().createGetDirectionExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetAPExpression(GetAPExpressionContext ctx) {
+ return getFactory().createGetActionPointsExpression(expressionVisitor.visit(ctx.expr),
+ toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetMaxAPExpression(GetMaxAPExpressionContext ctx) {
+ return getFactory().createGetMaxActionPointsExpression(expressionVisitor.visit(ctx.expr),
+ toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitGetHPExpression(GetHPExpressionContext ctx) {
+ return getFactory().createHitPointsExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitSameTeamExpression(SameTeamExpressionContext ctx) {
+ return getFactory().createSameTeamExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitSearchObjExpression(SearchObjExpressionContext ctx) {
+ return getFactory().createSearchObjectExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitDistanceExpression(DistanceExpressionContext ctx) {
+ return getFactory().createDistanceExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitIsWormExpression(IsWormExpressionContext ctx) {
+ return getFactory().createIsWormExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitIsFoodExpression(IsFoodExpressionContext ctx) {
+ return getFactory().createIsFoodExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ @Override
+ public E visitIsProjectileExpression(IsProjectileExpressionContext ctx) {
+ return getFactory().createIsProjectileExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
+ }
+
+ }
+
+ private final IProgramFactory factory;
+
+ private final ProcedureDefinitionVisitor procDefVisitor = new ProcedureDefinitionVisitor();
+ private final StatementVisitor statementVisitor = new StatementVisitor();
+ private final ExpressionVisitor expressionVisitor = new ExpressionVisitor();
+
+ private S main;
+ private List procedures;
+
+ public ParserVisitor(IProgramFactory factory) {
+ if (factory == null) {
+ throw new NullPointerException();
+ }
+ this.factory = factory;
+ }
+
+ private SourceLocation toSourceLocation(ParserRuleContext ctx) {
+ int line = ctx.getStart().getLine();
+ int column = ctx.getStart().getCharPositionInLine();
+ return new SourceLocation(line, column);
+ }
+
+ public IProgramFactory getFactory() {
+ return factory;
+ }
+
+ public int toInt(Token z) {
+ return Integer.parseInt(z.getText());
+ }
+
+ public S getMain() {
+ return main;
+ }
+
+ public List getProcedures() {
+ return Collections.unmodifiableList(procedures);
+ }
+
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/WormsProgram.g4 b/OGP1718-Worms/src-provided/worms/programs/internal/parser/WormsProgram.g4
new file mode 100755
index 0000000..4ceae35
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/WormsProgram.g4
@@ -0,0 +1,200 @@
+// ANTLR v4 Grammar for controling Worms.
+// Check the tutorial at http://jnb.ociweb.com/jnb/jnbJun2008.html
+// or http://www.antlr.org/ for details.
+
+
+grammar WormsProgram;
+
+@header {
+ package worms.programs.internal.parser.generated;
+}
+
+
+// ------------------------------------------------------------------------
+// --- Eval and Related Definitions ---------------------------------------
+// ------------------------------------------------------------------------
+program: (procdef+=proceduredef)*
+ (programBody+=statement)*
+;
+
+proceduredef: DEF procname=IDENTIFIER COLON?
+ body=statement
+;
+
+statement: assignmentStatement
+ | whileStatement
+ | ifStatement
+ | printStatement
+ | sequenceStatement
+ | invokeStatement
+ | breakStatement
+ | actionStatement
+;
+
+assignmentStatement: variableName=IDENTIFIER ASSIGN value=expression ';'
+;
+
+whileStatement: WHILE condition=expression COLON?
+ body=statement
+;
+
+ifStatement: IF condition=expression COLON?
+ ifbody=statement
+ (ELSE COLON?
+ elsebody=statement)?
+;
+
+printStatement: PRINT value=expression ';'
+;
+
+sequenceStatement: LEFT_BRACE (stmts+=statement)* RIGHT_BRACE
+;
+
+invokeStatement: INVOKE procName=IDENTIFIER ';'
+;
+
+
+breakStatement: BREAK ';'
+;
+
+
+actionStatement: TURN angle=expression ';' #turnAction
+ | MOVE ';' #moveAction
+ | JUMP ';' #jumpAction
+ | EAT ';' #eatAction
+ | FIRE ';' #fireAction
+;
+
+// order here sets order of operations (important for left-recursive expressions!)
+expression: variable=IDENTIFIER #readVariableExpression
+ | value=NUMBER #constantExpression
+ | TRUE #trueLiteralExpression
+ | FALSE #falseLiteralExpression
+ | NULL #nullExpression
+ | SELF #selfExpression
+ | LEFT_PAREN subExpr=expression RIGHT_PAREN #parenExpression
+ | left=expression op=(MUL | DIV) right=expression #mulDivExpression
+ | left=expression op=(ADD | SUB) right=expression #addSubExpression
+ | left=expression op=(LT | LTE | GT | GTE | EQ | NEQ) right=expression #comparisonExpression
+ | left=expression op=(AND | OR) right=expression #andOrExpression
+ | SQRT LEFT_PAREN expr=expression RIGHT_PAREN #sqrtExpression
+ | SIN LEFT_PAREN expr=expression RIGHT_PAREN #sinExpression
+ | COS LEFT_PAREN expr=expression RIGHT_PAREN #cosExpression
+ | NOT expr=expression #notExpression
+ | GETX expr=expression #getXExpression
+ | GETY expr=expression #getYExpression
+ | GETRADIUS expr=expression #getRadiusExpression
+ | GETDIR expr=expression #getDirectionExpression
+ | GETAP expr=expression #getAPExpression
+ | GETMAXAP expr=expression #getMaxAPExpression
+ | GETHP expr=expression #getHPExpression
+ | SAMETEAM expr=expression #sameTeamExpression
+ | SEARCHOBJ expr=expression #searchObjExpression
+ | DISTANCE expr=expression #distanceExpression
+ | ISWORM expr=expression #isWormExpression
+ | ISFOOD expr=expression #isFoodExpression
+ | ISPROJECTILE expr=expression #isProjectileExpression
+;
+
+// ------------------------------------------------------------------------
+// --- Specifiers -----------------------------------------------
+// ------------------------------------------------------------------------
+
+NULL: 'null';
+SELF: 'self';
+TRUE: 'true';
+FALSE: 'false';
+
+// ------------------------------------------------------------------------
+// --- Unary Operations ---------------------------------------------------
+// ------------------------------------------------------------------------
+SQRT: 'sqrt';
+SIN: 'sin';
+COS: 'cos';
+NOT: '!';
+GETX: 'getx';
+GETY: 'gety';
+GETRADIUS: 'getradius';
+GETDIR: 'getdir';
+GETAP: 'getap';
+GETMAXAP: 'getmaxap';
+GETHP: 'gethp';
+SAMETEAM: 'sameteam';
+SEARCHOBJ: 'searchobj';
+DISTANCE: 'distance';
+ISWORM: 'isworm';
+ISFOOD: 'isfood';
+ISPROJECTILE: 'isprojectile';
+
+// ------------------------------------------------------------------------
+// --- Actions -----------------------------------------------
+// ------------------------------------------------------------------------
+TURN: 'turn';
+MOVE: 'move';
+JUMP: 'jump';
+EAT: 'eat';
+FIRE: 'fire';
+
+
+// ------------------------------------------------------------------------
+// --- Control Flow -------------------------------------------------------
+// ------------------------------------------------------------------------
+DEF: 'def';
+IF: 'if';
+INVOKE: 'invoke';
+THEN: 'then';
+ELSE: 'else';
+WHILE: 'while';
+BREAK: 'break';
+PRINT: 'print';
+
+
+// ------------------------------------------------------------------------
+// --- Assignment and Arithmetics -----------------------------------------
+// ------------------------------------------------------------------------
+ASSIGN: ':=';
+ADD: '+';
+SUB: '-';
+MUL: '*';
+DIV: '/';
+AND: '&&';
+OR: '||';
+LT: '<';
+LTE: '<=';
+GT: '>';
+GTE: '>=';
+EQ: '==';
+NEQ: '!=';
+
+// ------------------------------------------------------------------------
+// --- Literals and Variables ---------------------------------------------
+// ------------------------------------------------------------------------
+
+NUMBER: INTEGER | FLOAT;
+FLOAT: INTEGER '.' ('0'..'9')+;
+INTEGER: ('-'|'+')? ('0'..'9')+;
+
+IDENTIFIER: LETTER (LETTER | DIGIT | '_')*;
+fragment LETTER: LOWER | UPPER;
+fragment LOWER: 'a'..'z';
+fragment UPPER: 'A'..'Z';
+fragment DIGIT: '0'..'9';
+
+LEFT_PAREN: '(';
+RIGHT_PAREN: ')';
+LEFT_BRACE: '{';
+RIGHT_BRACE: '}';
+COLON: ':';
+
+// ------------------------------------------------------------------------
+// --- Syntactical Ballast ------------------------------------------------
+// ------------------------------------------------------------------------
+
+// Skip runs of newline, space and tab characters.
+WHITESPACE: [ \t\r\n]+ -> skip;
+
+// Single-line comments begin with //, are followed by any characters
+// other than those in a newline, and are terminated by newline characters.
+SINGLE_COMMENT: '//' ~('\r' | '\n')* NEWLINE -> skip;
+fragment NEWLINE: ('\r'? '\n')+;
+
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/ExamplePrinter.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/ExamplePrinter.java
new file mode 100755
index 0000000..d5db737
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/ExamplePrinter.java
@@ -0,0 +1,42 @@
+package worms.programs.internal.parser.example;
+
+import java.io.IOException;
+
+import worms.programs.IProgramFactory;
+import worms.programs.ParseOutcome;
+import worms.programs.ProgramParser;
+
+public class ExamplePrinter {
+ public static void main(String[] args) throws IOException {
+ IProgramFactory factory = PrintingObjectFactory.create();
+ ProgramParser, ?, ?, PrintingProgram> parser = ProgramParser.create(factory);
+
+ /*
+ ParseOutcome outcome = parser.parseString(
+ "def controlled_move:"
+ + " if getap self > 100.0:"
+ + " { jump; print getx self; print gety self; }"
+ + " else move;"
+ + ""
+ + "max_distance := 10.0;"
+ + "while true: {"
+ + " w := searchobj 0.0;"
+ + " if isworm w: {"
+ + " if sameteam w:"
+ + " invoke controlled_move;"
+ + " else if distance w < max_distance:"
+ + " fire;"
+ + " else"
+ + " { turn d; max_distance := max_distance + 0.1; }"
+ + " }"
+ + "}");
+ */
+ //ParseOutcome outcome = parser.parseFile("programs/program_example.txt");
+ //ParseOutcome outcome = parser.parseFile("programs/syntax_test.txt");
+ ParseOutcome outcome = parser.parseFile("programs/program.txt");
+
+ System.out.println(outcome);
+
+ }
+
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObject.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObject.java
new file mode 100755
index 0000000..2183b4c
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObject.java
@@ -0,0 +1,80 @@
+package worms.programs.internal.parser.example;
+
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.stream.Collectors;
+
+import worms.programs.SourceLocation;
+
+public class PrintingObject {
+
+ private boolean indented = false;
+
+ private final StringBuilder repr = new StringBuilder();
+
+ public PrintingObject(SourceLocation loc, String method, Object... args) {
+ if (loc != null) {
+ method = loc + " " + method;
+ }
+ if (args.length > 1) {
+ indented(method + "(");
+ indented = true;
+ for (int i = 0; i < args.length; i++) {
+ indented(repr(args[i]), args.length > 1 && i < args.length - 1);
+ }
+ indented = false;
+ indented(")");
+ } else {
+ String msg = method + "( ";
+ if (args.length > 0) {
+ msg += repr(args[0]).toString().trim();
+ }
+ msg += " )";
+ indented(msg);
+ }
+ }
+
+ private String repr(Object object) {
+ if (object instanceof String) {
+ object = "\"" + object + "\"";
+ } else if (object instanceof List>) {
+ object = String.format("Arrays.toList(%s)", ((List>) object)
+ .stream().map(this::repr)
+ .collect(Collectors.joining(", ### Arrays.toList\n")));
+ }
+ if (object != null) {
+ return object.toString();
+ } else {
+ return "null";
+ }
+ }
+
+ @Override
+ public String toString() {
+ return repr.toString();
+ }
+
+ private void indented(Object object) {
+ indented(object, false);
+ }
+
+ private void indented(Object object, boolean appendComma) {
+ if (object != null) {
+ String str = object.toString();
+ StringTokenizer tok = new StringTokenizer(str, "\n");
+ while (tok.hasMoreTokens()) {
+ if (indented)
+ repr.append("| ");
+ repr.append(tok.nextToken());
+ if (!tok.hasMoreTokens() && appendComma) {
+ repr.append(",");
+ }
+ repr.append("\n");
+ }
+ } else {
+ if (indented)
+ repr.append(" null");
+ }
+
+ }
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObjectFactory.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObjectFactory.java
new file mode 100755
index 0000000..1950b1c
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingObjectFactory.java
@@ -0,0 +1,49 @@
+package worms.programs.internal.parser.example;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.List;
+
+import worms.programs.IProgramFactory;
+import worms.programs.SourceLocation;
+
+
+public class PrintingObjectFactory {
+
+ /**
+ * Creates an implementation of IProgramFactory where the implementation of
+ * each interface method (except createProgram) just creates a
+ * PrintingObject with all arguments.
+ */
+ @SuppressWarnings("unchecked")
+ public static IProgramFactory create() {
+
+ InvocationHandler handler = new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getName().equals("createProgram")) {
+ List functions = (List)args[0];
+ PrintingObject main = (PrintingObject) args[1];
+ return new PrintingProgram(functions, main);
+ }
+ if (args != null) {
+ SourceLocation sourceLocation = (SourceLocation) args[args.length - 1];
+ if (args.length >= 1) {
+ return new PrintingObject(sourceLocation, method.getName(),
+ Arrays.copyOfRange(args, 0, args.length - 1));
+ } else {
+ return new PrintingObject(sourceLocation, method.getName());
+ }
+ } else {
+ return new PrintingObject(null, method.getName());
+ }
+ }
+ };
+
+ return (IProgramFactory) Proxy.newProxyInstance(
+ IProgramFactory.class.getClassLoader(), new Class[] { IProgramFactory.class }, handler);
+ }
+}
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingProgram.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingProgram.java
new file mode 100755
index 0000000..685d7c5
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/example/PrintingProgram.java
@@ -0,0 +1,22 @@
+package worms.programs.internal.parser.example;
+
+import java.util.List;
+
+public class PrintingProgram {
+
+ private List procedures;
+ private PrintingObject main;
+
+ public PrintingProgram(List procedures, PrintingObject main) {
+ if (main == null) {
+ throw new NullPointerException("main null");
+ }
+ this.main = main;
+ this.procedures = procedures;
+ }
+
+ @Override
+ public String toString() {
+ return "Procedures: " + procedures.toString() + "\nMain:" + main.toString();
+ }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.interp b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.interp
new file mode 100755
index 0000000..e3d1b4b
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.interp
@@ -0,0 +1,141 @@
+token literal names:
+null
+';'
+'null'
+'self'
+'true'
+'false'
+'sqrt'
+'sin'
+'cos'
+'!'
+'getx'
+'gety'
+'getradius'
+'getdir'
+'getap'
+'getmaxap'
+'gethp'
+'sameteam'
+'searchobj'
+'distance'
+'isworm'
+'isfood'
+'isprojectile'
+'turn'
+'move'
+'jump'
+'eat'
+'fire'
+'def'
+'if'
+'invoke'
+'then'
+'else'
+'while'
+'break'
+'print'
+':='
+'+'
+'-'
+'*'
+'/'
+'&&'
+'||'
+'<'
+'<='
+'>'
+'>='
+'=='
+'!='
+null
+null
+null
+null
+'('
+')'
+'{'
+'}'
+':'
+null
+null
+
+token symbolic names:
+null
+null
+NULL
+SELF
+TRUE
+FALSE
+SQRT
+SIN
+COS
+NOT
+GETX
+GETY
+GETRADIUS
+GETDIR
+GETAP
+GETMAXAP
+GETHP
+SAMETEAM
+SEARCHOBJ
+DISTANCE
+ISWORM
+ISFOOD
+ISPROJECTILE
+TURN
+MOVE
+JUMP
+EAT
+FIRE
+DEF
+IF
+INVOKE
+THEN
+ELSE
+WHILE
+BREAK
+PRINT
+ASSIGN
+ADD
+SUB
+MUL
+DIV
+AND
+OR
+LT
+LTE
+GT
+GTE
+EQ
+NEQ
+NUMBER
+FLOAT
+INTEGER
+IDENTIFIER
+LEFT_PAREN
+RIGHT_PAREN
+LEFT_BRACE
+RIGHT_BRACE
+COLON
+WHITESPACE
+SINGLE_COMMENT
+
+rule names:
+program
+proceduredef
+statement
+assignmentStatement
+whileStatement
+ifStatement
+printStatement
+sequenceStatement
+invokeStatement
+breakStatement
+actionStatement
+expression
+
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 61, 188, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 3, 2, 7, 2, 28, 10, 2, 12, 2, 14, 2, 31, 11, 2, 3, 2, 7, 2, 34, 10, 2, 12, 2, 14, 2, 37, 11, 2, 3, 3, 3, 3, 3, 3, 5, 3, 42, 10, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 54, 10, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 5, 6, 64, 10, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 5, 7, 71, 10, 7, 3, 7, 3, 7, 3, 7, 5, 7, 76, 10, 7, 3, 7, 5, 7, 79, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 7, 9, 87, 10, 9, 12, 9, 14, 9, 90, 11, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 113, 10, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 169, 10, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 183, 10, 13, 12, 13, 14, 13, 186, 11, 13, 3, 13, 2, 3, 24, 14, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 2, 6, 3, 2, 41, 42, 3, 2, 39, 40, 3, 2, 45, 50, 3, 2, 43, 44, 2, 221, 2, 29, 3, 2, 2, 2, 4, 38, 3, 2, 2, 2, 6, 53, 3, 2, 2, 2, 8, 55, 3, 2, 2, 2, 10, 60, 3, 2, 2, 2, 12, 67, 3, 2, 2, 2, 14, 80, 3, 2, 2, 2, 16, 84, 3, 2, 2, 2, 18, 93, 3, 2, 2, 2, 20, 97, 3, 2, 2, 2, 22, 112, 3, 2, 2, 2, 24, 168, 3, 2, 2, 2, 26, 28, 5, 4, 3, 2, 27, 26, 3, 2, 2, 2, 28, 31, 3, 2, 2, 2, 29, 27, 3, 2, 2, 2, 29, 30, 3, 2, 2, 2, 30, 35, 3, 2, 2, 2, 31, 29, 3, 2, 2, 2, 32, 34, 5, 6, 4, 2, 33, 32, 3, 2, 2, 2, 34, 37, 3, 2, 2, 2, 35, 33, 3, 2, 2, 2, 35, 36, 3, 2, 2, 2, 36, 3, 3, 2, 2, 2, 37, 35, 3, 2, 2, 2, 38, 39, 7, 30, 2, 2, 39, 41, 7, 54, 2, 2, 40, 42, 7, 59, 2, 2, 41, 40, 3, 2, 2, 2, 41, 42, 3, 2, 2, 2, 42, 43, 3, 2, 2, 2, 43, 44, 5, 6, 4, 2, 44, 5, 3, 2, 2, 2, 45, 54, 5, 8, 5, 2, 46, 54, 5, 10, 6, 2, 47, 54, 5, 12, 7, 2, 48, 54, 5, 14, 8, 2, 49, 54, 5, 16, 9, 2, 50, 54, 5, 18, 10, 2, 51, 54, 5, 20, 11, 2, 52, 54, 5, 22, 12, 2, 53, 45, 3, 2, 2, 2, 53, 46, 3, 2, 2, 2, 53, 47, 3, 2, 2, 2, 53, 48, 3, 2, 2, 2, 53, 49, 3, 2, 2, 2, 53, 50, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 52, 3, 2, 2, 2, 54, 7, 3, 2, 2, 2, 55, 56, 7, 54, 2, 2, 56, 57, 7, 38, 2, 2, 57, 58, 5, 24, 13, 2, 58, 59, 7, 3, 2, 2, 59, 9, 3, 2, 2, 2, 60, 61, 7, 35, 2, 2, 61, 63, 5, 24, 13, 2, 62, 64, 7, 59, 2, 2, 63, 62, 3, 2, 2, 2, 63, 64, 3, 2, 2, 2, 64, 65, 3, 2, 2, 2, 65, 66, 5, 6, 4, 2, 66, 11, 3, 2, 2, 2, 67, 68, 7, 31, 2, 2, 68, 70, 5, 24, 13, 2, 69, 71, 7, 59, 2, 2, 70, 69, 3, 2, 2, 2, 70, 71, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 78, 5, 6, 4, 2, 73, 75, 7, 34, 2, 2, 74, 76, 7, 59, 2, 2, 75, 74, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 79, 5, 6, 4, 2, 78, 73, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 13, 3, 2, 2, 2, 80, 81, 7, 37, 2, 2, 81, 82, 5, 24, 13, 2, 82, 83, 7, 3, 2, 2, 83, 15, 3, 2, 2, 2, 84, 88, 7, 57, 2, 2, 85, 87, 5, 6, 4, 2, 86, 85, 3, 2, 2, 2, 87, 90, 3, 2, 2, 2, 88, 86, 3, 2, 2, 2, 88, 89, 3, 2, 2, 2, 89, 91, 3, 2, 2, 2, 90, 88, 3, 2, 2, 2, 91, 92, 7, 58, 2, 2, 92, 17, 3, 2, 2, 2, 93, 94, 7, 32, 2, 2, 94, 95, 7, 54, 2, 2, 95, 96, 7, 3, 2, 2, 96, 19, 3, 2, 2, 2, 97, 98, 7, 36, 2, 2, 98, 99, 7, 3, 2, 2, 99, 21, 3, 2, 2, 2, 100, 101, 7, 25, 2, 2, 101, 102, 5, 24, 13, 2, 102, 103, 7, 3, 2, 2, 103, 113, 3, 2, 2, 2, 104, 105, 7, 26, 2, 2, 105, 113, 7, 3, 2, 2, 106, 107, 7, 27, 2, 2, 107, 113, 7, 3, 2, 2, 108, 109, 7, 28, 2, 2, 109, 113, 7, 3, 2, 2, 110, 111, 7, 29, 2, 2, 111, 113, 7, 3, 2, 2, 112, 100, 3, 2, 2, 2, 112, 104, 3, 2, 2, 2, 112, 106, 3, 2, 2, 2, 112, 108, 3, 2, 2, 2, 112, 110, 3, 2, 2, 2, 113, 23, 3, 2, 2, 2, 114, 115, 8, 13, 1, 2, 115, 169, 7, 54, 2, 2, 116, 169, 7, 51, 2, 2, 117, 169, 7, 6, 2, 2, 118, 169, 7, 7, 2, 2, 119, 169, 7, 4, 2, 2, 120, 169, 7, 5, 2, 2, 121, 122, 7, 55, 2, 2, 122, 123, 5, 24, 13, 2, 123, 124, 7, 56, 2, 2, 124, 169, 3, 2, 2, 2, 125, 126, 7, 8, 2, 2, 126, 127, 7, 55, 2, 2, 127, 128, 5, 24, 13, 2, 128, 129, 7, 56, 2, 2, 129, 169, 3, 2, 2, 2, 130, 131, 7, 9, 2, 2, 131, 132, 7, 55, 2, 2, 132, 133, 5, 24, 13, 2, 133, 134, 7, 56, 2, 2, 134, 169, 3, 2, 2, 2, 135, 136, 7, 10, 2, 2, 136, 137, 7, 55, 2, 2, 137, 138, 5, 24, 13, 2, 138, 139, 7, 56, 2, 2, 139, 169, 3, 2, 2, 2, 140, 141, 7, 11, 2, 2, 141, 169, 5, 24, 13, 16, 142, 143, 7, 12, 2, 2, 143, 169, 5, 24, 13, 15, 144, 145, 7, 13, 2, 2, 145, 169, 5, 24, 13, 14, 146, 147, 7, 14, 2, 2, 147, 169, 5, 24, 13, 13, 148, 149, 7, 15, 2, 2, 149, 169, 5, 24, 13, 12, 150, 151, 7, 16, 2, 2, 151, 169, 5, 24, 13, 11, 152, 153, 7, 17, 2, 2, 153, 169, 5, 24, 13, 10, 154, 155, 7, 18, 2, 2, 155, 169, 5, 24, 13, 9, 156, 157, 7, 19, 2, 2, 157, 169, 5, 24, 13, 8, 158, 159, 7, 20, 2, 2, 159, 169, 5, 24, 13, 7, 160, 161, 7, 21, 2, 2, 161, 169, 5, 24, 13, 6, 162, 163, 7, 22, 2, 2, 163, 169, 5, 24, 13, 5, 164, 165, 7, 23, 2, 2, 165, 169, 5, 24, 13, 4, 166, 167, 7, 24, 2, 2, 167, 169, 5, 24, 13, 3, 168, 114, 3, 2, 2, 2, 168, 116, 3, 2, 2, 2, 168, 117, 3, 2, 2, 2, 168, 118, 3, 2, 2, 2, 168, 119, 3, 2, 2, 2, 168, 120, 3, 2, 2, 2, 168, 121, 3, 2, 2, 2, 168, 125, 3, 2, 2, 2, 168, 130, 3, 2, 2, 2, 168, 135, 3, 2, 2, 2, 168, 140, 3, 2, 2, 2, 168, 142, 3, 2, 2, 2, 168, 144, 3, 2, 2, 2, 168, 146, 3, 2, 2, 2, 168, 148, 3, 2, 2, 2, 168, 150, 3, 2, 2, 2, 168, 152, 3, 2, 2, 2, 168, 154, 3, 2, 2, 2, 168, 156, 3, 2, 2, 2, 168, 158, 3, 2, 2, 2, 168, 160, 3, 2, 2, 2, 168, 162, 3, 2, 2, 2, 168, 164, 3, 2, 2, 2, 168, 166, 3, 2, 2, 2, 169, 184, 3, 2, 2, 2, 170, 171, 12, 23, 2, 2, 171, 172, 9, 2, 2, 2, 172, 183, 5, 24, 13, 24, 173, 174, 12, 22, 2, 2, 174, 175, 9, 3, 2, 2, 175, 183, 5, 24, 13, 23, 176, 177, 12, 21, 2, 2, 177, 178, 9, 4, 2, 2, 178, 183, 5, 24, 13, 22, 179, 180, 12, 20, 2, 2, 180, 181, 9, 5, 2, 2, 181, 183, 5, 24, 13, 21, 182, 170, 3, 2, 2, 2, 182, 173, 3, 2, 2, 2, 182, 176, 3, 2, 2, 2, 182, 179, 3, 2, 2, 2, 183, 186, 3, 2, 2, 2, 184, 182, 3, 2, 2, 2, 184, 185, 3, 2, 2, 2, 185, 25, 3, 2, 2, 2, 186, 184, 3, 2, 2, 2, 15, 29, 35, 41, 53, 63, 70, 75, 78, 88, 112, 168, 182, 184]
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.tokens b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.tokens
new file mode 100755
index 0000000..a4780f1
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgram.tokens
@@ -0,0 +1,112 @@
+T__0=1
+NULL=2
+SELF=3
+TRUE=4
+FALSE=5
+SQRT=6
+SIN=7
+COS=8
+NOT=9
+GETX=10
+GETY=11
+GETRADIUS=12
+GETDIR=13
+GETAP=14
+GETMAXAP=15
+GETHP=16
+SAMETEAM=17
+SEARCHOBJ=18
+DISTANCE=19
+ISWORM=20
+ISFOOD=21
+ISPROJECTILE=22
+TURN=23
+MOVE=24
+JUMP=25
+EAT=26
+FIRE=27
+DEF=28
+IF=29
+INVOKE=30
+THEN=31
+ELSE=32
+WHILE=33
+BREAK=34
+PRINT=35
+ASSIGN=36
+ADD=37
+SUB=38
+MUL=39
+DIV=40
+AND=41
+OR=42
+LT=43
+LTE=44
+GT=45
+GTE=46
+EQ=47
+NEQ=48
+NUMBER=49
+FLOAT=50
+INTEGER=51
+IDENTIFIER=52
+LEFT_PAREN=53
+RIGHT_PAREN=54
+LEFT_BRACE=55
+RIGHT_BRACE=56
+COLON=57
+WHITESPACE=58
+SINGLE_COMMENT=59
+';'=1
+'null'=2
+'self'=3
+'true'=4
+'false'=5
+'sqrt'=6
+'sin'=7
+'cos'=8
+'!'=9
+'getx'=10
+'gety'=11
+'getradius'=12
+'getdir'=13
+'getap'=14
+'getmaxap'=15
+'gethp'=16
+'sameteam'=17
+'searchobj'=18
+'distance'=19
+'isworm'=20
+'isfood'=21
+'isprojectile'=22
+'turn'=23
+'move'=24
+'jump'=25
+'eat'=26
+'fire'=27
+'def'=28
+'if'=29
+'invoke'=30
+'then'=31
+'else'=32
+'while'=33
+'break'=34
+'print'=35
+':='=36
+'+'=37
+'-'=38
+'*'=39
+'/'=40
+'&&'=41
+'||'=42
+'<'=43
+'<='=44
+'>'=45
+'>='=46
+'=='=47
+'!='=48
+'('=53
+')'=54
+'{'=55
+'}'=56
+':'=57
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramBaseVisitor.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramBaseVisitor.java
new file mode 100755
index 0000000..eed84d5
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramBaseVisitor.java
@@ -0,0 +1,317 @@
+// Generated from WormsProgram.g4 by ANTLR 4.7.1
+
+ package worms.programs.internal.parser.generated;
+
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+/**
+ * This class provides an empty implementation of {@link WormsProgramVisitor},
+ * which can be extended to create a visitor which only needs to handle a subset
+ * of the available methods.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public class WormsProgramBaseVisitor extends AbstractParseTreeVisitor implements WormsProgramVisitor {
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitProgram(WormsProgramParser.ProgramContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitProceduredef(WormsProgramParser.ProceduredefContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitStatement(WormsProgramParser.StatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIfStatement(WormsProgramParser.IfStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitTurnAction(WormsProgramParser.TurnActionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMoveAction(WormsProgramParser.MoveActionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitJumpAction(WormsProgramParser.JumpActionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitEatAction(WormsProgramParser.EatActionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitFireAction(WormsProgramParser.FireActionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitCosExpression(WormsProgramParser.CosExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitNotExpression(WormsProgramParser.NotExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitNullExpression(WormsProgramParser.NullExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSinExpression(WormsProgramParser.SinExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx) { return visitChildren(ctx); }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.interp b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.interp
new file mode 100755
index 0000000..5386a5e
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.interp
@@ -0,0 +1,199 @@
+token literal names:
+null
+';'
+'null'
+'self'
+'true'
+'false'
+'sqrt'
+'sin'
+'cos'
+'!'
+'getx'
+'gety'
+'getradius'
+'getdir'
+'getap'
+'getmaxap'
+'gethp'
+'sameteam'
+'searchobj'
+'distance'
+'isworm'
+'isfood'
+'isprojectile'
+'turn'
+'move'
+'jump'
+'eat'
+'fire'
+'def'
+'if'
+'invoke'
+'then'
+'else'
+'while'
+'break'
+'print'
+':='
+'+'
+'-'
+'*'
+'/'
+'&&'
+'||'
+'<'
+'<='
+'>'
+'>='
+'=='
+'!='
+null
+null
+null
+null
+'('
+')'
+'{'
+'}'
+':'
+null
+null
+
+token symbolic names:
+null
+null
+NULL
+SELF
+TRUE
+FALSE
+SQRT
+SIN
+COS
+NOT
+GETX
+GETY
+GETRADIUS
+GETDIR
+GETAP
+GETMAXAP
+GETHP
+SAMETEAM
+SEARCHOBJ
+DISTANCE
+ISWORM
+ISFOOD
+ISPROJECTILE
+TURN
+MOVE
+JUMP
+EAT
+FIRE
+DEF
+IF
+INVOKE
+THEN
+ELSE
+WHILE
+BREAK
+PRINT
+ASSIGN
+ADD
+SUB
+MUL
+DIV
+AND
+OR
+LT
+LTE
+GT
+GTE
+EQ
+NEQ
+NUMBER
+FLOAT
+INTEGER
+IDENTIFIER
+LEFT_PAREN
+RIGHT_PAREN
+LEFT_BRACE
+RIGHT_BRACE
+COLON
+WHITESPACE
+SINGLE_COMMENT
+
+rule names:
+T__0
+NULL
+SELF
+TRUE
+FALSE
+SQRT
+SIN
+COS
+NOT
+GETX
+GETY
+GETRADIUS
+GETDIR
+GETAP
+GETMAXAP
+GETHP
+SAMETEAM
+SEARCHOBJ
+DISTANCE
+ISWORM
+ISFOOD
+ISPROJECTILE
+TURN
+MOVE
+JUMP
+EAT
+FIRE
+DEF
+IF
+INVOKE
+THEN
+ELSE
+WHILE
+BREAK
+PRINT
+ASSIGN
+ADD
+SUB
+MUL
+DIV
+AND
+OR
+LT
+LTE
+GT
+GTE
+EQ
+NEQ
+NUMBER
+FLOAT
+INTEGER
+IDENTIFIER
+LETTER
+LOWER
+UPPER
+DIGIT
+LEFT_PAREN
+RIGHT_PAREN
+LEFT_BRACE
+RIGHT_BRACE
+COLON
+WHITESPACE
+SINGLE_COMMENT
+NEWLINE
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 61, 447, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 5, 50, 374, 10, 50, 3, 51, 3, 51, 3, 51, 6, 51, 379, 10, 51, 13, 51, 14, 51, 380, 3, 52, 5, 52, 384, 10, 52, 3, 52, 6, 52, 387, 10, 52, 13, 52, 14, 52, 388, 3, 53, 3, 53, 3, 53, 3, 53, 7, 53, 395, 10, 53, 12, 53, 14, 53, 398, 11, 53, 3, 54, 3, 54, 5, 54, 402, 10, 54, 3, 55, 3, 55, 3, 56, 3, 56, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 6, 63, 421, 10, 63, 13, 63, 14, 63, 422, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 7, 64, 431, 10, 64, 12, 64, 14, 64, 434, 11, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 65, 5, 65, 441, 10, 65, 3, 65, 6, 65, 444, 10, 65, 13, 65, 14, 65, 445, 2, 2, 66, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 2, 109, 2, 111, 2, 113, 2, 115, 55, 117, 56, 119, 57, 121, 58, 123, 59, 125, 60, 127, 61, 129, 2, 3, 2, 5, 4, 2, 45, 45, 47, 47, 5, 2, 11, 12, 15, 15, 34, 34, 4, 2, 12, 12, 15, 15, 2, 453, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 3, 131, 3, 2, 2, 2, 5, 133, 3, 2, 2, 2, 7, 138, 3, 2, 2, 2, 9, 143, 3, 2, 2, 2, 11, 148, 3, 2, 2, 2, 13, 154, 3, 2, 2, 2, 15, 159, 3, 2, 2, 2, 17, 163, 3, 2, 2, 2, 19, 167, 3, 2, 2, 2, 21, 169, 3, 2, 2, 2, 23, 174, 3, 2, 2, 2, 25, 179, 3, 2, 2, 2, 27, 189, 3, 2, 2, 2, 29, 196, 3, 2, 2, 2, 31, 202, 3, 2, 2, 2, 33, 211, 3, 2, 2, 2, 35, 217, 3, 2, 2, 2, 37, 226, 3, 2, 2, 2, 39, 236, 3, 2, 2, 2, 41, 245, 3, 2, 2, 2, 43, 252, 3, 2, 2, 2, 45, 259, 3, 2, 2, 2, 47, 272, 3, 2, 2, 2, 49, 277, 3, 2, 2, 2, 51, 282, 3, 2, 2, 2, 53, 287, 3, 2, 2, 2, 55, 291, 3, 2, 2, 2, 57, 296, 3, 2, 2, 2, 59, 300, 3, 2, 2, 2, 61, 303, 3, 2, 2, 2, 63, 310, 3, 2, 2, 2, 65, 315, 3, 2, 2, 2, 67, 320, 3, 2, 2, 2, 69, 326, 3, 2, 2, 2, 71, 332, 3, 2, 2, 2, 73, 338, 3, 2, 2, 2, 75, 341, 3, 2, 2, 2, 77, 343, 3, 2, 2, 2, 79, 345, 3, 2, 2, 2, 81, 347, 3, 2, 2, 2, 83, 349, 3, 2, 2, 2, 85, 352, 3, 2, 2, 2, 87, 355, 3, 2, 2, 2, 89, 357, 3, 2, 2, 2, 91, 360, 3, 2, 2, 2, 93, 362, 3, 2, 2, 2, 95, 365, 3, 2, 2, 2, 97, 368, 3, 2, 2, 2, 99, 373, 3, 2, 2, 2, 101, 375, 3, 2, 2, 2, 103, 383, 3, 2, 2, 2, 105, 390, 3, 2, 2, 2, 107, 401, 3, 2, 2, 2, 109, 403, 3, 2, 2, 2, 111, 405, 3, 2, 2, 2, 113, 407, 3, 2, 2, 2, 115, 409, 3, 2, 2, 2, 117, 411, 3, 2, 2, 2, 119, 413, 3, 2, 2, 2, 121, 415, 3, 2, 2, 2, 123, 417, 3, 2, 2, 2, 125, 420, 3, 2, 2, 2, 127, 426, 3, 2, 2, 2, 129, 443, 3, 2, 2, 2, 131, 132, 7, 61, 2, 2, 132, 4, 3, 2, 2, 2, 133, 134, 7, 112, 2, 2, 134, 135, 7, 119, 2, 2, 135, 136, 7, 110, 2, 2, 136, 137, 7, 110, 2, 2, 137, 6, 3, 2, 2, 2, 138, 139, 7, 117, 2, 2, 139, 140, 7, 103, 2, 2, 140, 141, 7, 110, 2, 2, 141, 142, 7, 104, 2, 2, 142, 8, 3, 2, 2, 2, 143, 144, 7, 118, 2, 2, 144, 145, 7, 116, 2, 2, 145, 146, 7, 119, 2, 2, 146, 147, 7, 103, 2, 2, 147, 10, 3, 2, 2, 2, 148, 149, 7, 104, 2, 2, 149, 150, 7, 99, 2, 2, 150, 151, 7, 110, 2, 2, 151, 152, 7, 117, 2, 2, 152, 153, 7, 103, 2, 2, 153, 12, 3, 2, 2, 2, 154, 155, 7, 117, 2, 2, 155, 156, 7, 115, 2, 2, 156, 157, 7, 116, 2, 2, 157, 158, 7, 118, 2, 2, 158, 14, 3, 2, 2, 2, 159, 160, 7, 117, 2, 2, 160, 161, 7, 107, 2, 2, 161, 162, 7, 112, 2, 2, 162, 16, 3, 2, 2, 2, 163, 164, 7, 101, 2, 2, 164, 165, 7, 113, 2, 2, 165, 166, 7, 117, 2, 2, 166, 18, 3, 2, 2, 2, 167, 168, 7, 35, 2, 2, 168, 20, 3, 2, 2, 2, 169, 170, 7, 105, 2, 2, 170, 171, 7, 103, 2, 2, 171, 172, 7, 118, 2, 2, 172, 173, 7, 122, 2, 2, 173, 22, 3, 2, 2, 2, 174, 175, 7, 105, 2, 2, 175, 176, 7, 103, 2, 2, 176, 177, 7, 118, 2, 2, 177, 178, 7, 123, 2, 2, 178, 24, 3, 2, 2, 2, 179, 180, 7, 105, 2, 2, 180, 181, 7, 103, 2, 2, 181, 182, 7, 118, 2, 2, 182, 183, 7, 116, 2, 2, 183, 184, 7, 99, 2, 2, 184, 185, 7, 102, 2, 2, 185, 186, 7, 107, 2, 2, 186, 187, 7, 119, 2, 2, 187, 188, 7, 117, 2, 2, 188, 26, 3, 2, 2, 2, 189, 190, 7, 105, 2, 2, 190, 191, 7, 103, 2, 2, 191, 192, 7, 118, 2, 2, 192, 193, 7, 102, 2, 2, 193, 194, 7, 107, 2, 2, 194, 195, 7, 116, 2, 2, 195, 28, 3, 2, 2, 2, 196, 197, 7, 105, 2, 2, 197, 198, 7, 103, 2, 2, 198, 199, 7, 118, 2, 2, 199, 200, 7, 99, 2, 2, 200, 201, 7, 114, 2, 2, 201, 30, 3, 2, 2, 2, 202, 203, 7, 105, 2, 2, 203, 204, 7, 103, 2, 2, 204, 205, 7, 118, 2, 2, 205, 206, 7, 111, 2, 2, 206, 207, 7, 99, 2, 2, 207, 208, 7, 122, 2, 2, 208, 209, 7, 99, 2, 2, 209, 210, 7, 114, 2, 2, 210, 32, 3, 2, 2, 2, 211, 212, 7, 105, 2, 2, 212, 213, 7, 103, 2, 2, 213, 214, 7, 118, 2, 2, 214, 215, 7, 106, 2, 2, 215, 216, 7, 114, 2, 2, 216, 34, 3, 2, 2, 2, 217, 218, 7, 117, 2, 2, 218, 219, 7, 99, 2, 2, 219, 220, 7, 111, 2, 2, 220, 221, 7, 103, 2, 2, 221, 222, 7, 118, 2, 2, 222, 223, 7, 103, 2, 2, 223, 224, 7, 99, 2, 2, 224, 225, 7, 111, 2, 2, 225, 36, 3, 2, 2, 2, 226, 227, 7, 117, 2, 2, 227, 228, 7, 103, 2, 2, 228, 229, 7, 99, 2, 2, 229, 230, 7, 116, 2, 2, 230, 231, 7, 101, 2, 2, 231, 232, 7, 106, 2, 2, 232, 233, 7, 113, 2, 2, 233, 234, 7, 100, 2, 2, 234, 235, 7, 108, 2, 2, 235, 38, 3, 2, 2, 2, 236, 237, 7, 102, 2, 2, 237, 238, 7, 107, 2, 2, 238, 239, 7, 117, 2, 2, 239, 240, 7, 118, 2, 2, 240, 241, 7, 99, 2, 2, 241, 242, 7, 112, 2, 2, 242, 243, 7, 101, 2, 2, 243, 244, 7, 103, 2, 2, 244, 40, 3, 2, 2, 2, 245, 246, 7, 107, 2, 2, 246, 247, 7, 117, 2, 2, 247, 248, 7, 121, 2, 2, 248, 249, 7, 113, 2, 2, 249, 250, 7, 116, 2, 2, 250, 251, 7, 111, 2, 2, 251, 42, 3, 2, 2, 2, 252, 253, 7, 107, 2, 2, 253, 254, 7, 117, 2, 2, 254, 255, 7, 104, 2, 2, 255, 256, 7, 113, 2, 2, 256, 257, 7, 113, 2, 2, 257, 258, 7, 102, 2, 2, 258, 44, 3, 2, 2, 2, 259, 260, 7, 107, 2, 2, 260, 261, 7, 117, 2, 2, 261, 262, 7, 114, 2, 2, 262, 263, 7, 116, 2, 2, 263, 264, 7, 113, 2, 2, 264, 265, 7, 108, 2, 2, 265, 266, 7, 103, 2, 2, 266, 267, 7, 101, 2, 2, 267, 268, 7, 118, 2, 2, 268, 269, 7, 107, 2, 2, 269, 270, 7, 110, 2, 2, 270, 271, 7, 103, 2, 2, 271, 46, 3, 2, 2, 2, 272, 273, 7, 118, 2, 2, 273, 274, 7, 119, 2, 2, 274, 275, 7, 116, 2, 2, 275, 276, 7, 112, 2, 2, 276, 48, 3, 2, 2, 2, 277, 278, 7, 111, 2, 2, 278, 279, 7, 113, 2, 2, 279, 280, 7, 120, 2, 2, 280, 281, 7, 103, 2, 2, 281, 50, 3, 2, 2, 2, 282, 283, 7, 108, 2, 2, 283, 284, 7, 119, 2, 2, 284, 285, 7, 111, 2, 2, 285, 286, 7, 114, 2, 2, 286, 52, 3, 2, 2, 2, 287, 288, 7, 103, 2, 2, 288, 289, 7, 99, 2, 2, 289, 290, 7, 118, 2, 2, 290, 54, 3, 2, 2, 2, 291, 292, 7, 104, 2, 2, 292, 293, 7, 107, 2, 2, 293, 294, 7, 116, 2, 2, 294, 295, 7, 103, 2, 2, 295, 56, 3, 2, 2, 2, 296, 297, 7, 102, 2, 2, 297, 298, 7, 103, 2, 2, 298, 299, 7, 104, 2, 2, 299, 58, 3, 2, 2, 2, 300, 301, 7, 107, 2, 2, 301, 302, 7, 104, 2, 2, 302, 60, 3, 2, 2, 2, 303, 304, 7, 107, 2, 2, 304, 305, 7, 112, 2, 2, 305, 306, 7, 120, 2, 2, 306, 307, 7, 113, 2, 2, 307, 308, 7, 109, 2, 2, 308, 309, 7, 103, 2, 2, 309, 62, 3, 2, 2, 2, 310, 311, 7, 118, 2, 2, 311, 312, 7, 106, 2, 2, 312, 313, 7, 103, 2, 2, 313, 314, 7, 112, 2, 2, 314, 64, 3, 2, 2, 2, 315, 316, 7, 103, 2, 2, 316, 317, 7, 110, 2, 2, 317, 318, 7, 117, 2, 2, 318, 319, 7, 103, 2, 2, 319, 66, 3, 2, 2, 2, 320, 321, 7, 121, 2, 2, 321, 322, 7, 106, 2, 2, 322, 323, 7, 107, 2, 2, 323, 324, 7, 110, 2, 2, 324, 325, 7, 103, 2, 2, 325, 68, 3, 2, 2, 2, 326, 327, 7, 100, 2, 2, 327, 328, 7, 116, 2, 2, 328, 329, 7, 103, 2, 2, 329, 330, 7, 99, 2, 2, 330, 331, 7, 109, 2, 2, 331, 70, 3, 2, 2, 2, 332, 333, 7, 114, 2, 2, 333, 334, 7, 116, 2, 2, 334, 335, 7, 107, 2, 2, 335, 336, 7, 112, 2, 2, 336, 337, 7, 118, 2, 2, 337, 72, 3, 2, 2, 2, 338, 339, 7, 60, 2, 2, 339, 340, 7, 63, 2, 2, 340, 74, 3, 2, 2, 2, 341, 342, 7, 45, 2, 2, 342, 76, 3, 2, 2, 2, 343, 344, 7, 47, 2, 2, 344, 78, 3, 2, 2, 2, 345, 346, 7, 44, 2, 2, 346, 80, 3, 2, 2, 2, 347, 348, 7, 49, 2, 2, 348, 82, 3, 2, 2, 2, 349, 350, 7, 40, 2, 2, 350, 351, 7, 40, 2, 2, 351, 84, 3, 2, 2, 2, 352, 353, 7, 126, 2, 2, 353, 354, 7, 126, 2, 2, 354, 86, 3, 2, 2, 2, 355, 356, 7, 62, 2, 2, 356, 88, 3, 2, 2, 2, 357, 358, 7, 62, 2, 2, 358, 359, 7, 63, 2, 2, 359, 90, 3, 2, 2, 2, 360, 361, 7, 64, 2, 2, 361, 92, 3, 2, 2, 2, 362, 363, 7, 64, 2, 2, 363, 364, 7, 63, 2, 2, 364, 94, 3, 2, 2, 2, 365, 366, 7, 63, 2, 2, 366, 367, 7, 63, 2, 2, 367, 96, 3, 2, 2, 2, 368, 369, 7, 35, 2, 2, 369, 370, 7, 63, 2, 2, 370, 98, 3, 2, 2, 2, 371, 374, 5, 103, 52, 2, 372, 374, 5, 101, 51, 2, 373, 371, 3, 2, 2, 2, 373, 372, 3, 2, 2, 2, 374, 100, 3, 2, 2, 2, 375, 376, 5, 103, 52, 2, 376, 378, 7, 48, 2, 2, 377, 379, 4, 50, 59, 2, 378, 377, 3, 2, 2, 2, 379, 380, 3, 2, 2, 2, 380, 378, 3, 2, 2, 2, 380, 381, 3, 2, 2, 2, 381, 102, 3, 2, 2, 2, 382, 384, 9, 2, 2, 2, 383, 382, 3, 2, 2, 2, 383, 384, 3, 2, 2, 2, 384, 386, 3, 2, 2, 2, 385, 387, 4, 50, 59, 2, 386, 385, 3, 2, 2, 2, 387, 388, 3, 2, 2, 2, 388, 386, 3, 2, 2, 2, 388, 389, 3, 2, 2, 2, 389, 104, 3, 2, 2, 2, 390, 396, 5, 107, 54, 2, 391, 395, 5, 107, 54, 2, 392, 395, 5, 113, 57, 2, 393, 395, 7, 97, 2, 2, 394, 391, 3, 2, 2, 2, 394, 392, 3, 2, 2, 2, 394, 393, 3, 2, 2, 2, 395, 398, 3, 2, 2, 2, 396, 394, 3, 2, 2, 2, 396, 397, 3, 2, 2, 2, 397, 106, 3, 2, 2, 2, 398, 396, 3, 2, 2, 2, 399, 402, 5, 109, 55, 2, 400, 402, 5, 111, 56, 2, 401, 399, 3, 2, 2, 2, 401, 400, 3, 2, 2, 2, 402, 108, 3, 2, 2, 2, 403, 404, 4, 99, 124, 2, 404, 110, 3, 2, 2, 2, 405, 406, 4, 67, 92, 2, 406, 112, 3, 2, 2, 2, 407, 408, 4, 50, 59, 2, 408, 114, 3, 2, 2, 2, 409, 410, 7, 42, 2, 2, 410, 116, 3, 2, 2, 2, 411, 412, 7, 43, 2, 2, 412, 118, 3, 2, 2, 2, 413, 414, 7, 125, 2, 2, 414, 120, 3, 2, 2, 2, 415, 416, 7, 127, 2, 2, 416, 122, 3, 2, 2, 2, 417, 418, 7, 60, 2, 2, 418, 124, 3, 2, 2, 2, 419, 421, 9, 3, 2, 2, 420, 419, 3, 2, 2, 2, 421, 422, 3, 2, 2, 2, 422, 420, 3, 2, 2, 2, 422, 423, 3, 2, 2, 2, 423, 424, 3, 2, 2, 2, 424, 425, 8, 63, 2, 2, 425, 126, 3, 2, 2, 2, 426, 427, 7, 49, 2, 2, 427, 428, 7, 49, 2, 2, 428, 432, 3, 2, 2, 2, 429, 431, 10, 4, 2, 2, 430, 429, 3, 2, 2, 2, 431, 434, 3, 2, 2, 2, 432, 430, 3, 2, 2, 2, 432, 433, 3, 2, 2, 2, 433, 435, 3, 2, 2, 2, 434, 432, 3, 2, 2, 2, 435, 436, 5, 129, 65, 2, 436, 437, 3, 2, 2, 2, 437, 438, 8, 64, 2, 2, 438, 128, 3, 2, 2, 2, 439, 441, 7, 15, 2, 2, 440, 439, 3, 2, 2, 2, 440, 441, 3, 2, 2, 2, 441, 442, 3, 2, 2, 2, 442, 444, 7, 12, 2, 2, 443, 440, 3, 2, 2, 2, 444, 445, 3, 2, 2, 2, 445, 443, 3, 2, 2, 2, 445, 446, 3, 2, 2, 2, 446, 130, 3, 2, 2, 2, 14, 2, 373, 380, 383, 388, 394, 396, 401, 422, 432, 440, 445, 3, 8, 2, 2]
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.java
new file mode 100755
index 0000000..6f3be40
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.java
@@ -0,0 +1,280 @@
+// Generated from WormsProgram.g4 by ANTLR 4.7.1
+
+ package worms.programs.internal.parser.generated;
+
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
+public class WormsProgramLexer extends Lexer {
+ static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
+ public static final int
+ T__0=1, NULL=2, SELF=3, TRUE=4, FALSE=5, SQRT=6, SIN=7, COS=8, NOT=9,
+ GETX=10, GETY=11, GETRADIUS=12, GETDIR=13, GETAP=14, GETMAXAP=15, GETHP=16,
+ SAMETEAM=17, SEARCHOBJ=18, DISTANCE=19, ISWORM=20, ISFOOD=21, ISPROJECTILE=22,
+ TURN=23, MOVE=24, JUMP=25, EAT=26, FIRE=27, DEF=28, IF=29, INVOKE=30,
+ THEN=31, ELSE=32, WHILE=33, BREAK=34, PRINT=35, ASSIGN=36, ADD=37, SUB=38,
+ MUL=39, DIV=40, AND=41, OR=42, LT=43, LTE=44, GT=45, GTE=46, EQ=47, NEQ=48,
+ NUMBER=49, FLOAT=50, INTEGER=51, IDENTIFIER=52, LEFT_PAREN=53, RIGHT_PAREN=54,
+ LEFT_BRACE=55, RIGHT_BRACE=56, COLON=57, WHITESPACE=58, SINGLE_COMMENT=59;
+ public static String[] channelNames = {
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
+ };
+
+ public static String[] modeNames = {
+ "DEFAULT_MODE"
+ };
+
+ public static final String[] ruleNames = {
+ "T__0", "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
+ "GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
+ "SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
+ "JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
+ "BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
+ "LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
+ "LETTER", "LOWER", "UPPER", "DIGIT", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE",
+ "RIGHT_BRACE", "COLON", "WHITESPACE", "SINGLE_COMMENT", "NEWLINE"
+ };
+
+ private static final String[] _LITERAL_NAMES = {
+ null, "';'", "'null'", "'self'", "'true'", "'false'", "'sqrt'", "'sin'",
+ "'cos'", "'!'", "'getx'", "'gety'", "'getradius'", "'getdir'", "'getap'",
+ "'getmaxap'", "'gethp'", "'sameteam'", "'searchobj'", "'distance'", "'isworm'",
+ "'isfood'", "'isprojectile'", "'turn'", "'move'", "'jump'", "'eat'", "'fire'",
+ "'def'", "'if'", "'invoke'", "'then'", "'else'", "'while'", "'break'",
+ "'print'", "':='", "'+'", "'-'", "'*'", "'/'", "'&&'", "'||'", "'<'",
+ "'<='", "'>'", "'>='", "'=='", "'!='", null, null, null, null, "'('",
+ "')'", "'{'", "'}'", "':'"
+ };
+ private static final String[] _SYMBOLIC_NAMES = {
+ null, null, "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
+ "GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
+ "SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
+ "JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
+ "BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
+ "LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
+ "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE", "RIGHT_BRACE", "COLON", "WHITESPACE",
+ "SINGLE_COMMENT"
+ };
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+
+ public WormsProgramLexer(CharStream input) {
+ super(input);
+ _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+ }
+
+ @Override
+ public String getGrammarFileName() { return "WormsProgram.g4"; }
+
+ @Override
+ public String[] getRuleNames() { return ruleNames; }
+
+ @Override
+ public String getSerializedATN() { return _serializedATN; }
+
+ @Override
+ public String[] getChannelNames() { return channelNames; }
+
+ @Override
+ public String[] getModeNames() { return modeNames; }
+
+ @Override
+ public ATN getATN() { return _ATN; }
+
+ public static final String _serializedATN =
+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2=\u01bf\b\1\4\2\t"+
+ "\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
+ "\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
+ "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
+ "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
+ ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
+ "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
+ "\4>\t>\4?\t?\4@\t@\4A\tA\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3"+
+ "\4\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b"+
+ "\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f"+
+ "\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3"+
+ "\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3"+
+ "\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3"+
+ "\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3"+
+ "\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3"+
+ "\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3"+
+ "\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3"+
+ "\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3"+
+ "\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3"+
+ "\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\""+
+ "\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3%\3%\3%\3&\3&\3\'\3"+
+ "\'\3(\3(\3)\3)\3*\3*\3*\3+\3+\3+\3,\3,\3-\3-\3-\3.\3.\3/\3/\3/\3\60\3"+
+ "\60\3\60\3\61\3\61\3\61\3\62\3\62\5\62\u0176\n\62\3\63\3\63\3\63\6\63"+
+ "\u017b\n\63\r\63\16\63\u017c\3\64\5\64\u0180\n\64\3\64\6\64\u0183\n\64"+
+ "\r\64\16\64\u0184\3\65\3\65\3\65\3\65\7\65\u018b\n\65\f\65\16\65\u018e"+
+ "\13\65\3\66\3\66\5\66\u0192\n\66\3\67\3\67\38\38\39\39\3:\3:\3;\3;\3<"+
+ "\3<\3=\3=\3>\3>\3?\6?\u01a5\n?\r?\16?\u01a6\3?\3?\3@\3@\3@\3@\7@\u01af"+
+ "\n@\f@\16@\u01b2\13@\3@\3@\3@\3@\3A\5A\u01b9\nA\3A\6A\u01bc\nA\rA\16A"+
+ "\u01bd\2\2B\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
+ "\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
+ "\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65"+
+ "i\66k\2m\2o\2q\2s\67u8w9y:{;}<\177=\u0081\2\3\2\5\4\2--//\5\2\13\f\17"+
+ "\17\"\"\4\2\f\f\17\17\2\u01c5\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t"+
+ "\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2"+
+ "\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2"+
+ "\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2"+
+ "+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2"+
+ "\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2"+
+ "C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3"+
+ "\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2"+
+ "\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2"+
+ "i\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3"+
+ "\2\2\2\2\177\3\2\2\2\3\u0083\3\2\2\2\5\u0085\3\2\2\2\7\u008a\3\2\2\2\t"+
+ "\u008f\3\2\2\2\13\u0094\3\2\2\2\r\u009a\3\2\2\2\17\u009f\3\2\2\2\21\u00a3"+
+ "\3\2\2\2\23\u00a7\3\2\2\2\25\u00a9\3\2\2\2\27\u00ae\3\2\2\2\31\u00b3\3"+
+ "\2\2\2\33\u00bd\3\2\2\2\35\u00c4\3\2\2\2\37\u00ca\3\2\2\2!\u00d3\3\2\2"+
+ "\2#\u00d9\3\2\2\2%\u00e2\3\2\2\2\'\u00ec\3\2\2\2)\u00f5\3\2\2\2+\u00fc"+
+ "\3\2\2\2-\u0103\3\2\2\2/\u0110\3\2\2\2\61\u0115\3\2\2\2\63\u011a\3\2\2"+
+ "\2\65\u011f\3\2\2\2\67\u0123\3\2\2\29\u0128\3\2\2\2;\u012c\3\2\2\2=\u012f"+
+ "\3\2\2\2?\u0136\3\2\2\2A\u013b\3\2\2\2C\u0140\3\2\2\2E\u0146\3\2\2\2G"+
+ "\u014c\3\2\2\2I\u0152\3\2\2\2K\u0155\3\2\2\2M\u0157\3\2\2\2O\u0159\3\2"+
+ "\2\2Q\u015b\3\2\2\2S\u015d\3\2\2\2U\u0160\3\2\2\2W\u0163\3\2\2\2Y\u0165"+
+ "\3\2\2\2[\u0168\3\2\2\2]\u016a\3\2\2\2_\u016d\3\2\2\2a\u0170\3\2\2\2c"+
+ "\u0175\3\2\2\2e\u0177\3\2\2\2g\u017f\3\2\2\2i\u0186\3\2\2\2k\u0191\3\2"+
+ "\2\2m\u0193\3\2\2\2o\u0195\3\2\2\2q\u0197\3\2\2\2s\u0199\3\2\2\2u\u019b"+
+ "\3\2\2\2w\u019d\3\2\2\2y\u019f\3\2\2\2{\u01a1\3\2\2\2}\u01a4\3\2\2\2\177"+
+ "\u01aa\3\2\2\2\u0081\u01bb\3\2\2\2\u0083\u0084\7=\2\2\u0084\4\3\2\2\2"+
+ "\u0085\u0086\7p\2\2\u0086\u0087\7w\2\2\u0087\u0088\7n\2\2\u0088\u0089"+
+ "\7n\2\2\u0089\6\3\2\2\2\u008a\u008b\7u\2\2\u008b\u008c\7g\2\2\u008c\u008d"+
+ "\7n\2\2\u008d\u008e\7h\2\2\u008e\b\3\2\2\2\u008f\u0090\7v\2\2\u0090\u0091"+
+ "\7t\2\2\u0091\u0092\7w\2\2\u0092\u0093\7g\2\2\u0093\n\3\2\2\2\u0094\u0095"+
+ "\7h\2\2\u0095\u0096\7c\2\2\u0096\u0097\7n\2\2\u0097\u0098\7u\2\2\u0098"+
+ "\u0099\7g\2\2\u0099\f\3\2\2\2\u009a\u009b\7u\2\2\u009b\u009c\7s\2\2\u009c"+
+ "\u009d\7t\2\2\u009d\u009e\7v\2\2\u009e\16\3\2\2\2\u009f\u00a0\7u\2\2\u00a0"+
+ "\u00a1\7k\2\2\u00a1\u00a2\7p\2\2\u00a2\20\3\2\2\2\u00a3\u00a4\7e\2\2\u00a4"+
+ "\u00a5\7q\2\2\u00a5\u00a6\7u\2\2\u00a6\22\3\2\2\2\u00a7\u00a8\7#\2\2\u00a8"+
+ "\24\3\2\2\2\u00a9\u00aa\7i\2\2\u00aa\u00ab\7g\2\2\u00ab\u00ac\7v\2\2\u00ac"+
+ "\u00ad\7z\2\2\u00ad\26\3\2\2\2\u00ae\u00af\7i\2\2\u00af\u00b0\7g\2\2\u00b0"+
+ "\u00b1\7v\2\2\u00b1\u00b2\7{\2\2\u00b2\30\3\2\2\2\u00b3\u00b4\7i\2\2\u00b4"+
+ "\u00b5\7g\2\2\u00b5\u00b6\7v\2\2\u00b6\u00b7\7t\2\2\u00b7\u00b8\7c\2\2"+
+ "\u00b8\u00b9\7f\2\2\u00b9\u00ba\7k\2\2\u00ba\u00bb\7w\2\2\u00bb\u00bc"+
+ "\7u\2\2\u00bc\32\3\2\2\2\u00bd\u00be\7i\2\2\u00be\u00bf\7g\2\2\u00bf\u00c0"+
+ "\7v\2\2\u00c0\u00c1\7f\2\2\u00c1\u00c2\7k\2\2\u00c2\u00c3\7t\2\2\u00c3"+
+ "\34\3\2\2\2\u00c4\u00c5\7i\2\2\u00c5\u00c6\7g\2\2\u00c6\u00c7\7v\2\2\u00c7"+
+ "\u00c8\7c\2\2\u00c8\u00c9\7r\2\2\u00c9\36\3\2\2\2\u00ca\u00cb\7i\2\2\u00cb"+
+ "\u00cc\7g\2\2\u00cc\u00cd\7v\2\2\u00cd\u00ce\7o\2\2\u00ce\u00cf\7c\2\2"+
+ "\u00cf\u00d0\7z\2\2\u00d0\u00d1\7c\2\2\u00d1\u00d2\7r\2\2\u00d2 \3\2\2"+
+ "\2\u00d3\u00d4\7i\2\2\u00d4\u00d5\7g\2\2\u00d5\u00d6\7v\2\2\u00d6\u00d7"+
+ "\7j\2\2\u00d7\u00d8\7r\2\2\u00d8\"\3\2\2\2\u00d9\u00da\7u\2\2\u00da\u00db"+
+ "\7c\2\2\u00db\u00dc\7o\2\2\u00dc\u00dd\7g\2\2\u00dd\u00de\7v\2\2\u00de"+
+ "\u00df\7g\2\2\u00df\u00e0\7c\2\2\u00e0\u00e1\7o\2\2\u00e1$\3\2\2\2\u00e2"+
+ "\u00e3\7u\2\2\u00e3\u00e4\7g\2\2\u00e4\u00e5\7c\2\2\u00e5\u00e6\7t\2\2"+
+ "\u00e6\u00e7\7e\2\2\u00e7\u00e8\7j\2\2\u00e8\u00e9\7q\2\2\u00e9\u00ea"+
+ "\7d\2\2\u00ea\u00eb\7l\2\2\u00eb&\3\2\2\2\u00ec\u00ed\7f\2\2\u00ed\u00ee"+
+ "\7k\2\2\u00ee\u00ef\7u\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1\7c\2\2\u00f1"+
+ "\u00f2\7p\2\2\u00f2\u00f3\7e\2\2\u00f3\u00f4\7g\2\2\u00f4(\3\2\2\2\u00f5"+
+ "\u00f6\7k\2\2\u00f6\u00f7\7u\2\2\u00f7\u00f8\7y\2\2\u00f8\u00f9\7q\2\2"+
+ "\u00f9\u00fa\7t\2\2\u00fa\u00fb\7o\2\2\u00fb*\3\2\2\2\u00fc\u00fd\7k\2"+
+ "\2\u00fd\u00fe\7u\2\2\u00fe\u00ff\7h\2\2\u00ff\u0100\7q\2\2\u0100\u0101"+
+ "\7q\2\2\u0101\u0102\7f\2\2\u0102,\3\2\2\2\u0103\u0104\7k\2\2\u0104\u0105"+
+ "\7u\2\2\u0105\u0106\7r\2\2\u0106\u0107\7t\2\2\u0107\u0108\7q\2\2\u0108"+
+ "\u0109\7l\2\2\u0109\u010a\7g\2\2\u010a\u010b\7e\2\2\u010b\u010c\7v\2\2"+
+ "\u010c\u010d\7k\2\2\u010d\u010e\7n\2\2\u010e\u010f\7g\2\2\u010f.\3\2\2"+
+ "\2\u0110\u0111\7v\2\2\u0111\u0112\7w\2\2\u0112\u0113\7t\2\2\u0113\u0114"+
+ "\7p\2\2\u0114\60\3\2\2\2\u0115\u0116\7o\2\2\u0116\u0117\7q\2\2\u0117\u0118"+
+ "\7x\2\2\u0118\u0119\7g\2\2\u0119\62\3\2\2\2\u011a\u011b\7l\2\2\u011b\u011c"+
+ "\7w\2\2\u011c\u011d\7o\2\2\u011d\u011e\7r\2\2\u011e\64\3\2\2\2\u011f\u0120"+
+ "\7g\2\2\u0120\u0121\7c\2\2\u0121\u0122\7v\2\2\u0122\66\3\2\2\2\u0123\u0124"+
+ "\7h\2\2\u0124\u0125\7k\2\2\u0125\u0126\7t\2\2\u0126\u0127\7g\2\2\u0127"+
+ "8\3\2\2\2\u0128\u0129\7f\2\2\u0129\u012a\7g\2\2\u012a\u012b\7h\2\2\u012b"+
+ ":\3\2\2\2\u012c\u012d\7k\2\2\u012d\u012e\7h\2\2\u012e<\3\2\2\2\u012f\u0130"+
+ "\7k\2\2\u0130\u0131\7p\2\2\u0131\u0132\7x\2\2\u0132\u0133\7q\2\2\u0133"+
+ "\u0134\7m\2\2\u0134\u0135\7g\2\2\u0135>\3\2\2\2\u0136\u0137\7v\2\2\u0137"+
+ "\u0138\7j\2\2\u0138\u0139\7g\2\2\u0139\u013a\7p\2\2\u013a@\3\2\2\2\u013b"+
+ "\u013c\7g\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2\u013e\u013f\7g\2\2"+
+ "\u013fB\3\2\2\2\u0140\u0141\7y\2\2\u0141\u0142\7j\2\2\u0142\u0143\7k\2"+
+ "\2\u0143\u0144\7n\2\2\u0144\u0145\7g\2\2\u0145D\3\2\2\2\u0146\u0147\7"+
+ "d\2\2\u0147\u0148\7t\2\2\u0148\u0149\7g\2\2\u0149\u014a\7c\2\2\u014a\u014b"+
+ "\7m\2\2\u014bF\3\2\2\2\u014c\u014d\7r\2\2\u014d\u014e\7t\2\2\u014e\u014f"+
+ "\7k\2\2\u014f\u0150\7p\2\2\u0150\u0151\7v\2\2\u0151H\3\2\2\2\u0152\u0153"+
+ "\7<\2\2\u0153\u0154\7?\2\2\u0154J\3\2\2\2\u0155\u0156\7-\2\2\u0156L\3"+
+ "\2\2\2\u0157\u0158\7/\2\2\u0158N\3\2\2\2\u0159\u015a\7,\2\2\u015aP\3\2"+
+ "\2\2\u015b\u015c\7\61\2\2\u015cR\3\2\2\2\u015d\u015e\7(\2\2\u015e\u015f"+
+ "\7(\2\2\u015fT\3\2\2\2\u0160\u0161\7~\2\2\u0161\u0162\7~\2\2\u0162V\3"+
+ "\2\2\2\u0163\u0164\7>\2\2\u0164X\3\2\2\2\u0165\u0166\7>\2\2\u0166\u0167"+
+ "\7?\2\2\u0167Z\3\2\2\2\u0168\u0169\7@\2\2\u0169\\\3\2\2\2\u016a\u016b"+
+ "\7@\2\2\u016b\u016c\7?\2\2\u016c^\3\2\2\2\u016d\u016e\7?\2\2\u016e\u016f"+
+ "\7?\2\2\u016f`\3\2\2\2\u0170\u0171\7#\2\2\u0171\u0172\7?\2\2\u0172b\3"+
+ "\2\2\2\u0173\u0176\5g\64\2\u0174\u0176\5e\63\2\u0175\u0173\3\2\2\2\u0175"+
+ "\u0174\3\2\2\2\u0176d\3\2\2\2\u0177\u0178\5g\64\2\u0178\u017a\7\60\2\2"+
+ "\u0179\u017b\4\62;\2\u017a\u0179\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u017a"+
+ "\3\2\2\2\u017c\u017d\3\2\2\2\u017df\3\2\2\2\u017e\u0180\t\2\2\2\u017f"+
+ "\u017e\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2\2\2\u0181\u0183\4\62"+
+ ";\2\u0182\u0181\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0182\3\2\2\2\u0184"+
+ "\u0185\3\2\2\2\u0185h\3\2\2\2\u0186\u018c\5k\66\2\u0187\u018b\5k\66\2"+
+ "\u0188\u018b\5q9\2\u0189\u018b\7a\2\2\u018a\u0187\3\2\2\2\u018a\u0188"+
+ "\3\2\2\2\u018a\u0189\3\2\2\2\u018b\u018e\3\2\2\2\u018c\u018a\3\2\2\2\u018c"+
+ "\u018d\3\2\2\2\u018dj\3\2\2\2\u018e\u018c\3\2\2\2\u018f\u0192\5m\67\2"+
+ "\u0190\u0192\5o8\2\u0191\u018f\3\2\2\2\u0191\u0190\3\2\2\2\u0192l\3\2"+
+ "\2\2\u0193\u0194\4c|\2\u0194n\3\2\2\2\u0195\u0196\4C\\\2\u0196p\3\2\2"+
+ "\2\u0197\u0198\4\62;\2\u0198r\3\2\2\2\u0199\u019a\7*\2\2\u019at\3\2\2"+
+ "\2\u019b\u019c\7+\2\2\u019cv\3\2\2\2\u019d\u019e\7}\2\2\u019ex\3\2\2\2"+
+ "\u019f\u01a0\7\177\2\2\u01a0z\3\2\2\2\u01a1\u01a2\7<\2\2\u01a2|\3\2\2"+
+ "\2\u01a3\u01a5\t\3\2\2\u01a4\u01a3\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a4"+
+ "\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\b?\2\2\u01a9"+
+ "~\3\2\2\2\u01aa\u01ab\7\61\2\2\u01ab\u01ac\7\61\2\2\u01ac\u01b0\3\2\2"+
+ "\2\u01ad\u01af\n\4\2\2\u01ae\u01ad\3\2\2\2\u01af\u01b2\3\2\2\2\u01b0\u01ae"+
+ "\3\2\2\2\u01b0\u01b1\3\2\2\2\u01b1\u01b3\3\2\2\2\u01b2\u01b0\3\2\2\2\u01b3"+
+ "\u01b4\5\u0081A\2\u01b4\u01b5\3\2\2\2\u01b5\u01b6\b@\2\2\u01b6\u0080\3"+
+ "\2\2\2\u01b7\u01b9\7\17\2\2\u01b8\u01b7\3\2\2\2\u01b8\u01b9\3\2\2\2\u01b9"+
+ "\u01ba\3\2\2\2\u01ba\u01bc\7\f\2\2\u01bb\u01b8\3\2\2\2\u01bc\u01bd\3\2"+
+ "\2\2\u01bd\u01bb\3\2\2\2\u01bd\u01be\3\2\2\2\u01be\u0082\3\2\2\2\16\2"+
+ "\u0175\u017c\u017f\u0184\u018a\u018c\u0191\u01a6\u01b0\u01b8\u01bd\3\b"+
+ "\2\2";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.tokens b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.tokens
new file mode 100755
index 0000000..a4780f1
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramLexer.tokens
@@ -0,0 +1,112 @@
+T__0=1
+NULL=2
+SELF=3
+TRUE=4
+FALSE=5
+SQRT=6
+SIN=7
+COS=8
+NOT=9
+GETX=10
+GETY=11
+GETRADIUS=12
+GETDIR=13
+GETAP=14
+GETMAXAP=15
+GETHP=16
+SAMETEAM=17
+SEARCHOBJ=18
+DISTANCE=19
+ISWORM=20
+ISFOOD=21
+ISPROJECTILE=22
+TURN=23
+MOVE=24
+JUMP=25
+EAT=26
+FIRE=27
+DEF=28
+IF=29
+INVOKE=30
+THEN=31
+ELSE=32
+WHILE=33
+BREAK=34
+PRINT=35
+ASSIGN=36
+ADD=37
+SUB=38
+MUL=39
+DIV=40
+AND=41
+OR=42
+LT=43
+LTE=44
+GT=45
+GTE=46
+EQ=47
+NEQ=48
+NUMBER=49
+FLOAT=50
+INTEGER=51
+IDENTIFIER=52
+LEFT_PAREN=53
+RIGHT_PAREN=54
+LEFT_BRACE=55
+RIGHT_BRACE=56
+COLON=57
+WHITESPACE=58
+SINGLE_COMMENT=59
+';'=1
+'null'=2
+'self'=3
+'true'=4
+'false'=5
+'sqrt'=6
+'sin'=7
+'cos'=8
+'!'=9
+'getx'=10
+'gety'=11
+'getradius'=12
+'getdir'=13
+'getap'=14
+'getmaxap'=15
+'gethp'=16
+'sameteam'=17
+'searchobj'=18
+'distance'=19
+'isworm'=20
+'isfood'=21
+'isprojectile'=22
+'turn'=23
+'move'=24
+'jump'=25
+'eat'=26
+'fire'=27
+'def'=28
+'if'=29
+'invoke'=30
+'then'=31
+'else'=32
+'while'=33
+'break'=34
+'print'=35
+':='=36
+'+'=37
+'-'=38
+'*'=39
+'/'=40
+'&&'=41
+'||'=42
+'<'=43
+'<='=44
+'>'=45
+'>='=46
+'=='=47
+'!='=48
+'('=53
+')'=54
+'{'=55
+'}'=56
+':'=57
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramParser.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramParser.java
new file mode 100755
index 0000000..ba4c1e0
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramParser.java
@@ -0,0 +1,1757 @@
+// Generated from WormsProgram.g4 by ANTLR 4.7.1
+
+ package worms.programs.internal.parser.generated;
+
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.misc.*;
+import org.antlr.v4.runtime.tree.*;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
+public class WormsProgramParser extends Parser {
+ static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
+ public static final int
+ T__0=1, NULL=2, SELF=3, TRUE=4, FALSE=5, SQRT=6, SIN=7, COS=8, NOT=9,
+ GETX=10, GETY=11, GETRADIUS=12, GETDIR=13, GETAP=14, GETMAXAP=15, GETHP=16,
+ SAMETEAM=17, SEARCHOBJ=18, DISTANCE=19, ISWORM=20, ISFOOD=21, ISPROJECTILE=22,
+ TURN=23, MOVE=24, JUMP=25, EAT=26, FIRE=27, DEF=28, IF=29, INVOKE=30,
+ THEN=31, ELSE=32, WHILE=33, BREAK=34, PRINT=35, ASSIGN=36, ADD=37, SUB=38,
+ MUL=39, DIV=40, AND=41, OR=42, LT=43, LTE=44, GT=45, GTE=46, EQ=47, NEQ=48,
+ NUMBER=49, FLOAT=50, INTEGER=51, IDENTIFIER=52, LEFT_PAREN=53, RIGHT_PAREN=54,
+ LEFT_BRACE=55, RIGHT_BRACE=56, COLON=57, WHITESPACE=58, SINGLE_COMMENT=59;
+ public static final int
+ RULE_program = 0, RULE_proceduredef = 1, RULE_statement = 2, RULE_assignmentStatement = 3,
+ RULE_whileStatement = 4, RULE_ifStatement = 5, RULE_printStatement = 6,
+ RULE_sequenceStatement = 7, RULE_invokeStatement = 8, RULE_breakStatement = 9,
+ RULE_actionStatement = 10, RULE_expression = 11;
+ public static final String[] ruleNames = {
+ "program", "proceduredef", "statement", "assignmentStatement", "whileStatement",
+ "ifStatement", "printStatement", "sequenceStatement", "invokeStatement",
+ "breakStatement", "actionStatement", "expression"
+ };
+
+ private static final String[] _LITERAL_NAMES = {
+ null, "';'", "'null'", "'self'", "'true'", "'false'", "'sqrt'", "'sin'",
+ "'cos'", "'!'", "'getx'", "'gety'", "'getradius'", "'getdir'", "'getap'",
+ "'getmaxap'", "'gethp'", "'sameteam'", "'searchobj'", "'distance'", "'isworm'",
+ "'isfood'", "'isprojectile'", "'turn'", "'move'", "'jump'", "'eat'", "'fire'",
+ "'def'", "'if'", "'invoke'", "'then'", "'else'", "'while'", "'break'",
+ "'print'", "':='", "'+'", "'-'", "'*'", "'/'", "'&&'", "'||'", "'<'",
+ "'<='", "'>'", "'>='", "'=='", "'!='", null, null, null, null, "'('",
+ "')'", "'{'", "'}'", "':'"
+ };
+ private static final String[] _SYMBOLIC_NAMES = {
+ null, null, "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
+ "GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
+ "SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
+ "JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
+ "BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
+ "LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
+ "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE", "RIGHT_BRACE", "COLON", "WHITESPACE",
+ "SINGLE_COMMENT"
+ };
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+ @Override
+ public String getGrammarFileName() { return "WormsProgram.g4"; }
+
+ @Override
+ public String[] getRuleNames() { return ruleNames; }
+
+ @Override
+ public String getSerializedATN() { return _serializedATN; }
+
+ @Override
+ public ATN getATN() { return _ATN; }
+
+ public WormsProgramParser(TokenStream input) {
+ super(input);
+ _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+ }
+ public static class ProgramContext extends ParserRuleContext {
+ public ProceduredefContext proceduredef;
+ public List procdef = new ArrayList();
+ public StatementContext statement;
+ public List programBody = new ArrayList();
+ public List proceduredef() {
+ return getRuleContexts(ProceduredefContext.class);
+ }
+ public ProceduredefContext proceduredef(int i) {
+ return getRuleContext(ProceduredefContext.class,i);
+ }
+ public List statement() {
+ return getRuleContexts(StatementContext.class);
+ }
+ public StatementContext statement(int i) {
+ return getRuleContext(StatementContext.class,i);
+ }
+ public ProgramContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_program; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitProgram(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ProgramContext program() throws RecognitionException {
+ ProgramContext _localctx = new ProgramContext(_ctx, getState());
+ enterRule(_localctx, 0, RULE_program);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(27);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==DEF) {
+ {
+ {
+ setState(24);
+ ((ProgramContext)_localctx).proceduredef = proceduredef();
+ ((ProgramContext)_localctx).procdef.add(((ProgramContext)_localctx).proceduredef);
+ }
+ }
+ setState(29);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ setState(33);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TURN) | (1L << MOVE) | (1L << JUMP) | (1L << EAT) | (1L << FIRE) | (1L << IF) | (1L << INVOKE) | (1L << WHILE) | (1L << BREAK) | (1L << PRINT) | (1L << IDENTIFIER) | (1L << LEFT_BRACE))) != 0)) {
+ {
+ {
+ setState(30);
+ ((ProgramContext)_localctx).statement = statement();
+ ((ProgramContext)_localctx).programBody.add(((ProgramContext)_localctx).statement);
+ }
+ }
+ setState(35);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class ProceduredefContext extends ParserRuleContext {
+ public Token procname;
+ public StatementContext body;
+ public TerminalNode DEF() { return getToken(WormsProgramParser.DEF, 0); }
+ public TerminalNode IDENTIFIER() { return getToken(WormsProgramParser.IDENTIFIER, 0); }
+ public StatementContext statement() {
+ return getRuleContext(StatementContext.class,0);
+ }
+ public TerminalNode COLON() { return getToken(WormsProgramParser.COLON, 0); }
+ public ProceduredefContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_proceduredef; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitProceduredef(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ProceduredefContext proceduredef() throws RecognitionException {
+ ProceduredefContext _localctx = new ProceduredefContext(_ctx, getState());
+ enterRule(_localctx, 2, RULE_proceduredef);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(36);
+ match(DEF);
+ setState(37);
+ ((ProceduredefContext)_localctx).procname = match(IDENTIFIER);
+ setState(39);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==COLON) {
+ {
+ setState(38);
+ match(COLON);
+ }
+ }
+
+ setState(41);
+ ((ProceduredefContext)_localctx).body = statement();
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class StatementContext extends ParserRuleContext {
+ public AssignmentStatementContext assignmentStatement() {
+ return getRuleContext(AssignmentStatementContext.class,0);
+ }
+ public WhileStatementContext whileStatement() {
+ return getRuleContext(WhileStatementContext.class,0);
+ }
+ public IfStatementContext ifStatement() {
+ return getRuleContext(IfStatementContext.class,0);
+ }
+ public PrintStatementContext printStatement() {
+ return getRuleContext(PrintStatementContext.class,0);
+ }
+ public SequenceStatementContext sequenceStatement() {
+ return getRuleContext(SequenceStatementContext.class,0);
+ }
+ public InvokeStatementContext invokeStatement() {
+ return getRuleContext(InvokeStatementContext.class,0);
+ }
+ public BreakStatementContext breakStatement() {
+ return getRuleContext(BreakStatementContext.class,0);
+ }
+ public ActionStatementContext actionStatement() {
+ return getRuleContext(ActionStatementContext.class,0);
+ }
+ public StatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_statement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final StatementContext statement() throws RecognitionException {
+ StatementContext _localctx = new StatementContext(_ctx, getState());
+ enterRule(_localctx, 4, RULE_statement);
+ try {
+ setState(51);
+ _errHandler.sync(this);
+ switch (_input.LA(1)) {
+ case IDENTIFIER:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(43);
+ assignmentStatement();
+ }
+ break;
+ case WHILE:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(44);
+ whileStatement();
+ }
+ break;
+ case IF:
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(45);
+ ifStatement();
+ }
+ break;
+ case PRINT:
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(46);
+ printStatement();
+ }
+ break;
+ case LEFT_BRACE:
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(47);
+ sequenceStatement();
+ }
+ break;
+ case INVOKE:
+ enterOuterAlt(_localctx, 6);
+ {
+ setState(48);
+ invokeStatement();
+ }
+ break;
+ case BREAK:
+ enterOuterAlt(_localctx, 7);
+ {
+ setState(49);
+ breakStatement();
+ }
+ break;
+ case TURN:
+ case MOVE:
+ case JUMP:
+ case EAT:
+ case FIRE:
+ enterOuterAlt(_localctx, 8);
+ {
+ setState(50);
+ actionStatement();
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class AssignmentStatementContext extends ParserRuleContext {
+ public Token variableName;
+ public ExpressionContext value;
+ public TerminalNode ASSIGN() { return getToken(WormsProgramParser.ASSIGN, 0); }
+ public TerminalNode IDENTIFIER() { return getToken(WormsProgramParser.IDENTIFIER, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public AssignmentStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_assignmentStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitAssignmentStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final AssignmentStatementContext assignmentStatement() throws RecognitionException {
+ AssignmentStatementContext _localctx = new AssignmentStatementContext(_ctx, getState());
+ enterRule(_localctx, 6, RULE_assignmentStatement);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(53);
+ ((AssignmentStatementContext)_localctx).variableName = match(IDENTIFIER);
+ setState(54);
+ match(ASSIGN);
+ setState(55);
+ ((AssignmentStatementContext)_localctx).value = expression(0);
+ setState(56);
+ match(T__0);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class WhileStatementContext extends ParserRuleContext {
+ public ExpressionContext condition;
+ public StatementContext body;
+ public TerminalNode WHILE() { return getToken(WormsProgramParser.WHILE, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public StatementContext statement() {
+ return getRuleContext(StatementContext.class,0);
+ }
+ public TerminalNode COLON() { return getToken(WormsProgramParser.COLON, 0); }
+ public WhileStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_whileStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitWhileStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final WhileStatementContext whileStatement() throws RecognitionException {
+ WhileStatementContext _localctx = new WhileStatementContext(_ctx, getState());
+ enterRule(_localctx, 8, RULE_whileStatement);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(58);
+ match(WHILE);
+ setState(59);
+ ((WhileStatementContext)_localctx).condition = expression(0);
+ setState(61);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==COLON) {
+ {
+ setState(60);
+ match(COLON);
+ }
+ }
+
+ setState(63);
+ ((WhileStatementContext)_localctx).body = statement();
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class IfStatementContext extends ParserRuleContext {
+ public ExpressionContext condition;
+ public StatementContext ifbody;
+ public StatementContext elsebody;
+ public TerminalNode IF() { return getToken(WormsProgramParser.IF, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public List statement() {
+ return getRuleContexts(StatementContext.class);
+ }
+ public StatementContext statement(int i) {
+ return getRuleContext(StatementContext.class,i);
+ }
+ public List COLON() { return getTokens(WormsProgramParser.COLON); }
+ public TerminalNode COLON(int i) {
+ return getToken(WormsProgramParser.COLON, i);
+ }
+ public TerminalNode ELSE() { return getToken(WormsProgramParser.ELSE, 0); }
+ public IfStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_ifStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitIfStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final IfStatementContext ifStatement() throws RecognitionException {
+ IfStatementContext _localctx = new IfStatementContext(_ctx, getState());
+ enterRule(_localctx, 10, RULE_ifStatement);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(65);
+ match(IF);
+ setState(66);
+ ((IfStatementContext)_localctx).condition = expression(0);
+ setState(68);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==COLON) {
+ {
+ setState(67);
+ match(COLON);
+ }
+ }
+
+ setState(70);
+ ((IfStatementContext)_localctx).ifbody = statement();
+ setState(76);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
+ case 1:
+ {
+ setState(71);
+ match(ELSE);
+ setState(73);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==COLON) {
+ {
+ setState(72);
+ match(COLON);
+ }
+ }
+
+ setState(75);
+ ((IfStatementContext)_localctx).elsebody = statement();
+ }
+ break;
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class PrintStatementContext extends ParserRuleContext {
+ public ExpressionContext value;
+ public TerminalNode PRINT() { return getToken(WormsProgramParser.PRINT, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public PrintStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_printStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitPrintStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final PrintStatementContext printStatement() throws RecognitionException {
+ PrintStatementContext _localctx = new PrintStatementContext(_ctx, getState());
+ enterRule(_localctx, 12, RULE_printStatement);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(78);
+ match(PRINT);
+ setState(79);
+ ((PrintStatementContext)_localctx).value = expression(0);
+ setState(80);
+ match(T__0);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class SequenceStatementContext extends ParserRuleContext {
+ public StatementContext statement;
+ public List stmts = new ArrayList();
+ public TerminalNode LEFT_BRACE() { return getToken(WormsProgramParser.LEFT_BRACE, 0); }
+ public TerminalNode RIGHT_BRACE() { return getToken(WormsProgramParser.RIGHT_BRACE, 0); }
+ public List statement() {
+ return getRuleContexts(StatementContext.class);
+ }
+ public StatementContext statement(int i) {
+ return getRuleContext(StatementContext.class,i);
+ }
+ public SequenceStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_sequenceStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSequenceStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final SequenceStatementContext sequenceStatement() throws RecognitionException {
+ SequenceStatementContext _localctx = new SequenceStatementContext(_ctx, getState());
+ enterRule(_localctx, 14, RULE_sequenceStatement);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(82);
+ match(LEFT_BRACE);
+ setState(86);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TURN) | (1L << MOVE) | (1L << JUMP) | (1L << EAT) | (1L << FIRE) | (1L << IF) | (1L << INVOKE) | (1L << WHILE) | (1L << BREAK) | (1L << PRINT) | (1L << IDENTIFIER) | (1L << LEFT_BRACE))) != 0)) {
+ {
+ {
+ setState(83);
+ ((SequenceStatementContext)_localctx).statement = statement();
+ ((SequenceStatementContext)_localctx).stmts.add(((SequenceStatementContext)_localctx).statement);
+ }
+ }
+ setState(88);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ setState(89);
+ match(RIGHT_BRACE);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class InvokeStatementContext extends ParserRuleContext {
+ public Token procName;
+ public TerminalNode INVOKE() { return getToken(WormsProgramParser.INVOKE, 0); }
+ public TerminalNode IDENTIFIER() { return getToken(WormsProgramParser.IDENTIFIER, 0); }
+ public InvokeStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_invokeStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitInvokeStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final InvokeStatementContext invokeStatement() throws RecognitionException {
+ InvokeStatementContext _localctx = new InvokeStatementContext(_ctx, getState());
+ enterRule(_localctx, 16, RULE_invokeStatement);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(91);
+ match(INVOKE);
+ setState(92);
+ ((InvokeStatementContext)_localctx).procName = match(IDENTIFIER);
+ setState(93);
+ match(T__0);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class BreakStatementContext extends ParserRuleContext {
+ public TerminalNode BREAK() { return getToken(WormsProgramParser.BREAK, 0); }
+ public BreakStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_breakStatement; }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitBreakStatement(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final BreakStatementContext breakStatement() throws RecognitionException {
+ BreakStatementContext _localctx = new BreakStatementContext(_ctx, getState());
+ enterRule(_localctx, 18, RULE_breakStatement);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(95);
+ match(BREAK);
+ setState(96);
+ match(T__0);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class ActionStatementContext extends ParserRuleContext {
+ public ActionStatementContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_actionStatement; }
+
+ public ActionStatementContext() { }
+ public void copyFrom(ActionStatementContext ctx) {
+ super.copyFrom(ctx);
+ }
+ }
+ public static class MoveActionContext extends ActionStatementContext {
+ public TerminalNode MOVE() { return getToken(WormsProgramParser.MOVE, 0); }
+ public MoveActionContext(ActionStatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitMoveAction(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class TurnActionContext extends ActionStatementContext {
+ public ExpressionContext angle;
+ public TerminalNode TURN() { return getToken(WormsProgramParser.TURN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public TurnActionContext(ActionStatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitTurnAction(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class EatActionContext extends ActionStatementContext {
+ public TerminalNode EAT() { return getToken(WormsProgramParser.EAT, 0); }
+ public EatActionContext(ActionStatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitEatAction(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class FireActionContext extends ActionStatementContext {
+ public TerminalNode FIRE() { return getToken(WormsProgramParser.FIRE, 0); }
+ public FireActionContext(ActionStatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitFireAction(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class JumpActionContext extends ActionStatementContext {
+ public TerminalNode JUMP() { return getToken(WormsProgramParser.JUMP, 0); }
+ public JumpActionContext(ActionStatementContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitJumpAction(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ActionStatementContext actionStatement() throws RecognitionException {
+ ActionStatementContext _localctx = new ActionStatementContext(_ctx, getState());
+ enterRule(_localctx, 20, RULE_actionStatement);
+ try {
+ setState(110);
+ _errHandler.sync(this);
+ switch (_input.LA(1)) {
+ case TURN:
+ _localctx = new TurnActionContext(_localctx);
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(98);
+ match(TURN);
+ setState(99);
+ ((TurnActionContext)_localctx).angle = expression(0);
+ setState(100);
+ match(T__0);
+ }
+ break;
+ case MOVE:
+ _localctx = new MoveActionContext(_localctx);
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(102);
+ match(MOVE);
+ setState(103);
+ match(T__0);
+ }
+ break;
+ case JUMP:
+ _localctx = new JumpActionContext(_localctx);
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(104);
+ match(JUMP);
+ setState(105);
+ match(T__0);
+ }
+ break;
+ case EAT:
+ _localctx = new EatActionContext(_localctx);
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(106);
+ match(EAT);
+ setState(107);
+ match(T__0);
+ }
+ break;
+ case FIRE:
+ _localctx = new FireActionContext(_localctx);
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(108);
+ match(FIRE);
+ setState(109);
+ match(T__0);
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static class ExpressionContext extends ParserRuleContext {
+ public ExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_expression; }
+
+ public ExpressionContext() { }
+ public void copyFrom(ExpressionContext ctx) {
+ super.copyFrom(ctx);
+ }
+ }
+ public static class DistanceExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode DISTANCE() { return getToken(WormsProgramParser.DISTANCE, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public DistanceExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitDistanceExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class CosExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode COS() { return getToken(WormsProgramParser.COS, 0); }
+ public TerminalNode LEFT_PAREN() { return getToken(WormsProgramParser.LEFT_PAREN, 0); }
+ public TerminalNode RIGHT_PAREN() { return getToken(WormsProgramParser.RIGHT_PAREN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public CosExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitCosExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetYExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETY() { return getToken(WormsProgramParser.GETY, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetYExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetYExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class AndOrExpressionContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List expression() {
+ return getRuleContexts(ExpressionContext.class);
+ }
+ public ExpressionContext expression(int i) {
+ return getRuleContext(ExpressionContext.class,i);
+ }
+ public TerminalNode AND() { return getToken(WormsProgramParser.AND, 0); }
+ public TerminalNode OR() { return getToken(WormsProgramParser.OR, 0); }
+ public AndOrExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitAndOrExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class IsWormExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode ISWORM() { return getToken(WormsProgramParser.ISWORM, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public IsWormExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitIsWormExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class NotExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode NOT() { return getToken(WormsProgramParser.NOT, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public NotExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitNotExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ComparisonExpressionContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List expression() {
+ return getRuleContexts(ExpressionContext.class);
+ }
+ public ExpressionContext expression(int i) {
+ return getRuleContext(ExpressionContext.class,i);
+ }
+ public TerminalNode LT() { return getToken(WormsProgramParser.LT, 0); }
+ public TerminalNode LTE() { return getToken(WormsProgramParser.LTE, 0); }
+ public TerminalNode GT() { return getToken(WormsProgramParser.GT, 0); }
+ public TerminalNode GTE() { return getToken(WormsProgramParser.GTE, 0); }
+ public TerminalNode EQ() { return getToken(WormsProgramParser.EQ, 0); }
+ public TerminalNode NEQ() { return getToken(WormsProgramParser.NEQ, 0); }
+ public ComparisonExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitComparisonExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ParenExpressionContext extends ExpressionContext {
+ public ExpressionContext subExpr;
+ public TerminalNode LEFT_PAREN() { return getToken(WormsProgramParser.LEFT_PAREN, 0); }
+ public TerminalNode RIGHT_PAREN() { return getToken(WormsProgramParser.RIGHT_PAREN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public ParenExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitParenExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetRadiusExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETRADIUS() { return getToken(WormsProgramParser.GETRADIUS, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetRadiusExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetRadiusExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class TrueLiteralExpressionContext extends ExpressionContext {
+ public TerminalNode TRUE() { return getToken(WormsProgramParser.TRUE, 0); }
+ public TrueLiteralExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitTrueLiteralExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class NullExpressionContext extends ExpressionContext {
+ public TerminalNode NULL() { return getToken(WormsProgramParser.NULL, 0); }
+ public NullExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitNullExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class SqrtExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode SQRT() { return getToken(WormsProgramParser.SQRT, 0); }
+ public TerminalNode LEFT_PAREN() { return getToken(WormsProgramParser.LEFT_PAREN, 0); }
+ public TerminalNode RIGHT_PAREN() { return getToken(WormsProgramParser.RIGHT_PAREN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public SqrtExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSqrtExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class SinExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode SIN() { return getToken(WormsProgramParser.SIN, 0); }
+ public TerminalNode LEFT_PAREN() { return getToken(WormsProgramParser.LEFT_PAREN, 0); }
+ public TerminalNode RIGHT_PAREN() { return getToken(WormsProgramParser.RIGHT_PAREN, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public SinExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSinExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class SameTeamExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode SAMETEAM() { return getToken(WormsProgramParser.SAMETEAM, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public SameTeamExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSameTeamExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class IsProjectileExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode ISPROJECTILE() { return getToken(WormsProgramParser.ISPROJECTILE, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public IsProjectileExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitIsProjectileExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class IsFoodExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode ISFOOD() { return getToken(WormsProgramParser.ISFOOD, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public IsFoodExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitIsFoodExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ConstantExpressionContext extends ExpressionContext {
+ public Token value;
+ public TerminalNode NUMBER() { return getToken(WormsProgramParser.NUMBER, 0); }
+ public ConstantExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitConstantExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class SearchObjExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode SEARCHOBJ() { return getToken(WormsProgramParser.SEARCHOBJ, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public SearchObjExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSearchObjExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetXExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETX() { return getToken(WormsProgramParser.GETX, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetXExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetXExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class ReadVariableExpressionContext extends ExpressionContext {
+ public Token variable;
+ public TerminalNode IDENTIFIER() { return getToken(WormsProgramParser.IDENTIFIER, 0); }
+ public ReadVariableExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitReadVariableExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class MulDivExpressionContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List expression() {
+ return getRuleContexts(ExpressionContext.class);
+ }
+ public ExpressionContext expression(int i) {
+ return getRuleContext(ExpressionContext.class,i);
+ }
+ public TerminalNode MUL() { return getToken(WormsProgramParser.MUL, 0); }
+ public TerminalNode DIV() { return getToken(WormsProgramParser.DIV, 0); }
+ public MulDivExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitMulDivExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetDirectionExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETDIR() { return getToken(WormsProgramParser.GETDIR, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetDirectionExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetDirectionExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class SelfExpressionContext extends ExpressionContext {
+ public TerminalNode SELF() { return getToken(WormsProgramParser.SELF, 0); }
+ public SelfExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitSelfExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetHPExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETHP() { return getToken(WormsProgramParser.GETHP, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetHPExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetHPExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class AddSubExpressionContext extends ExpressionContext {
+ public ExpressionContext left;
+ public Token op;
+ public ExpressionContext right;
+ public List expression() {
+ return getRuleContexts(ExpressionContext.class);
+ }
+ public ExpressionContext expression(int i) {
+ return getRuleContext(ExpressionContext.class,i);
+ }
+ public TerminalNode ADD() { return getToken(WormsProgramParser.ADD, 0); }
+ public TerminalNode SUB() { return getToken(WormsProgramParser.SUB, 0); }
+ public AddSubExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitAddSubExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetMaxAPExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETMAXAP() { return getToken(WormsProgramParser.GETMAXAP, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetMaxAPExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetMaxAPExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class GetAPExpressionContext extends ExpressionContext {
+ public ExpressionContext expr;
+ public TerminalNode GETAP() { return getToken(WormsProgramParser.GETAP, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public GetAPExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitGetAPExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+ public static class FalseLiteralExpressionContext extends ExpressionContext {
+ public TerminalNode FALSE() { return getToken(WormsProgramParser.FALSE, 0); }
+ public FalseLiteralExpressionContext(ExpressionContext ctx) { copyFrom(ctx); }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof WormsProgramVisitor ) return ((WormsProgramVisitor extends T>)visitor).visitFalseLiteralExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ExpressionContext expression() throws RecognitionException {
+ return expression(0);
+ }
+
+ private ExpressionContext expression(int _p) throws RecognitionException {
+ ParserRuleContext _parentctx = _ctx;
+ int _parentState = getState();
+ ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState);
+ ExpressionContext _prevctx = _localctx;
+ int _startState = 22;
+ enterRecursionRule(_localctx, 22, RULE_expression, _p);
+ int _la;
+ try {
+ int _alt;
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(166);
+ _errHandler.sync(this);
+ switch (_input.LA(1)) {
+ case IDENTIFIER:
+ {
+ _localctx = new ReadVariableExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+
+ setState(113);
+ ((ReadVariableExpressionContext)_localctx).variable = match(IDENTIFIER);
+ }
+ break;
+ case NUMBER:
+ {
+ _localctx = new ConstantExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(114);
+ ((ConstantExpressionContext)_localctx).value = match(NUMBER);
+ }
+ break;
+ case TRUE:
+ {
+ _localctx = new TrueLiteralExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(115);
+ match(TRUE);
+ }
+ break;
+ case FALSE:
+ {
+ _localctx = new FalseLiteralExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(116);
+ match(FALSE);
+ }
+ break;
+ case NULL:
+ {
+ _localctx = new NullExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(117);
+ match(NULL);
+ }
+ break;
+ case SELF:
+ {
+ _localctx = new SelfExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(118);
+ match(SELF);
+ }
+ break;
+ case LEFT_PAREN:
+ {
+ _localctx = new ParenExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(119);
+ match(LEFT_PAREN);
+ setState(120);
+ ((ParenExpressionContext)_localctx).subExpr = expression(0);
+ setState(121);
+ match(RIGHT_PAREN);
+ }
+ break;
+ case SQRT:
+ {
+ _localctx = new SqrtExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(123);
+ match(SQRT);
+ setState(124);
+ match(LEFT_PAREN);
+ setState(125);
+ ((SqrtExpressionContext)_localctx).expr = expression(0);
+ setState(126);
+ match(RIGHT_PAREN);
+ }
+ break;
+ case SIN:
+ {
+ _localctx = new SinExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(128);
+ match(SIN);
+ setState(129);
+ match(LEFT_PAREN);
+ setState(130);
+ ((SinExpressionContext)_localctx).expr = expression(0);
+ setState(131);
+ match(RIGHT_PAREN);
+ }
+ break;
+ case COS:
+ {
+ _localctx = new CosExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(133);
+ match(COS);
+ setState(134);
+ match(LEFT_PAREN);
+ setState(135);
+ ((CosExpressionContext)_localctx).expr = expression(0);
+ setState(136);
+ match(RIGHT_PAREN);
+ }
+ break;
+ case NOT:
+ {
+ _localctx = new NotExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(138);
+ match(NOT);
+ setState(139);
+ ((NotExpressionContext)_localctx).expr = expression(14);
+ }
+ break;
+ case GETX:
+ {
+ _localctx = new GetXExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(140);
+ match(GETX);
+ setState(141);
+ ((GetXExpressionContext)_localctx).expr = expression(13);
+ }
+ break;
+ case GETY:
+ {
+ _localctx = new GetYExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(142);
+ match(GETY);
+ setState(143);
+ ((GetYExpressionContext)_localctx).expr = expression(12);
+ }
+ break;
+ case GETRADIUS:
+ {
+ _localctx = new GetRadiusExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(144);
+ match(GETRADIUS);
+ setState(145);
+ ((GetRadiusExpressionContext)_localctx).expr = expression(11);
+ }
+ break;
+ case GETDIR:
+ {
+ _localctx = new GetDirectionExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(146);
+ match(GETDIR);
+ setState(147);
+ ((GetDirectionExpressionContext)_localctx).expr = expression(10);
+ }
+ break;
+ case GETAP:
+ {
+ _localctx = new GetAPExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(148);
+ match(GETAP);
+ setState(149);
+ ((GetAPExpressionContext)_localctx).expr = expression(9);
+ }
+ break;
+ case GETMAXAP:
+ {
+ _localctx = new GetMaxAPExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(150);
+ match(GETMAXAP);
+ setState(151);
+ ((GetMaxAPExpressionContext)_localctx).expr = expression(8);
+ }
+ break;
+ case GETHP:
+ {
+ _localctx = new GetHPExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(152);
+ match(GETHP);
+ setState(153);
+ ((GetHPExpressionContext)_localctx).expr = expression(7);
+ }
+ break;
+ case SAMETEAM:
+ {
+ _localctx = new SameTeamExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(154);
+ match(SAMETEAM);
+ setState(155);
+ ((SameTeamExpressionContext)_localctx).expr = expression(6);
+ }
+ break;
+ case SEARCHOBJ:
+ {
+ _localctx = new SearchObjExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(156);
+ match(SEARCHOBJ);
+ setState(157);
+ ((SearchObjExpressionContext)_localctx).expr = expression(5);
+ }
+ break;
+ case DISTANCE:
+ {
+ _localctx = new DistanceExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(158);
+ match(DISTANCE);
+ setState(159);
+ ((DistanceExpressionContext)_localctx).expr = expression(4);
+ }
+ break;
+ case ISWORM:
+ {
+ _localctx = new IsWormExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(160);
+ match(ISWORM);
+ setState(161);
+ ((IsWormExpressionContext)_localctx).expr = expression(3);
+ }
+ break;
+ case ISFOOD:
+ {
+ _localctx = new IsFoodExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(162);
+ match(ISFOOD);
+ setState(163);
+ ((IsFoodExpressionContext)_localctx).expr = expression(2);
+ }
+ break;
+ case ISPROJECTILE:
+ {
+ _localctx = new IsProjectileExpressionContext(_localctx);
+ _ctx = _localctx;
+ _prevctx = _localctx;
+ setState(164);
+ match(ISPROJECTILE);
+ setState(165);
+ ((IsProjectileExpressionContext)_localctx).expr = expression(1);
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
+ _ctx.stop = _input.LT(-1);
+ setState(182);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,12,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ if ( _parseListeners!=null ) triggerExitRuleEvent();
+ _prevctx = _localctx;
+ {
+ setState(180);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
+ case 1:
+ {
+ _localctx = new MulDivExpressionContext(new ExpressionContext(_parentctx, _parentState));
+ ((MulDivExpressionContext)_localctx).left = _prevctx;
+ pushNewRecursionContext(_localctx, _startState, RULE_expression);
+ setState(168);
+ if (!(precpred(_ctx, 21))) throw new FailedPredicateException(this, "precpred(_ctx, 21)");
+ setState(169);
+ ((MulDivExpressionContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !(_la==MUL || _la==DIV) ) {
+ ((MulDivExpressionContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(170);
+ ((MulDivExpressionContext)_localctx).right = expression(22);
+ }
+ break;
+ case 2:
+ {
+ _localctx = new AddSubExpressionContext(new ExpressionContext(_parentctx, _parentState));
+ ((AddSubExpressionContext)_localctx).left = _prevctx;
+ pushNewRecursionContext(_localctx, _startState, RULE_expression);
+ setState(171);
+ if (!(precpred(_ctx, 20))) throw new FailedPredicateException(this, "precpred(_ctx, 20)");
+ setState(172);
+ ((AddSubExpressionContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !(_la==ADD || _la==SUB) ) {
+ ((AddSubExpressionContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(173);
+ ((AddSubExpressionContext)_localctx).right = expression(21);
+ }
+ break;
+ case 3:
+ {
+ _localctx = new ComparisonExpressionContext(new ExpressionContext(_parentctx, _parentState));
+ ((ComparisonExpressionContext)_localctx).left = _prevctx;
+ pushNewRecursionContext(_localctx, _startState, RULE_expression);
+ setState(174);
+ if (!(precpred(_ctx, 19))) throw new FailedPredicateException(this, "precpred(_ctx, 19)");
+ setState(175);
+ ((ComparisonExpressionContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LT) | (1L << LTE) | (1L << GT) | (1L << GTE) | (1L << EQ) | (1L << NEQ))) != 0)) ) {
+ ((ComparisonExpressionContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(176);
+ ((ComparisonExpressionContext)_localctx).right = expression(20);
+ }
+ break;
+ case 4:
+ {
+ _localctx = new AndOrExpressionContext(new ExpressionContext(_parentctx, _parentState));
+ ((AndOrExpressionContext)_localctx).left = _prevctx;
+ pushNewRecursionContext(_localctx, _startState, RULE_expression);
+ setState(177);
+ if (!(precpred(_ctx, 18))) throw new FailedPredicateException(this, "precpred(_ctx, 18)");
+ setState(178);
+ ((AndOrExpressionContext)_localctx).op = _input.LT(1);
+ _la = _input.LA(1);
+ if ( !(_la==AND || _la==OR) ) {
+ ((AndOrExpressionContext)_localctx).op = (Token)_errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(179);
+ ((AndOrExpressionContext)_localctx).right = expression(19);
+ }
+ break;
+ }
+ }
+ }
+ setState(184);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,12,_ctx);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ unrollRecursionContexts(_parentctx);
+ }
+ return _localctx;
+ }
+
+ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
+ switch (ruleIndex) {
+ case 11:
+ return expression_sempred((ExpressionContext)_localctx, predIndex);
+ }
+ return true;
+ }
+ private boolean expression_sempred(ExpressionContext _localctx, int predIndex) {
+ switch (predIndex) {
+ case 0:
+ return precpred(_ctx, 21);
+ case 1:
+ return precpred(_ctx, 20);
+ case 2:
+ return precpred(_ctx, 19);
+ case 3:
+ return precpred(_ctx, 18);
+ }
+ return true;
+ }
+
+ public static final String _serializedATN =
+ "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3=\u00bc\4\2\t\2\4"+
+ "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
+ "\13\4\f\t\f\4\r\t\r\3\2\7\2\34\n\2\f\2\16\2\37\13\2\3\2\7\2\"\n\2\f\2"+
+ "\16\2%\13\2\3\3\3\3\3\3\5\3*\n\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+
+ "\4\5\4\66\n\4\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\5\6@\n\6\3\6\3\6\3\7\3\7"+
+ "\3\7\5\7G\n\7\3\7\3\7\3\7\5\7L\n\7\3\7\5\7O\n\7\3\b\3\b\3\b\3\b\3\t\3"+
+ "\t\7\tW\n\t\f\t\16\tZ\13\t\3\t\3\t\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\f"+
+ "\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\5\fq\n\f\3\r\3\r\3\r\3\r"+
+ "\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+
+ "\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r"+
+ "\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\5\r\u00a9"+
+ "\n\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\7\r\u00b7\n\r\f\r"+
+ "\16\r\u00ba\13\r\3\r\2\3\30\16\2\4\6\b\n\f\16\20\22\24\26\30\2\6\3\2)"+
+ "*\3\2\'(\3\2-\62\3\2+,\2\u00dd\2\35\3\2\2\2\4&\3\2\2\2\6\65\3\2\2\2\b"+
+ "\67\3\2\2\2\n<\3\2\2\2\fC\3\2\2\2\16P\3\2\2\2\20T\3\2\2\2\22]\3\2\2\2"+
+ "\24a\3\2\2\2\26p\3\2\2\2\30\u00a8\3\2\2\2\32\34\5\4\3\2\33\32\3\2\2\2"+
+ "\34\37\3\2\2\2\35\33\3\2\2\2\35\36\3\2\2\2\36#\3\2\2\2\37\35\3\2\2\2 "+
+ "\"\5\6\4\2! \3\2\2\2\"%\3\2\2\2#!\3\2\2\2#$\3\2\2\2$\3\3\2\2\2%#\3\2\2"+
+ "\2&\'\7\36\2\2\')\7\66\2\2(*\7;\2\2)(\3\2\2\2)*\3\2\2\2*+\3\2\2\2+,\5"+
+ "\6\4\2,\5\3\2\2\2-\66\5\b\5\2.\66\5\n\6\2/\66\5\f\7\2\60\66\5\16\b\2\61"+
+ "\66\5\20\t\2\62\66\5\22\n\2\63\66\5\24\13\2\64\66\5\26\f\2\65-\3\2\2\2"+
+ "\65.\3\2\2\2\65/\3\2\2\2\65\60\3\2\2\2\65\61\3\2\2\2\65\62\3\2\2\2\65"+
+ "\63\3\2\2\2\65\64\3\2\2\2\66\7\3\2\2\2\678\7\66\2\289\7&\2\29:\5\30\r"+
+ "\2:;\7\3\2\2;\t\3\2\2\2<=\7#\2\2=?\5\30\r\2>@\7;\2\2?>\3\2\2\2?@\3\2\2"+
+ "\2@A\3\2\2\2AB\5\6\4\2B\13\3\2\2\2CD\7\37\2\2DF\5\30\r\2EG\7;\2\2FE\3"+
+ "\2\2\2FG\3\2\2\2GH\3\2\2\2HN\5\6\4\2IK\7\"\2\2JL\7;\2\2KJ\3\2\2\2KL\3"+
+ "\2\2\2LM\3\2\2\2MO\5\6\4\2NI\3\2\2\2NO\3\2\2\2O\r\3\2\2\2PQ\7%\2\2QR\5"+
+ "\30\r\2RS\7\3\2\2S\17\3\2\2\2TX\79\2\2UW\5\6\4\2VU\3\2\2\2WZ\3\2\2\2X"+
+ "V\3\2\2\2XY\3\2\2\2Y[\3\2\2\2ZX\3\2\2\2[\\\7:\2\2\\\21\3\2\2\2]^\7 \2"+
+ "\2^_\7\66\2\2_`\7\3\2\2`\23\3\2\2\2ab\7$\2\2bc\7\3\2\2c\25\3\2\2\2de\7"+
+ "\31\2\2ef\5\30\r\2fg\7\3\2\2gq\3\2\2\2hi\7\32\2\2iq\7\3\2\2jk\7\33\2\2"+
+ "kq\7\3\2\2lm\7\34\2\2mq\7\3\2\2no\7\35\2\2oq\7\3\2\2pd\3\2\2\2ph\3\2\2"+
+ "\2pj\3\2\2\2pl\3\2\2\2pn\3\2\2\2q\27\3\2\2\2rs\b\r\1\2s\u00a9\7\66\2\2"+
+ "t\u00a9\7\63\2\2u\u00a9\7\6\2\2v\u00a9\7\7\2\2w\u00a9\7\4\2\2x\u00a9\7"+
+ "\5\2\2yz\7\67\2\2z{\5\30\r\2{|\78\2\2|\u00a9\3\2\2\2}~\7\b\2\2~\177\7"+
+ "\67\2\2\177\u0080\5\30\r\2\u0080\u0081\78\2\2\u0081\u00a9\3\2\2\2\u0082"+
+ "\u0083\7\t\2\2\u0083\u0084\7\67\2\2\u0084\u0085\5\30\r\2\u0085\u0086\7"+
+ "8\2\2\u0086\u00a9\3\2\2\2\u0087\u0088\7\n\2\2\u0088\u0089\7\67\2\2\u0089"+
+ "\u008a\5\30\r\2\u008a\u008b\78\2\2\u008b\u00a9\3\2\2\2\u008c\u008d\7\13"+
+ "\2\2\u008d\u00a9\5\30\r\20\u008e\u008f\7\f\2\2\u008f\u00a9\5\30\r\17\u0090"+
+ "\u0091\7\r\2\2\u0091\u00a9\5\30\r\16\u0092\u0093\7\16\2\2\u0093\u00a9"+
+ "\5\30\r\r\u0094\u0095\7\17\2\2\u0095\u00a9\5\30\r\f\u0096\u0097\7\20\2"+
+ "\2\u0097\u00a9\5\30\r\13\u0098\u0099\7\21\2\2\u0099\u00a9\5\30\r\n\u009a"+
+ "\u009b\7\22\2\2\u009b\u00a9\5\30\r\t\u009c\u009d\7\23\2\2\u009d\u00a9"+
+ "\5\30\r\b\u009e\u009f\7\24\2\2\u009f\u00a9\5\30\r\7\u00a0\u00a1\7\25\2"+
+ "\2\u00a1\u00a9\5\30\r\6\u00a2\u00a3\7\26\2\2\u00a3\u00a9\5\30\r\5\u00a4"+
+ "\u00a5\7\27\2\2\u00a5\u00a9\5\30\r\4\u00a6\u00a7\7\30\2\2\u00a7\u00a9"+
+ "\5\30\r\3\u00a8r\3\2\2\2\u00a8t\3\2\2\2\u00a8u\3\2\2\2\u00a8v\3\2\2\2"+
+ "\u00a8w\3\2\2\2\u00a8x\3\2\2\2\u00a8y\3\2\2\2\u00a8}\3\2\2\2\u00a8\u0082"+
+ "\3\2\2\2\u00a8\u0087\3\2\2\2\u00a8\u008c\3\2\2\2\u00a8\u008e\3\2\2\2\u00a8"+
+ "\u0090\3\2\2\2\u00a8\u0092\3\2\2\2\u00a8\u0094\3\2\2\2\u00a8\u0096\3\2"+
+ "\2\2\u00a8\u0098\3\2\2\2\u00a8\u009a\3\2\2\2\u00a8\u009c\3\2\2\2\u00a8"+
+ "\u009e\3\2\2\2\u00a8\u00a0\3\2\2\2\u00a8\u00a2\3\2\2\2\u00a8\u00a4\3\2"+
+ "\2\2\u00a8\u00a6\3\2\2\2\u00a9\u00b8\3\2\2\2\u00aa\u00ab\f\27\2\2\u00ab"+
+ "\u00ac\t\2\2\2\u00ac\u00b7\5\30\r\30\u00ad\u00ae\f\26\2\2\u00ae\u00af"+
+ "\t\3\2\2\u00af\u00b7\5\30\r\27\u00b0\u00b1\f\25\2\2\u00b1\u00b2\t\4\2"+
+ "\2\u00b2\u00b7\5\30\r\26\u00b3\u00b4\f\24\2\2\u00b4\u00b5\t\5\2\2\u00b5"+
+ "\u00b7\5\30\r\25\u00b6\u00aa\3\2\2\2\u00b6\u00ad\3\2\2\2\u00b6\u00b0\3"+
+ "\2\2\2\u00b6\u00b3\3\2\2\2\u00b7\u00ba\3\2\2\2\u00b8\u00b6\3\2\2\2\u00b8"+
+ "\u00b9\3\2\2\2\u00b9\31\3\2\2\2\u00ba\u00b8\3\2\2\2\17\35#)\65?FKNXp\u00a8"+
+ "\u00b6\u00b8";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramVisitor.java b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramVisitor.java
new file mode 100755
index 0000000..c023634
--- /dev/null
+++ b/OGP1718-Worms/src-provided/worms/programs/internal/parser/generated/WormsProgramVisitor.java
@@ -0,0 +1,306 @@
+// Generated from WormsProgram.g4 by ANTLR 4.7.1
+
+ package worms.programs.internal.parser.generated;
+
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+
+/**
+ * This interface defines a complete generic visitor for a parse tree produced
+ * by {@link WormsProgramParser}.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public interface WormsProgramVisitor extends ParseTreeVisitor {
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#program}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitProgram(WormsProgramParser.ProgramContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#proceduredef}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitProceduredef(WormsProgramParser.ProceduredefContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#statement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitStatement(WormsProgramParser.StatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#assignmentStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#whileStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#ifStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIfStatement(WormsProgramParser.IfStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#printStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#sequenceStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#invokeStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx);
+ /**
+ * Visit a parse tree produced by {@link WormsProgramParser#breakStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code turnAction}
+ * labeled alternative in {@link WormsProgramParser#actionStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitTurnAction(WormsProgramParser.TurnActionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code moveAction}
+ * labeled alternative in {@link WormsProgramParser#actionStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMoveAction(WormsProgramParser.MoveActionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code jumpAction}
+ * labeled alternative in {@link WormsProgramParser#actionStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitJumpAction(WormsProgramParser.JumpActionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code eatAction}
+ * labeled alternative in {@link WormsProgramParser#actionStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitEatAction(WormsProgramParser.EatActionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code fireAction}
+ * labeled alternative in {@link WormsProgramParser#actionStatement}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitFireAction(WormsProgramParser.FireActionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code distanceExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code cosExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitCosExpression(WormsProgramParser.CosExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getYExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code andOrExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code isWormExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code notExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitNotExpression(WormsProgramParser.NotExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code comparisonExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code parenExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getRadiusExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code trueLiteralExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code nullExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitNullExpression(WormsProgramParser.NullExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code sqrtExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code sinExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSinExpression(WormsProgramParser.SinExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code sameTeamExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code isProjectileExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code isFoodExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code constantExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code searchObjExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getXExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code readVariableExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code mulDivExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getDirectionExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code selfExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getHPExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code addSubExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getMaxAPExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code getAPExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by the {@code falseLiteralExpression}
+ * labeled alternative in {@link WormsProgramParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx);
+}
\ No newline at end of file
diff --git a/OGP1718-Worms/src-provided/worms/util/ModelException.java b/OGP1718-Worms/src-provided/worms/util/ModelException.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/src-provided/worms/util/MustNotImplementException.java b/OGP1718-Worms/src-provided/worms/util/MustNotImplementException.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java b/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java
new file mode 100755
index 0000000..050b8d6
--- /dev/null
+++ b/OGP1718-Worms/tests/worms/model/Part3_FullFacadeTest.java
@@ -0,0 +1,4262 @@
+package worms.model;
+
+import static java.lang.Math.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+import java.util.stream.IntStream;
+import java.math.BigInteger;
+
+import org.junit.*;
+
+import worms.facade.Facade;
+import worms.facade.IFacade;
+import worms.internal.gui.game.IActionHandler;
+import worms.programs.IProgramFactory;
+import worms.programs.ProgramFactory;
+import worms.programs.ProgramParser;
+import worms.util.*;
+
+public class Part3_FullFacadeTest {
+
+ private static int max_score = 0;
+ private static int score = 0;
+
+ private static final double EPS = 1e-3;
+
+ public final static double GAME_STANDARD_ACCELERATION = 5.0;
+
+ private final static IFacade facade = new Facade();
+ private final static IActionHandler actionHandler = new SimpleActionHandler(facade);
+ private final static ProgramFactory programFactory = new ProgramFactory();
+
+ private static final double[] FIXTURE_LOCATION = new double[] { 3.0, -7.0 };
+ private static final double FIXTURE_RADIUS = 0.30;
+ private static final String FIXTURE_NAME = "Test";
+ private static final double FIXTURE_DIRECTION = 3 * PI / 7;
+ private static final int FIXTURE_MAX_ACTION_POINTS = referenceMaxActionPoints(FIXTURE_RADIUS);
+ private static Worm fixtureWorm;
+ private static Food fixtureFood;
+
+ private boolean[][] map10x10, map5x5;
+ private static World theWorld, otherWorld;
+ private static Team theTeam = null;
+
+ @Before
+ public void setUp() {
+ fixtureWorm = facade.createWorm(null, FIXTURE_LOCATION, FIXTURE_DIRECTION, FIXTURE_RADIUS, FIXTURE_NAME, null);
+ fixtureFood = facade.createFood(null, FIXTURE_LOCATION);
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ map5x5 = new boolean[][] { { false, false, false, false, false, }, { true, true, true, true, true, },
+ { true, true, true, true, true, }, { true, true, true, true, true, },
+ { true, true, true, true, true, }, };
+ otherWorld = facade.createWorld(5.0, 5.0, map5x5);
+ try {
+ theTeam = facade.createTeam(theWorld, "TheTeam");
+ } catch (MustNotImplementException exc) {
+ }
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() {
+ System.out.println();
+ System.out.println("===============================");
+ System.out.println();
+ System.out.println(" FINAL SCORE: " + score + "/" + max_score);
+ System.out.println();
+ System.out.println(" FINAL PERCENTAGE: " + Math.round(score*100/max_score) + "%");
+ System.out.println();
+ }
+
+ /**********************
+ * AUXILIARY METHODS
+ **********************/
+
+ private static final double DENSITY = 1062;
+
+ private static final double referenceWormMass(double radius) {
+ return DENSITY * (4.0 / 3.0 * PI * pow(radius, 3));
+ }
+
+ private static int referenceMaxActionPoints(double radius) {
+ return (int) round(referenceWormMass(radius));
+ }
+
+ private static final double FULL_TURN_COST = 60;
+
+ private static int referenceCostToTurn(double angle) {
+ return (int) ceil(FULL_TURN_COST * abs(angle) / 2 / PI);
+ }
+
+ private static double referenceJumpDistance(int actionPoints, double radius, double theta) {
+ double v0 = referenceJumpV0(actionPoints, radius);
+ double d = v0 * v0 * sin(2 * theta) / GAME_STANDARD_ACCELERATION;
+ return d;
+ }
+
+ private static double[] referenceJumpStep(double dt, double[] loc, long actionPoints, double radius, double theta) {
+ double v0 = referenceJumpV0(actionPoints, radius);
+ double v0x = v0 * cos(theta);
+ double v0y = v0 * sin(theta);
+ double x = loc[0] + v0x * dt;
+ double y = loc[1] + v0y * dt - GAME_STANDARD_ACCELERATION * dt * dt / 2;
+ return new double[] { x, y };
+ }
+
+ private static double referenceJumpTime(int actionPoints, double radius, double theta) {
+ double v0 = referenceJumpV0(actionPoints, radius);
+ double t = referenceJumpDistance(actionPoints, radius, theta) / (v0 * cos(theta));
+ return t;
+ }
+
+ private static double referenceJumpV0(long actionPoints, double radius) {
+ double force = (5 * actionPoints) + (referenceWormMass(radius) * GAME_STANDARD_ACCELERATION);
+ double v0 = 0.5 * force / referenceWormMass(radius);
+ return v0;
+ }
+
+ private static double getDistance(double[] p1, double[] p2) {
+ double dx = p1[0]-p2[0];
+ double dy = p1[1]-p2[1];
+ return Math.sqrt(dx*dx + dy*dy);
+ }
+
+
+ /**************
+ * WORLD TESTS
+ *************/
+
+ @Test
+ public void createWorld_LegalCase() {
+ max_score += 10;
+ boolean[][] passableMap = new boolean[][] { { true, false, true, true, false },
+ { false, false, true, true, true }, { true, true, true, true, false },
+ { false, false, false, false, false } };
+ World theWorld = facade.createWorld(5.0, 4.0, passableMap);
+ assertEquals(5.0, facade.getWorldWidth(theWorld), EPS);
+ assertEquals(4.0, facade.getWorldHeight(theWorld), EPS);
+ assertFalse(facade.hasActiveGame(theWorld));
+ score += 1;
+ assertTrue(facade.isPassable(theWorld, new double[] { 0.5, 3.5 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 4.5, 3.5 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { 2.5, 2.5 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { 0.5, 3.5 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 0.5, 0.5 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 3.5, 0.5 }));
+ score += 7;
+ assertEquals(0, facade.getAllItems(theWorld).size());
+ score += 1;
+ try {
+ assertEquals(0, facade.getAllTeams(theWorld).size());
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ @Test
+ public void createWorld_IllegalDimension() {
+ max_score += 1;
+ boolean[][] passableMap = new boolean[][] { { true, false, true, true, false },
+ { false, false, true, true, true }, { true, true, true, true, false },
+ { false, false, false, false, false } };
+ try {
+ facade.createWorld(-1.0, 4.0, passableMap);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.createWorld(10.0, Double.NaN, passableMap);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 1;
+ }
+
+ @Test
+ public void createWorld_IllegalMap() {
+ max_score += 5;
+ // No effective map.
+ try {
+ facade.createWorld(10.0, 4.0, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Map with no cells.
+ try {
+ facade.createWorld(10.0, 4.0, new boolean[0][0]);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Non-rectangular map
+ try {
+ boolean[][] passableMap = new boolean[][] { { true, false, true, true }, { false, false, true, true, true },
+ { true, true, true, true, false }, { false, false, false } };
+ facade.createWorld(10.0, Double.NaN, passableMap);
+ fail();
+ } catch (ModelException exc) {
+ score += 3;
+ }
+ }
+
+ @Test
+ public void terminateWorld_EmptyWorld() {
+ max_score += 1;
+ facade.terminate(theWorld);
+ assertEquals(0, facade.getAllItems(theWorld).size());
+ try {
+ assertEquals(0, facade.getAllTeams(theWorld).size());
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ score += 1;
+ }
+
+ @Test
+ public void terminateWorld_WorldWithGameObjects() {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.5, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 6.0, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ facade.terminate(theWorld);
+ assertEquals(0, facade.getAllItems(theWorld).size());
+ assertNull(facade.getWorld(worm1));
+ assertNull(facade.getWorld(worm2));
+ score += 4;
+ }
+
+ @Test
+ public void terminateWorld_WorldWithTeams() {
+ max_score += 2;
+ try {
+ facade.createTeam(theWorld, "TeamA");
+ facade.createTeam(theWorld, "TeamB");
+ facade.terminate(theWorld);
+ assertEquals(0, facade.getAllTeams(theWorld).size());
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void isPassablePoint_TrueCases() {
+ max_score += 2;
+ assertTrue(facade.isPassable(theWorld, new double[] { 4.0, 6.0 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { 0.0, 8.99 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { 8.99, 0.0 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { 8.99, 8.99 }));
+ score += 2;
+ }
+
+ @Test
+ public void isPassablePoint_FalseCases() {
+ max_score += 2;
+ assertFalse(facade.isPassable(theWorld, new double[] { 9.3, 9.7 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 9.01, 0.0 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 9.01, 0.0 }));
+ assertFalse(facade.isPassable(theWorld, new double[] { 9.01, 9.01 }));
+ score += 2;
+ }
+
+ @Test
+ public void isPassablePoint_OutsideWorld() {
+ max_score += 2;
+ assertTrue(facade.isPassable(theWorld, new double[] { 10.0, 12.0 }));
+ assertTrue(facade.isPassable(theWorld, new double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY }));
+ score += 2;
+ }
+
+ @Test
+ public void isPassableArea_TrueCases() {
+ max_score += 4;
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ assertTrue(facade.isPassable(theWorld, new double[] { 3.0, 7.0 }, 1.95));
+ assertTrue(facade.isPassable(theWorld, new double[] { 3.0, 3.0 }, 1.95));
+ assertTrue(facade.isPassable(theWorld, new double[] { 7.0, 7.0 }, 1.95));
+ assertTrue(facade.isPassable(theWorld, new double[] { 7.0, 3.0 }, 1.95));
+ score += 4;
+ }
+
+ @Test
+ public void isPassableArea_FalseCases() {
+ max_score += 4;
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ //False cases completely in world
+ assertFalse(facade.isPassable(theWorld, new double[] { 3.0, 7.3 }, 1.95));
+ assertFalse(facade.isPassable(theWorld, new double[] { 3.0, 2.9 }, 1.95));
+ assertFalse(facade.isPassable(theWorld, new double[] { 7.1, 7.0 }, 1.95));
+ assertFalse(facade.isPassable(theWorld, new double[] { 7.0, 2.9 }, 1.95));
+ score += 4;
+ }
+
+ @Test
+ public void isPassableArea_AreasNotCompleteltInWorld() {
+ max_score += 4;
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ assertFalse(facade.isPassable(theWorld, new double[] { 3.0, 7.3 }, 3.95));
+ assertTrue(facade.isPassable(theWorld, new double[] { 20.0, -10.0 }, 1.95));
+ score += 4;
+ }
+
+ @Test
+ public void isAdjacent_TrueCases() {
+ max_score += 6;
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ assertTrue(facade.isAdjacent(theWorld, new double[] { 3.00, 7.95 }, 1.00));
+ assertTrue(facade.isAdjacent(theWorld, new double[] { 2.05, 3.00 }, 1.00));
+ assertTrue(facade.isAdjacent(theWorld, new double[] { 7.00, 2.05 }, 1.00));
+ assertTrue(facade.isAdjacent(theWorld, new double[] { 3.00, 7.95 }, 1.00));
+ score += 6;
+ }
+
+ @Test
+ public void isAdjacent_FalseCases() {
+ max_score += 8;
+ map10x10 = new boolean[][] { { false, false, false, false, false, false, false, false, false, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ theWorld = facade.createWorld(10.0, 10.0, map10x10);
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 3.00, 7.85 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 3.00, 8.05 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 2.15, 3.00 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 1.95, 3.00 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 7.00, 2.15 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 7.00, 1.95 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 3.00, 7.85 }, 1.00));
+ assertFalse(facade.isAdjacent(theWorld, new double[] { 3.00, 8.05 }, 1.00));
+ score += 8;
+ }
+
+ @Test
+ public void addWorm_LegalCase() {
+ max_score += 5;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ facade.addWorm(theWorld, wormToAdd);
+ assertEquals(theWorld, facade.getWorld(wormToAdd));
+ assertTrue(facade.hasAsWorm(theWorld, wormToAdd));
+ score += 5;
+ }
+
+ @Test
+ public void addWorm_TerminatedWorld() {
+ max_score += 1;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ facade.terminate(theWorld);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_WorldWithActiveGame() {
+ max_score += 1;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ facade.startGame(theWorld);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_NonEffectiveWorm() {
+ max_score += 1;
+ try {
+ facade.addWorm(theWorld, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_TerminatedWorm() {
+ max_score += 1;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ facade.terminate(wormToAdd);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_WormAlreadyInWorld() {
+ max_score += 1;
+ Worm wormToAdd = facade.createWorm(theWorld, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_WormInOtherWorld() {
+ max_score += 1;
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm wormToAdd = facade.createWorm(theWorld, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ try {
+ facade.addWorm(otherWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void addWorm_NotFullyInWorld() {
+ max_score += 5;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 1.8, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 5;
+ }
+ }
+
+ @Test
+ public void addWorm_NotFullyOnPassableTerrain() {
+ max_score += 10;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 7.5, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 10;
+ }
+ }
+
+ @Test
+ public void addWorm_NotAdjacentToImpassableTerrain() {
+ max_score += 3;
+ Worm wormToAdd = facade.createWorm(null, new double[] { 3.0, 6.5 }, FIXTURE_DIRECTION, 1.95, "Addy", null);
+ try {
+ facade.addWorm(theWorld, wormToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 3;
+ }
+ }
+
+ @Test
+ public void removeWorm_LegalCase() {
+ max_score += 5;
+ Worm wormToRemove = facade.createWorm(theWorld, new double[] { 3.0, 7.0 }, FIXTURE_DIRECTION, 1.95, "Addy",
+ null);
+ facade.removeWorm(theWorld, wormToRemove);
+ assertEquals(null, facade.getWorld(wormToRemove));
+ assertFalse(facade.hasAsWorm(theWorld, wormToRemove));
+ score += 5;
+ }
+
+ @Test
+ public void removeWorm_NonEffectiveWorm() {
+ max_score += 1;
+ try {
+ facade.removeWorm(theWorld, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void removeWorm_WormNotInWorld() {
+ max_score += 1;
+ try {
+ facade.removeWorm(theWorld, fixtureWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void getAllWorms_BasicCase() {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.5, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 6.0, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ List allWorms = facade.getAllWorms(theWorld);
+ assertEquals(2, allWorms.size());
+ assertTrue(allWorms.contains(worm1));
+ assertTrue(allWorms.contains(worm2));
+ score += 3;
+ }
+
+ @Test
+ public void getAllWorms_LeakTest() {
+ max_score += 8;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.5, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 6.0, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ List allWorms = facade.getAllWorms(theWorld);
+ allWorms.remove(worm2);
+ assertTrue(facade.hasAsWorm(theWorld, worm2));
+ allWorms.add(fixtureWorm);
+ facade.removeWorm(theWorld, worm2);
+ assertEquals(1, facade.getAllWorms(theWorld).size());
+ score += 8;
+ }
+
+ @Test
+ public void addFood_LegalCase() {
+ max_score += 3;
+ Food foodToAdd = facade.createFood(null, new double[] { 8.795, 7.0 });
+ facade.addFood(theWorld, foodToAdd);
+ assertEquals(theWorld, facade.getWorld(foodToAdd));
+ assertTrue(facade.hasAsFood(theWorld, foodToAdd));
+ score += 3;
+ }
+
+ @Test
+ public void addFood_NotAdjacentToImpassableTerrain() {
+ max_score += 1;
+ Food foodToAdd = facade.createFood(null, new double[] { 6.3, 7.0 });
+ try {
+ facade.addFood(theWorld, foodToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void removeFood_LegalCase() {
+ max_score += 3;
+ Food foodToRemove = facade.createFood(theWorld, new double[] { 3.0, 8.79 });
+ facade.removeFood(theWorld, foodToRemove);
+ assertEquals(null, facade.getWorld(foodToRemove));
+ assertFalse(facade.hasAsFood(theWorld, foodToRemove));
+ score += 3;
+ }
+
+ @Test
+ public void removeFood_FoodNotInWorld() {
+ max_score += 1;
+ try {
+ facade.removeFood(theWorld, fixtureFood);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void getAllItems_BasicCase() {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.5, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 6.0, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ Food food1 = facade.createFood(theWorld, new double[] { 0.22, 8.79 });
+ Food food2 = facade.createFood(theWorld, new double[] { 8.79, 8.79 });
+ Collection allItems = facade.getAllItems(theWorld);
+ assertEquals(4, allItems.size());
+ assertTrue(allItems.contains(worm1));
+ assertTrue(allItems.contains(worm2));
+ assertTrue(allItems.contains(food1));
+ assertTrue(allItems.contains(food2));
+ score += 3;
+ }
+
+ @Test
+ public void getAllItems_LeakTest() {
+ max_score += 6;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.5, 8.0 }, FIXTURE_DIRECTION, 0.95, "Addy", null);
+ facade.createFood(theWorld, new double[] { 0.22, 8.79 });
+ Collection allItems = facade.getAllItems(theWorld);
+ allItems.remove(worm1);
+ assertTrue(facade.hasAsWorm(theWorld, worm1));
+ allItems.add(fixtureWorm);
+ assertEquals(1, facade.getAllWorms(theWorld).size());
+ score += 6;
+ }
+
+ @Test
+ public void getAllTeams_BasicCase() {
+ max_score += 2;
+ try {
+ Team team1 = facade.createTeam(theWorld, "TeamA");
+ Team team2 = facade.createTeam(theWorld, "TeamB");
+ Set allTeams = facade.getAllTeams(theWorld);
+ assertEquals(3, allTeams.size());
+ assertTrue(allTeams.contains(team1));
+ assertTrue(allTeams.contains(team2));
+ assertTrue(allTeams.contains(theTeam));
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void getAllTeams_LeakTest() {
+ max_score += 6;
+ try {
+ Team team1 = facade.createTeam(theWorld, "TeamA");
+ facade.createTeam(theWorld, "TeamB");
+ Set allTeams = facade.getAllTeams(theWorld);
+ allTeams.remove(team1);
+ assertTrue(facade.getAllTeams(theWorld).contains(team1));
+ Team team3 = facade.createTeam(null, "TeamC");
+ allTeams.add(team3);
+ assertEquals(3, facade.getAllTeams(theWorld).size());
+ score += 6;
+ } catch (MustNotImplementException exc) {
+ max_score -= 6;
+ }
+ }
+
+ @Test
+ public void getActiveWorm_NoActiveGame() {
+ max_score += 1;
+ assertNull(facade.getActiveWorm(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getActiveWorm_NoWormsInWorld() {
+ max_score += 1;
+ facade.startGame(theWorld);
+ assertNull(facade.getActiveWorm(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getActiveWorm_WormsInWorld() {
+ max_score += 2;
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "WormA", null);
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "WormB", null);
+ facade.startGame(theWorld);
+ assertTrue(facade.getAllWorms(theWorld).contains(facade.getActiveWorm(theWorld)));
+ score += 2;
+ }
+
+ @Test
+ public void startGame_SingleWormInWorld() {
+ max_score += 4;
+ Worm worm = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "Worm", null);
+ facade.decreaseNbActionPoints(worm, 20);
+ BigInteger nbHitPoints = facade.getNbHitPoints(worm);
+ facade.startGame(theWorld);
+ assertEquals(worm, facade.getActiveWorm(theWorld));
+ assertEquals(facade.getMaxNbActionPoints(worm), facade.getNbActionPoints(worm));
+ assertEquals(nbHitPoints.add(BigInteger.TEN), facade.getNbHitPoints(worm));
+ score += 4;
+ }
+
+ @Test
+ public void startGame_SeveralWormsInWorld() {
+ max_score += 6;
+ Worm wormA = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "WormA", null);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 2.1, 6.99 }, 0.4, 2.0, "WormB", null);
+ Worm wormC = facade.createWorm(theWorld, new double[] { 8.48, 8.48 }, 4.5, 0.5, "WormC", null);
+ facade.decreaseNbActionPoints(wormA, 20);
+ BigInteger nbHitPointsA = facade.getNbHitPoints(wormA);
+ facade.decreaseNbActionPoints(wormB, 20);
+ BigInteger nbHitPointsB = facade.getNbHitPoints(wormB);
+ facade.decreaseNbActionPoints(wormC, 20);
+ BigInteger nbHitPointsC = facade.getNbHitPoints(wormA);
+ facade.startGame(theWorld);
+ Worm activeWorm = facade.getActiveWorm(theWorld);
+ assertTrue(facade.getAllWorms(theWorld).contains(activeWorm));
+ if (activeWorm == wormA) {
+ assertEquals(facade.getMaxNbActionPoints(wormA), facade.getNbActionPoints(wormA));
+ assertEquals(nbHitPointsA.add(BigInteger.TEN), facade.getNbHitPoints(wormA));
+ }
+ if (activeWorm == wormB) {
+ assertEquals(facade.getMaxNbActionPoints(wormB), facade.getNbActionPoints(wormB));
+ assertEquals(nbHitPointsB.add(BigInteger.TEN), facade.getNbHitPoints(wormB));
+ }
+ if (activeWorm == wormC) {
+ assertEquals(facade.getMaxNbActionPoints(wormC), facade.getNbActionPoints(wormC));
+ assertEquals(nbHitPointsC.add(BigInteger.TEN), facade.getNbHitPoints(wormC));
+ }
+ score += 6;
+ }
+
+ @Test
+ public void finishGame_RegularCase() {
+ max_score += 1;
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "Worm", null);
+ facade.startGame(theWorld);
+ facade.finishGame(theWorld);
+ assertNull(facade.getActiveWorm(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void finishGame_NoActiveGame() {
+ max_score += 1;
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "Worm", null);
+ facade.finishGame(theWorld);
+ assertNull(facade.getActiveWorm(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void activateNextWorm_SeveralWorms() {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Worm worm3 = facade.createWorm(theWorld, new double[] { 6.5, 7.95 }, 0.1, 1.0, "ThirdWorm", null);
+ facade.startGame(theWorld);
+ Set activatedWorms = new HashSet<>();
+ activatedWorms.add(facade.getActiveWorm(theWorld));
+ facade.activateNextWorm(theWorld);
+ activatedWorms.add(facade.getActiveWorm(theWorld));
+ facade.activateNextWorm(theWorld);
+ activatedWorms.add(facade.getActiveWorm(theWorld));
+ assertTrue(activatedWorms.contains(worm1));
+ assertTrue(activatedWorms.contains(worm2));
+ assertTrue(activatedWorms.contains(worm3));
+ score += 2;
+ }
+
+ @Test
+ public void activateNextWorm_WormsLeavingWorld() {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Worm worm3 = facade.createWorm(theWorld, new double[] { 6.5, 7.95 }, 0.1, 1.0, "ThirdWorm", null);
+ facade.startGame(theWorld);
+ Worm firstActivatedWorm = facade.getActiveWorm(theWorld);
+ if (firstActivatedWorm == worm1) {
+ facade.removeWorm(theWorld, worm2);
+ facade.activateNextWorm(theWorld);
+ assertEquals(worm3, facade.getActiveWorm(theWorld));
+ } else if (firstActivatedWorm == worm2) {
+ facade.removeWorm(theWorld, worm3);
+ facade.activateNextWorm(theWorld);
+ assertEquals(worm1, facade.getActiveWorm(theWorld));
+ } else {
+ facade.removeWorm(theWorld, worm1);
+ facade.activateNextWorm(theWorld);
+ assertEquals(worm2, facade.getActiveWorm(theWorld));
+ }
+ score += 4;
+ }
+
+ @Test
+ public void activateNextWorm_NoMoreActiveWorms() {
+ max_score += 1;
+ Worm worm = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "Worm", null);
+ facade.startGame(theWorld);
+ facade.removeWorm(theWorld, worm);
+ facade.activateNextWorm(theWorld);
+ assertNull(facade.getActiveWorm(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getWinner_NoActiveGame() {
+ max_score += 1;
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "Worm", null);
+ assertNull(facade.getWinner(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getWinner_WinningWorm() {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Worm worm3 = facade.createWorm(theWorld, new double[] { 6.5, 7.95 }, 0.1, 1.0, "ThirdWorm", null);
+ facade.startGame(theWorld);
+ facade.removeWorm(theWorld, worm3);
+ facade.activateNextWorm(theWorld);
+ facade.removeWorm(theWorld, worm2);
+ facade.activateNextWorm(theWorld);
+ facade.activateNextWorm(theWorld);
+ assertEquals(facade.getName(worm1), facade.getWinner(theWorld));
+ score += 4;
+ }
+
+ @Test
+ public void getWinner_WinningTeam() {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Worm worm3 = facade.createWorm(theWorld, new double[] { 6.5, 7.95 }, 0.1, 1.0, "ThirdWorm", null);
+ Team someTeam = facade.createTeam(theWorld, "SomeTeam");
+ facade.addWormsToTeam(someTeam, worm1, worm3);
+ facade.startGame(theWorld);
+ facade.activateNextWorm(theWorld);
+ facade.removeWorm(theWorld, worm2);
+ facade.activateNextWorm(theWorld);
+ facade.activateNextWorm(theWorld);
+ assertEquals(facade.getName(someTeam), facade.getWinner(theWorld));
+ score += 4;
+ }
+
+ @Test
+ public void getWinner_WorldWithoutWorms() {
+ max_score += 1;
+ facade.startGame(theWorld);
+ assertNull(facade.getWinner(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getWinner_SeveralWormsNotInTeam() {
+ max_score += 1;
+ facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ facade.startGame(theWorld);
+ assertNull(facade.getWinner(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getWinner_SeveralWormsInDifferentTeams() {
+ max_score += 1;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Team teamA = facade.createTeam(theWorld, "TeamA");
+ facade.addWormsToTeam(teamA, worm1);
+ Team teamB = facade.createTeam(theWorld, "TeamB");
+ facade.addWormsToTeam(teamB, worm2);
+ facade.startGame(theWorld);
+ assertNull(facade.getWinner(theWorld));
+ score += 1;
+ }
+
+ @Test
+ public void getWinner_IndividualWormTeamWorm() {
+ max_score += 1;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.95, 4.0 }, 0.1, 1.0, "FirstWorm", null);
+ facade.createWorm(theWorld, new double[] { 2.5, 7.95 }, 0.1, 1.0, "SecondWorm", null);
+ Team teamA = facade.createTeam(theWorld, "TeamA");
+ facade.addWormsToTeam(teamA, worm1);
+ facade.startGame(theWorld);
+ assertNull(facade.getWinner(theWorld));
+ score += 1;
+ }
+
+ /**************
+ * WORM TESTS
+ *************/
+
+ @Test
+ public void createWorm_LegalCaseNoWorldNoTeam() {
+ max_score += 12;
+ double[] location = new double[] { 3.0, -7.0 };
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ Worm newWorm = facade.createWorm(null, location, direction, radius, name, null);
+ assertNull(facade.getWorld(newWorm));
+ assertNull(facade.getTeam(newWorm));
+ assertEquals(location[0], facade.getLocation(newWorm)[0], EPS);
+ assertEquals(location[1], facade.getLocation(newWorm)[1], EPS);
+ score += 2;
+ assertEquals(direction, facade.getOrientation(newWorm), EPS);
+ score += 2;
+ assertEquals(radius, facade.getRadius(newWorm), EPS);
+ score += 2;
+ assertEquals(Math.round(facade.getMass(newWorm)), facade.getNbActionPoints(newWorm));
+ assertEquals(Math.round(facade.getMass(newWorm)), facade.getMaxNbActionPoints(newWorm));
+ score += 2;
+ assertEquals(name, facade.getName(newWorm));
+ score += 2;
+ assertTrue(facade.getNbHitPoints(newWorm).compareTo(BigInteger.valueOf(1000)) >= 0);
+ assertTrue(facade.getNbHitPoints(newWorm).compareTo(BigInteger.valueOf(2000)) <= 0);
+ score += 2;
+ }
+
+ @Test
+ public void createWorm_LegalCaseInWorld() {
+ max_score += 6;
+ double[] location = new double[] { 8.68, 8.68 };
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ Worm newWorm = facade.createWorm(theWorld, location, direction, radius, name, null);
+ assertEquals(theWorld, facade.getWorld(newWorm));
+ assertTrue(facade.hasAsWorm(theWorld, newWorm));
+ score += 6;
+ }
+
+ @Test
+ public void createWorm_LegalCaseInTeam() {
+ max_score += 6;
+ double[] location = new double[] { 8.68, 8.68 };
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ try {
+ Worm newWorm = facade.createWorm(theWorld, location, direction, radius, name, theTeam);
+ assertEquals(theTeam, facade.getTeam(newWorm));
+ assertEquals(1, facade.getAllWormsOfTeam(theTeam).size());
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(newWorm));
+ score += 6;
+ } catch (MustNotImplementException exc) {
+ max_score -= 6;
+ }
+ }
+
+ @Test
+ public void createWorm_IllegalWorld() {
+ max_score += 2;
+ World someWorld = facade.createWorld(10.0, 20.0, map10x10);
+ facade.terminate(someWorld);
+ try {
+ facade.createWorm(someWorld, new double[] { 8.68, 8.68 }, 0.3, 0.3, "Worm", null);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void createWorm_InfinitePosition() {
+ max_score += 3;
+ double[] location = new double[] { Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY };
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ Worm newWorm = facade.createWorm(null, location, direction, radius, name, null);
+ assertEquals(Double.POSITIVE_INFINITY, facade.getLocation(newWorm)[0], EPS);
+ assertEquals(Double.NEGATIVE_INFINITY, facade.getLocation(newWorm)[1], EPS);
+ score += 3;
+ }
+
+ @Test
+ public void createWorm_IllegalLocation() {
+ max_score += 2;
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ // Illegal x-displacement
+ try {
+ double[] location = new double[] { Double.NaN, 1.0 };
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Illegal y-displacement
+ try {
+ double[] location = new double[] { 1.0, Double.NaN };
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void createWorm_IllegalOrientation() {
+ max_score += 2;
+ double[] location = new double[] { 3.0, -7.0 };
+ double radius = 0.30;
+ String name = "Test";
+ // Negative orientation
+ try {
+ double direction = -1.0;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Orientation too large
+ try {
+ double direction = 7.0;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Infinite Orientation
+ try {
+ double direction = Double.POSITIVE_INFINITY;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Orientation not a number
+ try {
+ double direction = Double.NaN;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 2;
+ }
+
+ @Test
+ public void createWorm_IllegalRadius() {
+ max_score += 2;
+ double[] location = new double[] { 3.0, -7.0 };
+ double direction = 3 * PI / 7;
+ String name = "Test";
+ // Radius below 0.25
+ try {
+ double radius = 0.2;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Negative radius
+ try {
+ double radius = -4.0;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Infinite Radius
+ try {
+ double radius = Double.POSITIVE_INFINITY;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ // Radius not a number
+ try {
+ double radius = Double.NaN;
+ facade.createWorm(null, location, direction, radius, name, null);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 2;
+ }
+
+ @Test
+ public void createWorm_IllegalTeam() {
+ max_score += 2;
+ double[] location = new double[] { 3.0, -7.0 };
+ double direction = 3 * PI / 7;
+ String name = "Test";
+ // Radius below 0.25
+ try {
+ double radius = 0.2;
+ facade.createWorm(null, location, direction, radius, name, theTeam);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+
+ }
+
+ @Test
+ public void terminateWorm_NoWorldNoTeam() {
+ max_score += 1;
+ Worm someWorm = facade.createWorm(null, new double[] { -4.0, 7.0 }, 0.8, 1.0, "Worm", null);
+ facade.terminate(someWorm);
+ assertTrue(facade.isTerminated(someWorm));
+ score += 1;
+ }
+
+ @Test
+ public void terminateWorm_InWorldNoTeam() {
+ max_score += 1;
+ facade.terminate(fixtureWorm);
+ assertTrue(facade.isTerminated(fixtureWorm));
+ assertNull(facade.getWorld(fixtureWorm));
+ assertFalse(facade.hasAsWorm(theWorld, fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void terminateWorm_InWorldInTeam() {
+ max_score += 1;
+ try {
+ facade.addWormsToTeam(theTeam, fixtureWorm);
+ facade.terminate(fixtureWorm);
+ assertTrue(facade.isTerminated(fixtureWorm));
+ assertNull(facade.getTeam(fixtureWorm));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).isEmpty());
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score = -1;
+ }
+ }
+
+ @Test
+ public void setRadius_IllegalValues() {
+ max_score += 1;
+ try {
+ facade.setRadius(fixtureWorm, 0.2);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.setRadius(fixtureWorm, -0.5);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.setRadius(fixtureWorm, Double.NaN);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 1;
+ }
+
+ @Test
+ public void setRadius_LargerRadiusUpdatesMass() {
+ max_score += 2;
+ double newRadius = 2.0;
+ facade.setRadius(fixtureWorm, newRadius);
+ assertEquals(newRadius, facade.getRadius(fixtureWorm), EPS);
+ assertEquals(referenceWormMass(newRadius), facade.getMass(fixtureWorm), EPS);
+ score += 2;
+ }
+
+ @Test
+ public void setRadius_LargerRadiusUpdatesMaxActionPoints() {
+ max_score += 2;
+ double newRadius = 2.0;
+ facade.setRadius(fixtureWorm, newRadius);
+ assertEquals(newRadius, facade.getRadius(fixtureWorm), EPS);
+ assertEquals(referenceMaxActionPoints(newRadius), facade.getMaxNbActionPoints(fixtureWorm));
+ score += 2;
+ }
+
+ @Test
+ public void setRadius_ShrinkingRadiusReducesActionPoints() {
+ max_score += 5;
+ Worm worm = fixtureWorm;
+ Assume.assumeTrue(referenceMaxActionPoints(FIXTURE_RADIUS) == facade.getNbActionPoints(worm));
+ try {
+ facade.setRadius(worm, FIXTURE_RADIUS / 2);
+ assertEquals(FIXTURE_RADIUS / 2, facade.getRadius(worm), EPS);
+ assertEquals(referenceMaxActionPoints(FIXTURE_RADIUS / 2), facade.getMaxNbActionPoints(worm));
+ assertEquals(facade.getMaxNbActionPoints(worm), facade.getNbActionPoints(worm));
+ } catch (ModelException e) {
+ // interpretation 2: new radius is invalid
+ // ensure that nothing has been modified
+ assertEquals(FIXTURE_RADIUS, facade.getRadius(worm), EPS);
+ assertEquals(referenceMaxActionPoints(FIXTURE_RADIUS), facade.getMaxNbActionPoints(worm));
+ assertEquals(facade.getMaxNbActionPoints(worm), facade.getNbActionPoints(worm));
+ }
+ score += 5;
+ }
+
+ @Test
+ public void setRadius_LargerRadiusOnImpasableTerrain() {
+ max_score += 5;
+ double[] location = new double[] { 1.0, 8.68 };
+ double direction = 3 * PI / 7;
+ double radius = 0.30;
+ String name = "Test";
+ Worm newWorm = facade.createWorm(theWorld, location, direction, radius, name, null);
+ try {
+ facade.setRadius(newWorm, 2.0);
+ fail();
+ } catch (ModelException exc) {
+ score += 5;
+ }
+ }
+
+ @Test
+ public void getMass_SingleCase() {
+ max_score += 2;
+ double expectedMass = 1062.0 * (4.0 / 3.0 * PI * pow(FIXTURE_RADIUS, 3));
+ assertEquals(expectedMass, facade.getMass(fixtureWorm), EPS);
+ score += 2;
+ }
+
+ @Test
+ public void decreaseActionPoints_LegalCase() {
+ max_score += 1;
+ long oldNbActionPoints = facade.getNbActionPoints(fixtureWorm);
+ facade.decreaseNbActionPoints(fixtureWorm, 3);
+ assertEquals(oldNbActionPoints - 3, facade.getNbActionPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void decreaseActionPoints_NegativeDelta() {
+ max_score += 1;
+ facade.decreaseNbActionPoints(fixtureWorm, 5);
+ long oldNbActionPoints = facade.getNbActionPoints(fixtureWorm);
+ facade.decreaseNbActionPoints(fixtureWorm, -3);
+ assertEquals(oldNbActionPoints + 3, facade.getNbActionPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void decreaseActionPoints_DeltaTooLarge() {
+ max_score += 1;
+ long oldNbActionPoints = facade.getNbActionPoints(fixtureWorm);
+ facade.decreaseNbActionPoints(fixtureWorm, Integer.MAX_VALUE);
+ assertEquals(oldNbActionPoints, facade.getNbActionPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void decreaseActionPoints_DeltaTooNegative() {
+ max_score += 1;
+ long oldNbActionPoints = facade.getNbActionPoints(fixtureWorm);
+ long maxNbActionPoints = facade.getMaxNbActionPoints(fixtureWorm);
+ long delta = oldNbActionPoints - maxNbActionPoints - 10;
+ facade.decreaseNbActionPoints(fixtureWorm, delta);
+ assertEquals(oldNbActionPoints, facade.getNbActionPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void incrementHitPoints_LegalCase() {
+ max_score += 2;
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(fixtureWorm);
+ facade.incrementNbHitPoints(fixtureWorm, 3);
+ assertEquals(oldNbHitPoints.add(BigInteger.valueOf(3)), facade.getNbHitPoints(fixtureWorm));
+ score += 1;
+ oldNbHitPoints = facade.getNbHitPoints(fixtureWorm);
+ facade.incrementNbHitPoints(fixtureWorm, -100);
+ assertEquals(oldNbHitPoints.add(BigInteger.valueOf(-100)), facade.getNbHitPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void incrementHitPoints_ZeroCase() {
+ max_score += 2;
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(fixtureWorm);
+ facade.incrementNbHitPoints(fixtureWorm, -oldNbHitPoints.longValue());
+ assertEquals(BigInteger.ZERO, facade.getNbHitPoints(fixtureWorm));
+ assertTrue(facade.isTerminated(fixtureWorm));
+ score += 2;
+ }
+
+ @Test
+ public void incrementHitPoints_NegativeCase() {
+ max_score += 2;
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(fixtureWorm);
+ facade.incrementNbHitPoints(fixtureWorm, -2 * oldNbHitPoints.longValue());
+ assertEquals(BigInteger.ZERO, facade.getNbHitPoints(fixtureWorm));
+ assertTrue(facade.isTerminated(fixtureWorm));
+ score += 2;
+ }
+
+ @Test
+ public void rename_LegalCases() {
+ max_score += 3;
+ Worm worm = fixtureWorm;
+ facade.rename(worm, "John");
+ assertEquals("John", facade.getName(worm));
+ facade.rename(worm, "James o'Hara");
+ assertEquals("James o'Hara", facade.getName(worm));
+ facade.rename(worm, "J ");
+ assertEquals("J ", facade.getName(worm));
+ facade.rename(worm, "J\"");
+ assertEquals("J\"", facade.getName(worm));
+ facade.rename(worm, "J_a_");
+ assertEquals("J_a_", facade.getName(worm));
+ score += 3;
+ }
+
+ @Test
+ public void rename_NameTooShort() {
+ max_score += 1;
+ try {
+ facade.rename(fixtureWorm, "J");
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.rename(fixtureWorm, "");
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 1;
+ }
+
+ @Test
+ public void rename_NameWithIllegalCharacters() {
+ max_score += 1;
+ try {
+ facade.rename(fixtureWorm, "John123");
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void rename_NameWithoutStartingCapital() {
+ max_score += 1;
+ try {
+ facade.rename(fixtureWorm, "john");
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void rename_NullName() {
+ max_score += 1;
+ try {
+ facade.rename(fixtureWorm, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void turn_HalfTurn() {
+ max_score += 1;
+ facade.turn(fixtureWorm, PI);
+ assertEquals(PI + FIXTURE_DIRECTION, facade.getOrientation(fixtureWorm), EPS);
+ assertEquals(referenceCostToTurn(PI),
+ facade.getMaxNbActionPoints(fixtureWorm) - facade.getNbActionPoints(fixtureWorm));
+ score += 1;
+ }
+
+ @Test
+ public void turn_QuarterTurnNegative() {
+ max_score += 2;
+ facade.turn(fixtureWorm, PI);
+ facade.turn(fixtureWorm, -PI / 2);
+ assertEquals(PI + FIXTURE_DIRECTION - PI / 2, facade.getOrientation(fixtureWorm), EPS);
+ assertEquals(referenceCostToTurn(PI + PI / 2),
+ facade.getMaxNbActionPoints(fixtureWorm) - facade.getNbActionPoints(fixtureWorm));
+ score += 2;
+ }
+
+ @Test
+ public void turn_IllegalAngles() {
+ max_score += 3;
+ try {
+ facade.turn(fixtureWorm, -7);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.turn(fixtureWorm, +7);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.turn(fixtureWorm, Double.NaN);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 3;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_WormNotInWorld() {
+ max_score += 5;
+ Worm theWorm = facade.createWorm(null, new double[] { 8.0, 4.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ double[] destination = facade.getFurthestLocationInDirection(theWorm, 3 * PI / 4, 2.0);
+ assertEquals(8.0 - Math.sqrt(2.0), destination[0], EPS);
+ assertEquals(4.0 + Math.sqrt(2.0), destination[1], EPS);
+ score += 5;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_NoMovePossible() {
+ max_score += 3;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 4.0 }, 0.0, 1.0, "Worm", null);
+ double[] destination = facade.getFurthestLocationInDirection(theWorm, 0.3, 5.0);
+ assertEquals(facade.getLocation(theWorm)[0], destination[0], EPS);
+ assertEquals(facade.getLocation(theWorm)[1], destination[1], EPS);
+ score += 3;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_MaximalMoveWithinWorld() {
+ max_score += 5;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 4.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ double[] destination = facade.getFurthestLocationInDirection(theWorm, 3 * PI / 4, 2.0);
+ assertEquals(8.0 - Math.sqrt(2.0), destination[0], EPS);
+ assertEquals(4.0 + Math.sqrt(2.0), destination[1], EPS);
+ score += 5;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_MaximalMoveOutsideWorld() {
+ max_score += 5;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 1.0 }, 5 * PI / 6.0, 1.0, "Worm", null);
+ double[] destination = facade.getFurthestLocationInDirection(theWorm, 5 * PI / 6, 20.0);
+ assertEquals(8.0 + 20 * Math.cos(5 * PI / 6), destination[0], EPS);
+ assertEquals(1.0 + 20 * Math.sin(5 * PI / 6), destination[1], EPS);
+ score += 5;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_NonMaximalMove() {
+ max_score += 8;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 3.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ double[] destination = facade.getFurthestLocationInDirection(theWorm, 3 * PI / 4, 10.0);
+ assertEquals(8.0 - 5.0, destination[0], EPS);
+ assertEquals(3.0 + 5.0, destination[1], EPS);
+ score += 8;
+ }
+
+ @Test
+ public void getFurthestLocationInDirection_IllegalCases() {
+ max_score += 6;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 4.0 }, PI, 1.0, "Worm", null);
+ // Negative orientation
+ try {
+ facade.getFurthestLocationInDirection(theWorm, -0.5, 3.0);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Orientation not below 2*PI
+ try {
+ facade.getFurthestLocationInDirection(theWorm, 3 * PI, 3.0);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Orientation not a number
+ try {
+ facade.getFurthestLocationInDirection(theWorm, Double.NaN, 3.0);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Negative maximum distance
+ try {
+ facade.getFurthestLocationInDirection(theWorm, 0.5, -3.0);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Infinite maximum distance
+ try {
+ facade.getFurthestLocationInDirection(theWorm, 0.5, Double.POSITIVE_INFINITY);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ // Maximum distance not a number
+ try {
+ facade.getFurthestLocationInDirection(theWorm, 0.5, Double.NaN);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void move_ReachingImpassableTerrainInDirection() {
+ max_score += 15;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 7.5 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ double[] expectedLocation = new double[] {7.5,8.0};
+ assertTrue(facade.isAdjacent(theWorld, newLocation, facade.getRadius(theWorm)));
+ assertEquals(expectedLocation[0]+facade.getRadius(theWorm)*0.1/2.0, newLocation[0], facade.getRadius(theWorm)*0.12/2.0);
+ assertEquals(expectedLocation[1]-facade.getRadius(theWorm)*0.1/2.0, newLocation[1], facade.getRadius(theWorm)*0.12/2.0);
+ // We allow a deviation of +/-1 in calculating the action points.
+ assertTrue((facade.getNbActionPoints(theWorm) >= oldNbActionPoints - 4)
+ && (facade.getNbActionPoints(theWorm) <= oldNbActionPoints - 2));
+ score += 15;
+ }
+
+ @Test
+ public void move_OnlyPassableTerrainInDirection() {
+ max_score += 15;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.0, 3.0 }, PI, 2.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ assertEquals(7.0 - 2.0, newLocation[0], EPS);
+ assertEquals(3.0, newLocation[1], EPS);
+ // We allow a deviation of +/-1 in calculating the action points.
+ assertTrue((facade.getNbActionPoints(theWorm) >= oldNbActionPoints - 3)
+ && (facade.getNbActionPoints(theWorm) <= oldNbActionPoints - 1));
+ score += 15;
+ }
+
+ @Test
+ public void move_ReachingImpassableTerrainDeviatingDirectionAlmostVertical() {
+ max_score += 15;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 5.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ // The worm will move in an almost vertical direction, such that he is still
+ // adjacent to the vertical wall.
+ double[] expectedLocation = new double[] {8.0,6.0};
+ assertTrue(facade.isAdjacent(theWorld, newLocation, facade.getRadius(theWorm)));
+ assertEquals(expectedLocation[0]-facade.getRadius(theWorm)*0.1/2.0, newLocation[0], facade.getRadius(theWorm)*0.12/2.0);
+ assertEquals(expectedLocation[1]-facade.getRadius(theWorm)*0.1/2.0, newLocation[1], facade.getRadius(theWorm)*0.12/2.0);
+ assertTrue((facade.getNbActionPoints(theWorm) >= oldNbActionPoints - 5)
+ && (facade.getNbActionPoints(theWorm) <= oldNbActionPoints - 3));
+ score += 15;
+ }
+
+ @Test
+ public void move_ReachingImpassableTerrainDeviatingDirectionDiagonalDirection() {
+ max_score += 15;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm theWorm = facade.createWorm(otherWorld, new double[] { 7.0, 5.0 }, PI, 2.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ // The worm will move adjacent to the cell in row 7 and column 4.
+ assertTrue(facade.isAdjacent(otherWorld, newLocation, 2.0));
+ double distanceToEdge = Math.sqrt(Math.pow(newLocation[0] - 5.0, 2.0) + Math.pow(newLocation[1] - 2.0, 2.0));
+ assertEquals(2.1, distanceToEdge, 0.2);
+ assertTrue((facade.getNbActionPoints(theWorm) >= oldNbActionPoints - 5)
+ && (facade.getNbActionPoints(theWorm) <= oldNbActionPoints - 3));
+ score += 15;
+ }
+
+ @Test
+ public void move_ReachingImpassableTerrainDeviatingDirectionSeveralDirections() {
+ max_score += 15;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm theWorm = facade.createWorm(otherWorld, new double[] { 7.0, 5.0 }, PI, 2.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ // The worm will move adjacent to the cell in row 1 and column 6 or adjacent to
+ // row 9 and column 6.
+ assertTrue(facade.isAdjacent(otherWorld, newLocation, 2.0));
+ double distanceToEdge = Math.min(
+ Math.sqrt(Math.pow(newLocation[0] - 5.0, 2.0) + Math.pow(newLocation[1] - 2.0, 2.0)),
+ Math.sqrt(Math.pow(newLocation[0] - 5.0, 2.0) + Math.pow(newLocation[1] - 8.0, 2.0)) );
+ assertEquals(2.1, distanceToEdge, 0.2);
+ assertTrue((facade.getNbActionPoints(theWorm) >= oldNbActionPoints - 5)
+ && (facade.getNbActionPoints(theWorm) <= oldNbActionPoints - 3));
+ score += 15;
+ }
+
+ @Test
+ public void move_OverlappingWormAtDestination() {
+ max_score += 12;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 8.0 }, PI, 1.0, "Worm", null);
+ Worm otherWorm = facade.createWorm(theWorld, new double[] { 4.5, 7.0 }, 3 * PI / 4.0, 2.0, "WormA", null);
+ long oldHitPointsTheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long oldHitPointsOtherWorm = facade.getNbHitPoints(otherWorm).longValue();
+ facade.move(theWorm);
+ long newHitPointsTheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long newHitPointOtherWorm = facade.getNbHitPoints(otherWorm).longValue();
+ long deltaTheWorm = oldHitPointsTheWorm - newHitPointsTheWorm;
+ long deltaOtherWorm = oldHitPointsOtherWorm - newHitPointOtherWorm;
+ long delta = deltaTheWorm + deltaOtherWorm;
+ assertTrue((delta >= 1) && (delta <= 10));
+ assertEquals(deltaTheWorm, Math.round(delta / (2.0 / 3.0)));
+ assertEquals(deltaOtherWorm, delta - deltaTheWorm);
+ score += 12;
+ }
+
+ @Test
+ public void move_OverlappingWormsAtDestination() {
+ max_score += 14;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 6.0, 6.0 }, PI, 3.0, "Worm", null);
+ Worm otherWorm1 = facade.createWorm(theWorld, new double[] { 1.0, 8.0 }, 3 * PI / 4.0, 1.0, "WormA", null);
+ Worm otherWorm2 = facade.createWorm(theWorld, new double[] { 3.5, 7.5 }, 3 * PI / 4.0, 1.5, "WormB", null);
+ long oldHitPointsTheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long oldHitPointsOtherWorm1 = facade.getNbHitPoints(otherWorm1).longValue();
+ long oldHitPointsOtherWorm2 = facade.getNbHitPoints(otherWorm2).longValue();
+ facade.move(theWorm);
+ long newHitPointsTheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long newHitPointOtherWorm1 = facade.getNbHitPoints(otherWorm1).longValue();
+ long newHitPointOtherWorm2 = facade.getNbHitPoints(otherWorm2).longValue();
+ long deltaTheWorm = oldHitPointsTheWorm - newHitPointsTheWorm;
+ long deltaOtherWorm1 = oldHitPointsOtherWorm1 - newHitPointOtherWorm1;
+ long deltaOtherWorm2 = oldHitPointsOtherWorm2 - newHitPointOtherWorm2;
+ assertTrue(deltaTheWorm <= 0);
+ assertTrue((deltaOtherWorm1 >= 1) && (deltaOtherWorm1 <= 14));
+ assertTrue((deltaOtherWorm2 >= 1) && (deltaOtherWorm2 <= 15));
+ // Large margin to cope with possible rounding errors.
+ assertEquals(deltaTheWorm, (-deltaOtherWorm1 / 4.0) + (-deltaOtherWorm2 / 3.0), 1.0);
+ score += 14;
+ }
+
+ @Test
+ public void move_DestinationOutsideWorld() {
+ max_score += 10;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 1.2 }, 3 * PI / 2.0, 1.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.move(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ assertEquals(8.0 - 0.0, newLocation[0], EPS);
+ assertEquals(1.2 - 1.0, newLocation[1], EPS);
+ assertEquals(oldNbActionPoints - (1 + 1 * 3), facade.getNbActionPoints(theWorm));
+ assertNull(facade.getWorld(theWorm));
+ assertFalse(facade.hasAsWorm(theWorld, theWorm));
+ score += 10;
+ }
+
+ @Test
+ public void move_WormNotInWorld() {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(null, new double[] { 8.0, 1.2 }, 3 * PI / 2.0, 1.0, "Worm", null);
+ try {
+ facade.move(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void move_NotEnoughActionPoints() {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 7.5 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.decreaseNbActionPoints(theWorm, oldNbActionPoints - 1);
+ try {
+ facade.move(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void move_TerminatedWorm() {
+ max_score += 1;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 8.0, 3.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ facade.terminate(theWorm);
+ try {
+ facade.move(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void fall_InWorldNoOverlappingWorms() {
+ max_score += 15;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm theWorm = facade.createWorm(otherWorld, new double[] { 4.5, 6.0 }, PI, 2.0, "Worm", null);
+ try {
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(theWorm);
+ facade.fall(theWorm);
+ double[] newLocation = facade.getLocation(theWorm);
+ assertTrue(facade.isAdjacent(otherWorld, newLocation, facade.getRadius(theWorm)));
+ assertEquals(4.5, newLocation[0], EPS);
+ assertEquals(3.0+facade.getRadius(theWorm)*0.1/2.0, newLocation[1], facade.getRadius(theWorm)*0.12/2.0);
+ assertEquals(oldNbHitPoints.subtract(BigInteger.valueOf(9)),facade.getNbHitPoints(theWorm) );
+ score += 15;
+ } catch (MustNotImplementException exc) {
+ max_score -= 15;
+ }
+ }
+
+ @Test
+ public void fall_InWorldOverlappingWorms() {
+ max_score += 12;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, false, false, false, true, true, true, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm theWorm = facade.createWorm(otherWorld, new double[] { 4.5, 6.0 }, PI, 2.0, "Worm", null);
+ Worm worm1 = facade.createWorm(otherWorld, new double[] { 5.5, 2.0 }, PI, 1.0, "WormA", null);
+ Worm worm2 = facade.createWorm(otherWorld, new double[] { 3.5, 2.0 }, PI, 1.0, "WormB", null);
+ try {
+ long oldNbHitPoints_TheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long oldNbHitPoints_worm1 = facade.getNbHitPoints(worm1).longValue();
+ long oldNbHitPoints_worm2 = facade.getNbHitPoints(worm2).longValue();
+ facade.fall(theWorm);
+ assertEquals(oldNbHitPoints_TheWorm - 9 + oldNbHitPoints_worm1 / 2 + oldNbHitPoints_worm2 / 2,
+ facade.getNbHitPoints(theWorm).longValue());
+ assertEquals(facade.getNbHitPoints(worm1).longValue(), oldNbHitPoints_worm1 / 2);
+ assertEquals(facade.getNbHitPoints(worm2).longValue(), oldNbHitPoints_worm2 / 2);
+ score += 12;
+ } catch (MustNotImplementException exc) {
+ max_score -= 12;
+ }
+ }
+
+ @Test
+ public void fall_OutOfWorld() {
+ max_score += 6;
+ // Worm hanging on the ceiling.
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 3.0, 8.0 }, 3 * PI / 4.0, 1.0, "Worm", null);
+ try {
+ facade.fall(theWorm);
+ assertFalse(facade.hasAsWorm(theWorld, theWorm));
+ assertNull(facade.getWorld(theWorm));
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ // Worm hanging on side wall.
+ Worm otherWorm = facade.createWorm(theWorld, new double[] { 8.0, 3.0 }, 3 * PI / 4.0, 1.0, "WormB", null);
+ try {
+ facade.fall(otherWorm);
+ assertFalse(facade.hasAsWorm(theWorld, otherWorm));
+ assertNull(facade.getWorld(otherWorm));
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void jumpStep_LegalCase() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 2 * PI / 3.0;
+ double worm_radius = 1.5;
+ long worm_actionPoints = referenceMaxActionPoints(worm_radius);
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] expectedLocation = referenceJumpStep(0.1, worm_location, worm_actionPoints, worm_radius,
+ worm_orientation);
+ double[] stepLocation = facade.getJumpStep(theWorm, 0.1);
+ assertEquals("Result must have exactly 2 coordinates", 2, stepLocation.length);
+ assertEquals("x coordinate must match", expectedLocation[0], stepLocation[0], EPS);
+ assertEquals("y coordinate must match", expectedLocation[1], stepLocation[1], EPS);
+ score += 4;
+ }
+
+ @Test
+ public void jumpStep_VerticalJump() {
+ max_score += 2;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ long worm_actionPoints = referenceMaxActionPoints(worm_radius);
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] expectedLocation = referenceJumpStep(0.1, worm_location, worm_actionPoints, worm_radius,
+ worm_orientation);
+ double[] stepLocation = facade.getJumpStep(theWorm, 0.1);
+ assertEquals("Result must have exactly 2 coordinates", 2, stepLocation.length);
+ assertEquals("x coordinate must match", expectedLocation[0], stepLocation[0], EPS);
+ assertEquals("y coordinate must match", expectedLocation[1], stepLocation[1], EPS);
+ score += 2;
+ }
+
+ @Test
+ public void jumpStep_HorizontalJump() {
+ max_score += 2;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI;
+ double worm_radius = 1.5;
+ long worm_actionPoints = referenceMaxActionPoints(worm_radius);
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] expectedLocation = referenceJumpStep(0.1, worm_location, worm_actionPoints, worm_radius,
+ worm_orientation);
+ double[] stepLocation = facade.getJumpStep(theWorm, 0.1);
+ assertEquals("Result must have exactly 2 coordinates", 2, stepLocation.length);
+ assertEquals("x coordinate must match", expectedLocation[0], stepLocation[0], EPS);
+ assertEquals("y coordinate must match", expectedLocation[1], stepLocation[1], EPS);
+ score += 2;
+ }
+
+ @Test
+ public void jumpStep_NoActionPoints() {
+ max_score += 1;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI;
+ double worm_radius = 1.5;
+ long worm_actionPoints = referenceMaxActionPoints(worm_radius);
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.decreaseNbActionPoints(theWorm, worm_actionPoints);
+ try {
+ facade.getJumpStep(theWorm, 0.1);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void jumpStep_ImproperOrientation() {
+ max_score += 1;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 5.0 * PI / 4.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ facade.getJumpStep(theWorm, 0.1);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void jumpStep_ImproperDt() {
+ max_score += 1;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 5.0 * PI / 4.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ facade.getJumpStep(theWorm, Double.NaN);
+ fail();
+ } catch (ModelException exc) {
+ }
+ try {
+ facade.getJumpStep(theWorm, -1.0);
+ fail();
+ } catch (ModelException exc) {
+ }
+ score += 1;
+ }
+
+ @Test
+ public void jumpTime_ReachingImpassableTerrain() {
+ max_score += 14;
+ double[] worm_location = new double[] { 7.5, 6.5 };
+ double worm_orientation = 3 * PI / 4.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double jumpTime = facade.getJumpTime(theWorm, 0.01);
+ assertEquals(0.39, jumpTime, 0.05);
+ double[] locationAfterJump = facade.getJumpStep(theWorm, jumpTime);
+ assertTrue(facade.isAdjacent(theWorld, locationAfterJump, worm_radius));
+ score += 14;
+ }
+
+ @Test
+ public void jumpTime_OutsideWorld() {
+ max_score += 8;
+ double[] worm_location = new double[] { 8.5, 0.6 };
+ double worm_orientation = 7.0 * PI / 8.0;
+ double worm_radius = 0.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ facade.getJumpTime(theWorm, 0.05);
+ fail();
+ } catch (ModelException exc) {
+ score += 8;
+ }
+ }
+
+ @Test
+ public void jumpTime_TooShort() {
+ max_score += 8;
+ double[] worm_location = new double[] { 7.5, 7.3 };
+ double worm_orientation = 7.0 * PI / 8.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ facade.getJumpTime(theWorm, 0.05);
+ fail();
+ } catch (ModelException exc) {
+ score += 8;
+ }
+ }
+
+ @Test
+ public void jumpTime_WormCannotJump() {
+ max_score += 1;
+ try {
+ facade.getJumpTime(fixtureWorm, 0.001);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void jump_ReachingImpassableTerrain() {
+ max_score += 9;
+ double[] worm_location = new double[] { 7.5, 6.5 };
+ double worm_orientation = 3 * PI / 4.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.jump(theWorm, 0.01);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), worm_radius));
+ assertEquals(0, facade.getNbActionPoints(theWorm));
+ score += 9;
+ }
+
+ @Test
+ public void jump_SingleOverlappingWorm() {
+ max_score += 11;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ double[] worm_location = new double[] { 2.5, 3.0 };
+ double worm_orientation = PI / 4.0;
+ double worm_radius = 2.0;
+ Worm theWorm = facade.createWorm(otherWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Worm worm1 = facade.createWorm(otherWorld, new double[] { 8.0, 4.0 }, 0.5, 1.0, "WormA", null);
+ long oldNbHitPoints_TheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long oldNbHitPoints_worm1 = facade.getNbHitPoints(worm1).longValue();
+ facade.jump(theWorm, 0.01);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), worm_radius));
+ assertEquals(0, facade.getNbActionPoints(theWorm));
+ long newNbHitPoints_TheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long newNbHitPoints_worm1 = facade.getNbHitPoints(worm1).longValue();
+ assertTrue((newNbHitPoints_TheWorm < oldNbHitPoints_TheWorm) ^ (newNbHitPoints_worm1 < oldNbHitPoints_worm1));
+ assertTrue((newNbHitPoints_TheWorm == 0) || (newNbHitPoints_TheWorm >= oldNbHitPoints_TheWorm - 5));
+ assertTrue((newNbHitPoints_worm1 == 0) || (newNbHitPoints_worm1 >= oldNbHitPoints_TheWorm - 40));
+ score += 11;
+ }
+
+ @Test
+ public void jump_SeveralOverlappingWorms() {
+ max_score += 13;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { false, false, false, false, false, false, false, false, false, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ double[] worm_location = new double[] { 2.5, 3.0 };
+ double worm_orientation = PI / 4.0;
+ double worm_radius = 2.0;
+ Worm theWorm = facade.createWorm(otherWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Worm worm1 = facade.createWorm(otherWorld, new double[] { 8.0, 4.0 }, 0.5, 1.0, "WormA", null);
+ Worm worm2 = facade.createWorm(otherWorld, new double[] { 6.0, 4.0 }, 0.5, 3.0, "WormB", null);
+ long oldNbHitPoints_TheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long oldNbHitPoints_worm1 = facade.getNbHitPoints(worm1).longValue();
+ long oldNbHitPoints_worm2 = facade.getNbHitPoints(worm2).longValue();
+ facade.jump(theWorm, 0.01);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), worm_radius));
+ assertEquals(0, facade.getNbActionPoints(theWorm));
+ long newNbHitPoints_TheWorm = facade.getNbHitPoints(theWorm).longValue();
+ long newNbHitPoints_worm1 = facade.getNbHitPoints(worm1).longValue();
+ long newNbHitPoints_worm2 = facade.getNbHitPoints(worm2).longValue();
+ assertTrue(((newNbHitPoints_TheWorm == oldNbHitPoints_TheWorm) && (newNbHitPoints_worm1 < oldNbHitPoints_worm1)
+ && (newNbHitPoints_worm2 < oldNbHitPoints_worm2))
+ || ((newNbHitPoints_TheWorm < oldNbHitPoints_TheWorm) && ((newNbHitPoints_worm1 == oldNbHitPoints_worm1)
+ || (newNbHitPoints_worm2 == oldNbHitPoints_worm2))));
+ score += 13;
+ }
+
+ @Test
+ public void jump_NoJumpPossible() {
+ max_score += 3;
+ try {
+ double[] worm_location = new double[] { 7.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.jump(theWorm, 0.01);
+ fail();
+ } catch (ModelException exc) {
+ score += 3;
+ }
+ }
+
+ @Test
+ public void jump_DirectedDownward() {
+ max_score += 1;
+ try {
+ double[] worm_location = new double[] { 7.5, 6.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.jump(theWorm, 0.01);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void eat_WormNotInWorld() {
+ max_score += 1;
+ facade.eat(fixtureWorm);
+ assertEquals(FIXTURE_RADIUS, facade.getRadius(fixtureWorm), EPS);
+ assertEquals(FIXTURE_LOCATION[0], facade.getLocation(fixtureWorm)[0], EPS);
+ assertEquals(FIXTURE_LOCATION[1], facade.getLocation(fixtureWorm)[1], EPS);
+ score += 1;
+ }
+
+ @Test
+ public void eat_NoOverlappingPortion() {
+ max_score += 2;
+ double[] worm_location = new double[] { 4.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 0.5, 8.795 };
+ Food newFood = facade.createFood(theWorld, location);
+ facade.eat(theWorm);
+ assertFalse(facade.isTerminated(newFood));
+ assertEquals(1.5, facade.getRadius(theWorm), EPS);
+ assertEquals(4.5, facade.getLocation(theWorm)[0], EPS);
+ assertEquals(7.5, facade.getLocation(theWorm)[1], EPS);
+ score += 2;
+ }
+
+ @Test
+ public void eat_OverlapWithSingleHealthyPortion() {
+ max_score += 8;
+ double[] worm_location = new double[] { 4.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 4.5, 8.795 };
+ Food newFood = facade.createFood(theWorld, location);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood));
+ assertEquals(1.5 * 1.1, facade.getRadius(theWorm), EPS);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), facade.getRadius(theWorm)));
+ assertTrue(getDistance(worm_location,facade.getLocation(theWorm)) < facade.getRadius(theWorm)*0.2);
+ assertEquals(oldNbActionPoints - 8, facade.getNbActionPoints(theWorm));
+ score += 8;
+ }
+
+ @Test
+ public void eat_OverlapWithSinglePoisonousPortion() {
+ max_score += 8;
+ double[] worm_location = new double[] { 4.5, 7.49 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 4.5, 8.795 };
+ Food newFood = facade.createFood(theWorld, location);
+ facade.poison(newFood);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood));
+ assertEquals(1.5 * 0.9, facade.getRadius(theWorm), EPS);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), facade.getRadius(theWorm)));
+ assertTrue(getDistance(worm_location,facade.getLocation(theWorm)) < facade.getRadius(theWorm)*0.2);
+ long expectedNbActionPoints = Math.min(oldNbActionPoints - 8,
+ referenceMaxActionPoints(facade.getRadius(theWorm)));
+ assertEquals(expectedNbActionPoints, facade.getNbActionPoints(theWorm));
+ score += 8;
+ }
+
+ @Test
+ public void eat_SmallWormOverlapWithSinglePoisonousPortion() {
+ max_score += 6;
+ double[] worm_location = new double[] { 4.5, 8.73 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 0.26;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 4.5, 8.795 };
+ Food newFood = facade.createFood(theWorld, location);
+ facade.poison(newFood);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood));
+ assertEquals(0.25, facade.getRadius(theWorm), EPS);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), facade.getRadius(theWorm)));
+ assertTrue(getDistance(worm_location,facade.getLocation(theWorm)) < facade.getRadius(theWorm)*0.2);
+ long expectedNbActionPoints = Math.min(oldNbActionPoints - 8,
+ referenceMaxActionPoints(facade.getRadius(theWorm)));
+ assertEquals(expectedNbActionPoints, facade.getNbActionPoints(theWorm));
+ score += 6;
+ }
+
+ @Test
+ public void eat_OverlapWithSeveralHealthyPortions() {
+ max_score += 2;
+ double[] worm_location = new double[] { 4.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Food newFood1 = facade.createFood(theWorld, new double[] { 4.5, 8.795 });
+ Food newFood2 = facade.createFood(theWorld, new double[] { 4.2, 8.795 });
+ Food newFood3 = facade.createFood(theWorld, new double[] { 4.8, 8.795 });
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood1) ^ facade.isTerminated(newFood2) ^ facade.isTerminated(newFood3));
+ assertEquals(1.5 * 1.1, facade.getRadius(theWorm), EPS);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), facade.getRadius(theWorm)));
+ assertTrue(getDistance(worm_location,facade.getLocation(theWorm)) < facade.getRadius(theWorm)*0.2);
+ assertEquals(oldNbActionPoints - 8, facade.getNbActionPoints(theWorm));
+ score += 2;
+ }
+
+ @Test
+ public void eat_WormLocatedInCorner() {
+ max_score += 18;
+ double[] worm_location = new double[] { 7.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Food newFood1 = facade.createFood(theWorld, new double[] { 7.5, 8.795 });
+ Food newFood2 = facade.createFood(theWorld, new double[] { 8.795, 7.5 });
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood1) ^ facade.isTerminated(newFood2));
+ assertEquals(1.5 * 1.1, facade.getRadius(theWorm), EPS);
+ assertTrue(facade.isAdjacent(theWorld, facade.getLocation(theWorm), facade.getRadius(theWorm)));
+ assertTrue(getDistance(worm_location,facade.getLocation(theWorm)) < facade.getRadius(theWorm)*0.2);
+ assertEquals(oldNbActionPoints - 8, facade.getNbActionPoints(theWorm));
+ score += 18;
+ }
+
+ @Test
+ public void eat_NotEnoughActionPoints() {
+ max_score += 2;
+ double[] worm_location = new double[] { 4.5, 7.5 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 4.5, 8.795 };
+ Food newFood = facade.createFood(theWorld, location);
+ facade.decreaseNbActionPoints(theWorm, facade.getNbActionPoints(theWorm) - 7);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertFalse(facade.isTerminated(newFood));
+ assertEquals(1.5, facade.getRadius(theWorm), EPS);
+ assertEquals(4.5, facade.getLocation(theWorm)[0], EPS);
+ assertEquals(7.5, facade.getLocation(theWorm)[1], EPS);
+ assertEquals(oldNbActionPoints, facade.getNbActionPoints(theWorm));
+ score += 2;
+ }
+
+ @Test
+ public void eat_EnlargedWormNotFullyInWorld() {
+ max_score += 8;
+ double[] worm_location = new double[] { 7.5, 1.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ double[] location = new double[] { 8.795, 1.5 };
+ Food newFood = facade.createFood(theWorld, location);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(newFood));
+ assertNull(facade.getWorld(theWorm));
+ assertTrue(facade.getAllItems(theWorld).isEmpty());
+ assertEquals(oldNbActionPoints - 8, facade.getNbActionPoints(theWorm));
+ score += 8;
+ }
+
+ @Test
+ public void eat_ExplodingWorm() {
+ max_score += 15;
+ map10x10 = new boolean[][] { { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, true, true, true, true, true, false },
+ { true, true, true, true, false, false, false,false, false,false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, true, false },
+ { false,false,false,false,false,false,false,false,false,false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ double[] worm_location = new double[] { 7.0, 3.0 };
+ double worm_orientation = PI / 4.0;
+ double worm_radius = 2.0;
+ Worm theWorm = facade.createWorm(otherWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.createFood(otherWorld, new double[] { 8.79, 3.0 });
+ facade.eat(theWorm);
+ assertTrue(facade.isTerminated(theWorm));
+ assertTrue(facade.getAllItems(otherWorld).isEmpty());
+ score += 15;
+ }
+
+ @Test
+ public void fire_LegalCase() {
+ max_score += 12;
+ double[] worm_location = new double[] { 7.5, 3.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ for (int nbTries = 1; nbTries <= 10; nbTries++) {
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ Projectile projectile = facade.fire(theWorm);
+ assertEquals(3 * PI / 2.0, facade.getOrientation(projectile), EPS);
+ double[] projectileLocation = facade.getLocation(projectile);
+ assertEquals(7.5, projectileLocation[0], EPS);
+ assertEquals(3.505 - worm_radius - facade.getRadius(projectile), projectileLocation[1], EPS);
+ assertTrue(facade.getNbActionPoints(theWorm) < oldNbActionPoints);
+ }
+ score += 12;
+ }
+
+ @Test
+ public void fire_WormOverlapsWithBullet() {
+ max_score += 12;
+ double[] worm_location = new double[] { 7.495, 5.8 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile = facade.fire(theWorm);
+ facade.jump(projectile, 0.00001);
+ Worm otherWorm = facade.createWorm(theWorld, new double[] { 7.495, 7.5 }, worm_orientation, worm_radius, "Worm",
+ null);
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(otherWorm);
+ assertNull(facade.fire(otherWorm));
+ assertTrue(oldNbHitPoints.compareTo(facade.getNbHitPoints(otherWorm)) > 0);
+ assertTrue(facade.isTerminated(projectile));
+ score += 12;
+ }
+
+ @Test
+ public void fire_BulletNotFullyInWorld() {
+ max_score += 7;
+ double[] worm_location = new double[] { 7.5, 1.50005 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ facade.fire(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 7;
+ }
+ }
+
+ @Test
+ public void fire_NotInWorld() {
+ max_score += 1;
+ try {
+ facade.fire(fixtureWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ @Test
+ public void fire_NotEnoughActionPoints() {
+ max_score += 1;
+ try {
+ double[] worm_location = new double[] { 7.5, 1.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.decreaseNbActionPoints(theWorm, facade.getNbActionPoints(theWorm) - 20);
+ facade.fire(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ }
+ }
+
+ /**************
+ * FOOD TESTS
+ *************/
+
+ @Test
+ public void createFood_LegalCaseNoWorld() {
+ max_score += 1;
+ double[] location = new double[] { 3.0, -7.0 };
+ Food newFood = facade.createFood(null, location);
+ assertNull(facade.getWorld(newFood));
+ assertEquals(location[0], facade.getLocation(newFood)[0], EPS);
+ assertEquals(location[1], facade.getLocation(newFood)[1], EPS);
+ assertEquals(0.2, facade.getRadius(newFood), EPS);
+ assertEquals(150.0 * (4.0 / 3.0 * PI * Math.pow(0.2, 3.0)), facade.getMass(newFood), EPS);
+ assertFalse(facade.isPoisonous(newFood));
+ score += 1;
+ }
+
+ @Test
+ public void createFood_LegalCaseinWorld() {
+ max_score += 1;
+ double[] location = new double[] { 3.0, 8.79 };
+ Food newFood = facade.createFood(theWorld, location);
+ assertEquals(theWorld, facade.getWorld(newFood));
+ assertTrue(facade.hasAsFood(theWorld, newFood));
+ assertEquals(location[0], facade.getLocation(newFood)[0], EPS);
+ assertEquals(location[1], facade.getLocation(newFood)[1], EPS);
+ assertEquals(0.2, facade.getRadius(newFood), EPS);
+ assertEquals(150.0 * (4.0 / 3.0 * PI * Math.pow(0.2, 3.0)), facade.getMass(newFood), EPS);
+ assertFalse(facade.isPoisonous(newFood));
+ score += 1;
+ }
+
+ @Test
+ public void terminateFood_NoWorld() {
+ max_score += 1;
+ facade.terminate(fixtureFood);
+ assertTrue(facade.isTerminated(fixtureFood));
+ score += 1;
+ }
+
+ @Test
+ public void terminateFood_InWorld() {
+ max_score += 1;
+ double[] location = new double[] { 3.0, 8.79 };
+ Food newFood = facade.createFood(theWorld, location);
+ facade.terminate(newFood);
+ assertTrue(facade.isTerminated(newFood));
+ assertNull(facade.getWorld(newFood));
+ assertFalse(facade.hasAsFood(theWorld, newFood));
+ score += 1;
+ }
+
+ /*******************
+ * PROJECTILE TESTS
+ *******************/
+
+ @Test
+ public void jumpStepProjectile_LegalCase() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 2 * PI / 3.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile = facade.fire(theWorm);
+ double[] stepLocation = facade.getJumpStep(projectile, 0.1);
+ double[] expectedRifleLocation = new double[] { 2.997, 9.275 };
+ double[] expectedBazookaLocation = new double[] { 6.114, 3.875 };
+ assertEquals("Result must have exactly 2 coordinates", 2, stepLocation.length);
+ assertTrue((Math.abs(stepLocation[0] - expectedRifleLocation[0]) < 0.01)
+ || (Math.abs(stepLocation[0] - expectedBazookaLocation[0]) < 0.01));
+ assertTrue((Math.abs(stepLocation[1] - expectedRifleLocation[1]) < 0.01)
+ || (Math.abs(stepLocation[1] - expectedBazookaLocation[1]) < 0.01));
+ score += 4;
+ }
+
+ @Test
+ public void jumpTimeProjectile_ReachingImpassableTerrain() {
+ max_score += 8;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile = facade.fire(theWorm);
+ double jumpTime = facade.getJumpTime(projectile, 0.00001);
+ assertTrue((Math.abs(jumpTime - 0.08) < 0.01) || (Math.abs(jumpTime - 0.53) < 0.01));
+ double[] locationAfterJump = facade.getJumpStep(projectile, jumpTime);
+ assertTrue(facade.isAdjacent(theWorld, locationAfterJump, facade.getRadius(projectile))
+ || (!facade.isPassable(theWorld, locationAfterJump, facade.getRadius(projectile))));
+ score += 8;
+ }
+
+ @Test
+ public void jumpTimeProjectile_HittingWorm() {
+ max_score += 8;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ facade.createWorm(theWorld, new double[] { 7.5, 7.5 }, 0.0, 1.5, "Other", null);
+ Projectile projectile = facade.fire(theWorm);
+ double jumpTime = facade.getJumpTime(projectile, 0.00001);
+ assertTrue((Math.abs(jumpTime - 0.08) < 0.01) || (Math.abs(jumpTime - 0.53) < 0.01));
+ double[] locationAfterJump = facade.getJumpStep(projectile, jumpTime);
+ assertTrue(locationAfterJump[1] >= 6.0 - facade.getRadius(projectile));
+ score += 8;
+ }
+
+ @Test
+ public void jumpTimeProjectile_OutsideWorld() {
+ max_score += 6;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 0.99 * PI;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ Projectile projectile = facade.fire(theWorm);
+ facade.getJumpTime(projectile, 0.00001);
+ fail();
+ } catch (ModelException exc) {
+ score += 6;
+ }
+ }
+
+ @Test
+ public void jumpProjectile_HittingSingleWorm() {
+ max_score += 10;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Worm hittedWorm = facade.createWorm(theWorld, new double[] { 7.5, 7.5 }, 0.0, 1.5, "Other", null);
+ BigInteger oldNbHitPoints = facade.getNbHitPoints(hittedWorm);
+ Projectile projectile = facade.fire(theWorm);
+ facade.jump(projectile, 0.00001);
+ assertTrue(oldNbHitPoints.compareTo(facade.getNbHitPoints(hittedWorm)) > 0);
+ assertTrue(facade.isTerminated(projectile));
+ score += 10;
+ }
+
+ @Test
+ public void jumpProjectile_HittingSeveralWorms() {
+ max_score += 6;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Worm hittedWorm1 = facade.createWorm(theWorld, new double[] { 7.5, 7.5 }, 0.0, 1.5, "OtherA", null);
+ Worm hittedWorm2 = facade.createWorm(theWorld, new double[] { 7.5, 8.0 }, 0.0, 1.0, "OtherB", null);
+ BigInteger oldNbHitPoints1 = facade.getNbHitPoints(hittedWorm1);
+ BigInteger oldNbHitPoints2 = facade.getNbHitPoints(hittedWorm2);
+ Projectile projectile = facade.fire(theWorm);
+ facade.jump(projectile, 0.00001);
+ assertTrue(oldNbHitPoints1.compareTo(facade.getNbHitPoints(hittedWorm1)) > 0);
+ assertTrue(oldNbHitPoints2.compareTo(facade.getNbHitPoints(hittedWorm2)) > 0);
+ assertTrue(facade.isTerminated(projectile));
+ score += 6;
+ }
+
+ @Test
+ public void jumpProjectile_OutsideWorld() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = 0.99 * PI;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ try {
+ Projectile projectile = facade.fire(theWorm);
+ facade.jump(projectile, 0.0001);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ }
+ }
+
+ @Test
+ public void jumpProjectile_ReachingImpassableTerrain() {
+ max_score += 6;
+ double[] worm_location = new double[] { 7.5, 1.5 };
+ double worm_orientation = PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile = facade.fire(theWorm);
+ facade.jump(projectile, 0.00001);
+ double[] locationAfterJump = facade.getLocation(projectile);
+ assertTrue(facade.isAdjacent(theWorld, locationAfterJump, facade.getRadius(projectile))
+ || (!facade.isPassable(theWorld, locationAfterJump, facade.getRadius(projectile))));
+ assertFalse(facade.isTerminated(projectile));
+ score += 6;
+ }
+
+ /**************
+ * TEAM TESTS
+ *************/
+
+ @Test
+ public void createTeam_LegalCaseNoWorld() {
+ max_score += 2;
+ try {
+ Team theTeam = facade.createTeam(null, "Team");
+ assertEquals(0, facade.getNbWormsOfTeam(theTeam));
+ assertEquals("Team", facade.getName(theTeam));
+ assertFalse(facade.isTerminated(theTeam));
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void createTeam_LegalCaseInWorld() {
+ max_score += 4;
+ try {
+ assertEquals(0, facade.getNbWormsOfTeam(theTeam));
+ assertEquals("TheTeam", facade.getName(theTeam));
+ assertFalse(facade.isTerminated(theTeam));
+ assertTrue(facade.getAllTeams(theWorld).contains(theTeam));
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void createTeam_IllegalName() {
+ max_score += 1;
+ try {
+ facade.createTeam(theWorld, "'abc");
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ @Test
+ public void createTeam_TooManyTeams() {
+ max_score += 3;
+ try {
+ facade.createTeam(theWorld, "TeamB");
+ score -= 3;
+ facade.createTeam(theWorld, "TeamC");
+ facade.createTeam(theWorld, "TeamD");
+ facade.createTeam(theWorld, "TeamE");
+ facade.createTeam(theWorld, "TeamF");
+ facade.createTeam(theWorld, "TeamG");
+ facade.createTeam(theWorld, "TeamH");
+ facade.createTeam(theWorld, "TeamI");
+ facade.createTeam(theWorld, "TeamJ");
+ // We must reach this point, otherwise we are not
+ // able to have 10 teams in a world.
+ score += 3;
+ facade.createTeam(theWorld, "TeamH");
+ fail();
+ } catch (ModelException exc) {
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void terminate_SingleCase() {
+ max_score += 5;
+ try {
+ Worm wormA = facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormA",
+ theTeam);
+ Worm wormB = facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormB",
+ theTeam);
+ facade.terminate(theTeam);
+ assertTrue(facade.isTerminated(theTeam));
+ assertEquals(0, facade.getAllWormsOfTeam(theTeam).size());
+ assertNull(facade.getTeam(wormA));
+ assertNull(facade.getTeam(wormB));
+ score += 5;
+ } catch (MustNotImplementException exc) {
+ max_score -= 5;
+ }
+ }
+
+ @Test
+ public void getAllWormsOfTeam_LegalCase() {
+ max_score += 2;
+ try {
+ Worm wormA = facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormA",
+ theTeam);
+ Worm wormB = facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormB",
+ theTeam);
+ List members = facade.getAllWormsOfTeam(theTeam);
+ assertEquals(2, members.size());
+ assertTrue(members.contains(wormA));
+ assertTrue(members.contains(wormB));
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void getAllWormsOfTeam_LeakTest() {
+ max_score += 10;
+ try {
+ facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormA", theTeam);
+ facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormB", theTeam);
+ List members = facade.getAllWormsOfTeam(theTeam);
+ Worm wormC = facade.createWorm(null, new double[] { 2.0, Double.POSITIVE_INFINITY }, 2.0, 12.0, "WormC",
+ null);
+ members.add(wormC);
+ assertEquals(2, facade.getNbWormsOfTeam(theTeam));
+ assertFalse(facade.getAllWormsOfTeam(theTeam).contains(wormC));
+ score += 10;
+ } catch (MustNotImplementException exc) {
+ max_score -= 10;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_SeveralWormsOfSameWorld() {
+ max_score += 4;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", null);
+ Worm wormC = facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", null);
+ facade.addWormsToTeam(theTeam, wormA, wormB, wormC);
+ assertEquals(3, facade.getNbWormsOfTeam(theTeam));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormA));
+ assertEquals(theTeam, facade.getTeam(wormA));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormB));
+ assertEquals(theTeam, facade.getTeam(wormB));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormC));
+ assertEquals(theTeam, facade.getTeam(wormC));
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormsFromDifferentWorlds() {
+ max_score += 4;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ Worm wormB = facade.createWorm(otherWorld, new double[] { 2.5, 3.0 }, 2.0, 1.0, "WormB", null);
+ Worm wormC = facade.createWorm(null, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", null);
+ facade.addWormsToTeam(theTeam, wormA, wormB, wormC);
+ assertEquals(3, facade.getNbWormsOfTeam(theTeam));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormA));
+ assertEquals(theTeam, facade.getTeam(wormA));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormB));
+ assertEquals(theTeam, facade.getTeam(wormB));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormC));
+ assertEquals(theTeam, facade.getTeam(wormC));
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_NullSequenceOfWorms() {
+ max_score += 1;
+ try {
+ facade.addWormsToTeam(theTeam, (Worm[]) null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormWithSameNameAlreadyInTeam() {
+ max_score += 3;
+ try {
+ facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormABis = facade.createWorm(otherWorld, new double[] { 2.5, 3.0 }, 2.0, 1.0, "WormA", null);
+ facade.addWormsToTeam(theTeam, wormABis);
+ fail();
+ } catch (ModelException exc) {
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormsWitSameName() {
+ max_score += 3;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ Worm wormABis = facade.createWorm(otherWorld, new double[] { 2.5, 3.0 }, 2.0, 1.0, "WormA", null);
+ facade.addWormsToTeam(theTeam, wormA, wormABis);
+ fail();
+ } catch (ModelException exc) {
+ assertEquals(0, facade.getNbWormsOfTeam(theTeam));
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_SameWormSeveralTimes() {
+ max_score += 3;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ facade.addWormsToTeam(theTeam, wormA, wormA);
+ // Accepting the worm once is OK.
+ assertEquals(1, facade.getNbWormsOfTeam(theTeam));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormA));
+ score += 3;
+ } catch (ModelException exc) {
+ // Rejecting duplicate worms is also OK.
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormTooLight() {
+ max_score += 4;
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(otherWorld, new double[] { 2.5, 3.0 }, 2.0, 1.0, "WormB", null);
+ try {
+ facade.addWormsToTeam(theTeam, wormB);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormTooHeavy() {
+ max_score += 4;
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 8.0 }, 2.0, 1.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(otherWorld, new double[] { 2.5, 2.0 }, 2.0, 2.0, "WormB", null);
+ try {
+ facade.addWormsToTeam(theTeam, wormB);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_WormAlreadyInOtherTeam() {
+ max_score += 2;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Team otherTeam = facade.createTeam(null, "OtherTeam");
+ facade.addWormsToTeam(otherTeam, wormA);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_TerminatedWorm() {
+ max_score += 2;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ facade.terminate(wormA);
+ facade.addWormsToTeam(theTeam, wormA);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void addWormsToTeam_NonEffectiveWorm() {
+ max_score += 2;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", null);
+ Worm[] wormsToAdd = new Worm[] { wormA, null };
+ facade.addWormsToTeam(theTeam, wormsToAdd);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ } catch (MustNotImplementException exc) {
+ max_score -= 2;
+ }
+ }
+
+ @Test
+ public void removeWormsFromTeam_SeveralWormsFromTeam() {
+ max_score += 4;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", theTeam);
+ Worm wormC = facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", theTeam);
+ facade.removeWormsFromTeam(theTeam, wormA, wormC);
+ assertEquals(1, facade.getNbWormsOfTeam(theTeam));
+ assertFalse(facade.getAllWormsOfTeam(theTeam).contains(wormA));
+ assertNull(facade.getTeam(wormA));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormB));
+ assertFalse(facade.getAllWormsOfTeam(theTeam).contains(wormC));
+ assertNull(facade.getTeam(wormC));
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void removeWormsFromTeam_NoWorms() {
+ max_score += 1;
+ try {
+ facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", theTeam);
+ facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", theTeam);
+ facade.removeWormsFromTeam(theTeam);
+ assertEquals(3, facade.getNbWormsOfTeam(theTeam));
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ @Test
+ public void removeWormsFromTeam_NullSequenceOfWorms() {
+ max_score += 1;
+ try {
+ facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ facade.removeWormsFromTeam(theTeam, (Worm[]) null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ @Test
+ public void removeWormsFromTeam_WormOfOtherTeam() {
+ max_score += 4;
+ Team otherTeam = null;
+ try {
+ otherTeam = facade.createTeam(null, "OtherTeam");
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", otherTeam);
+ facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", otherTeam);
+ facade.removeWormsFromTeam(otherTeam, wormB, wormA);
+ fail();
+ } catch (ModelException exc) {
+ assertEquals(2, facade.getAllWormsOfTeam(otherTeam).size());
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void removeWormsFromTeam_NonEffectiveWorm() {
+ max_score += 4;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", theTeam);
+ Worm wormC = facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", theTeam);
+ facade.removeWormsFromTeam(theTeam, new Worm[] { wormB, null, wormC });
+ fail();
+ } catch (ModelException exc) {
+ assertEquals(3, facade.getAllWormsOfTeam(theTeam).size());
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void mergeTeams_LegalCase() {
+ max_score += 10;
+ try {
+ Worm wormA = facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ Worm wormB = facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", theTeam);
+ Team otherTeam = facade.createTeam(otherWorld, "OtherTeam");
+ Worm wormC = facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormC", otherTeam);
+ Worm wormD = facade.createWorm(otherWorld, new double[] { 2.5, 2.0 }, 2.0, 2.0, "WormD", otherTeam);
+ facade.mergeTeams(theTeam, otherTeam);
+ assertEquals(4, facade.getNbWormsOfTeam(theTeam));
+ assertEquals(0, facade.getNbWormsOfTeam(otherTeam));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormC));
+ assertEquals(theTeam, facade.getTeam(wormC));
+ assertTrue(facade.getAllWormsOfTeam(theTeam).contains(wormD));
+ assertEquals(theTeam, facade.getTeam(wormD));
+ score += 10;
+ } catch (MustNotImplementException exc) {
+ max_score -= 10;
+ }
+ }
+
+ @Test
+ public void mergeTeams_NameConflict() {
+ max_score += 6;
+ Team otherTeam = null;
+ try {
+ facade.createWorm(theWorld, new double[] { 2.3, 7.0 }, 2.0, 2.0, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.8, 7.0 }, 2.0, 2.0, "WormB", theTeam);
+ otherTeam = facade.createTeam(otherWorld, "OtherTeam");
+ facade.createWorm(theWorld, new double[] { 7.0, 2.5 }, 2.0, 2.0, "WormA", otherTeam);
+ facade.createWorm(otherWorld, new double[] { 2.5, 2.0 }, 2.0, 2.0, "WormD", otherTeam);
+ facade.mergeTeams(theTeam, otherTeam);
+ fail();
+ } catch (ModelException exc) {
+ assertEquals(2, facade.getAllWormsOfTeam(theTeam).size());
+ assertEquals(2, facade.getAllWormsOfTeam(otherTeam).size());
+ score += 6;
+ } catch (MustNotImplementException exc) {
+ max_score -= 6;
+ }
+ }
+
+ @Test
+ public void mergeTeams_NonEffectiveTeam() {
+ max_score += 1;
+ try {
+ facade.mergeTeams(theTeam, null);
+ fail();
+ } catch (ModelException exc) {
+ score += 1;
+ } catch (MustNotImplementException exc) {
+ max_score -= 1;
+ }
+ }
+
+ /***************
+ * WIZARD TESTS
+ **************/
+
+ @Test
+ public void castSpell_NotEnoughGameObjects() {
+ max_score += 2;
+ try {
+ facade.castSpell(theWorld);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void castSpell_WormsSameTeam() {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormA", theTeam);
+ BigInteger nbHitPoints1 = facade.getNbHitPoints(worm1);
+ Worm worm2 = facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", theTeam);
+ BigInteger nbHitPoints2 = facade.getNbHitPoints(worm2);
+ facade.castSpell(theWorld);
+ BigInteger expectedNbHitPoints = nbHitPoints1.add(nbHitPoints2).divide(BigInteger.valueOf(2));
+ assertEquals(expectedNbHitPoints, facade.getNbHitPoints(worm1));
+ assertEquals(expectedNbHitPoints, facade.getNbHitPoints(worm2));
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_WormsDifferentTeams() {
+ max_score += 4;
+ Worm largestWorm = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormA",
+ theTeam);
+ long nbActionPointsLargest = facade.getNbActionPoints(largestWorm);
+ Worm smallestWorm = facade.createWorm(theWorld, new double[] { 6.0, 8.0 }, FIXTURE_DIRECTION, 1.0, "WormB",
+ null);
+ facade.decreaseNbActionPoints(smallestWorm, 10);
+ long nbActionPointsSmallest = facade.getNbActionPoints(smallestWorm);
+ facade.castSpell(theWorld);
+ long actionPointsToTransfer = Math.min(nbActionPointsLargest, 5);
+ assertEquals(nbActionPointsLargest - actionPointsToTransfer, facade.getNbActionPoints(largestWorm));
+ assertEquals(nbActionPointsSmallest + actionPointsToTransfer, facade.getNbActionPoints(smallestWorm));
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_WormsWithFood() {
+ max_score += 4;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormA", theTeam);
+ double[] location = new double[] { 8.795, 1.5 };
+ Food theFood = facade.createFood(theWorld, location);
+ facade.castSpell(theWorld);
+ assertEquals(1.5 * 1.1, facade.getRadius(theWorm), EPS);
+ assertFalse(facade.isTerminated(theFood));
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_Food() {
+ max_score += 4;
+ Food food1 = facade.createFood(theWorld, new double[] { 8.795, 1.5 });
+ Food food2 = facade.createFood(theWorld, new double[] { 8.795, 7.5 });
+ facade.poison(food2);
+ facade.castSpell(theWorld);
+ assertTrue(facade.isPoisonous(food1));
+ assertFalse(facade.isPoisonous(food2));
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_WormWithProjectile() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 3.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ long oldNbActionPoints = facade.getNbActionPoints(theWorm);
+ facade.fire(theWorm);
+ facade.castSpell(theWorld);
+ assertTrue(facade.getNbActionPoints(theWorm) < oldNbActionPoints);
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_FoodWithProjectile() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 3.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile = facade.fire(theWorm);
+ facade.terminate(theWorm);
+ double[] location = new double[] { 8.795, 1.5 };
+ Food theFood = facade.createFood(theWorld, location);
+ facade.castSpell(theWorld);
+ assertTrue(facade.isTerminated(theFood));
+ assertTrue(facade.isTerminated(projectile));
+ score += 4;
+ }
+
+ @Test
+ public void castSpell_Projectiles() {
+ max_score += 4;
+ double[] worm_location = new double[] { 7.5, 3.505 };
+ double worm_orientation = 3 * PI / 2.0;
+ double worm_radius = 1.5;
+ Worm theWorm = facade.createWorm(theWorld, worm_location, worm_orientation, worm_radius, "Worm", null);
+ Projectile projectile1 = facade.fire(theWorm);
+ int oldNbHitPoints1 = facade.getNbHitPoints(projectile1);
+ Projectile projectile2 = facade.fire(theWorm);
+ int oldNbHitPoints2 = facade.getNbHitPoints(projectile2);
+ facade.terminate(theWorm);
+ facade.castSpell(theWorld);
+ assertTrue((facade.getNbHitPoints(projectile1) == oldNbHitPoints1 + 2) || (oldNbHitPoints1 == 7)
+ || (oldNbHitPoints1 == 10));
+ assertTrue((facade.getNbHitPoints(projectile2) == oldNbHitPoints2 + 2) || (oldNbHitPoints2 == 7)
+ || (oldNbHitPoints2 == 10));
+ score += 4;
+ }
+
+ /****************
+ * PROGRAM TESTS
+ ***************/
+
+ @Test
+ public void loadProgram_ActiveGame() {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ facade.startGame(theWorld);
+ String code = "print 2.0;";
+ Program theProgram = ProgramParser.parseProgramFromString(code, programFactory);
+ try {
+ facade.loadProgramOnWorm(theWorm, theProgram, actionHandler);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ /******************
+ * STATEMENT TESTS
+ ******************/
+
+ @Test
+ public void testPrintStatement_LegalCase() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testSequenceStatement_EmptyBody() throws ModelException {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "{ }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 3;
+ }
+
+ @Test
+ public void testSequenceStatement_NonNestedNonInterruptable() throws ModelException {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "{ print 4.0; " + "print 12.0; }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 4.0, 12.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 3;
+ }
+
+ @Test
+ public void testSequenceStatement_NestedNonInterruptable() throws ModelException {
+ max_score += 5;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 4.0; " + " { print 12.0; print 6.0; } print 15.0; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 4.0, 12.0, 6.0, 15.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 5;
+ }
+
+ @Test
+ public void testSequenceStatement_NonNestedInterruptable() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.2, 1.5, "WormA", theTeam);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ String code = "{ print 4.0; turn 1.0; print 12.0; }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 4.0, 12.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.2, facade.getOrientation(worm1), EPS);
+ score += 10;
+ }
+
+ @Test
+ public void testSequenceStatement_NestedInterruptable() throws ModelException {
+ max_score += 15;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.2, 1.5, "WormA", theTeam);
+ String code = "{ print 4.0; { print 3.0; turn 1.0; print 2.0; } turn 0.4; print 12.0; }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -10);
+ results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 4.0, 3.0, 2.0, 12.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.6, facade.getOrientation(worm1), EPS);
+ score += 15;
+ }
+
+ @Test
+ public void testAssignmentStatement_NewVariable() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "{ varname := 7.0; print varname; }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 7.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ }
+
+ @Test
+ public void testAssignmentStatement_ExistingVariable() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "{ varname := 7.0; varname := 12.0; print varname; }";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 12.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ }
+
+ @Test
+ public void testAssignmentStatement_AssignmentToProcedureName() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: print 4.0; p := 7.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 10;
+ } catch (MustNotImplementException exc) {
+ max_score -= 10;
+ }
+ }
+
+ @Test
+ public void testTurnStatement_LegalCase() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 1.0, 1.5, "WormA", theTeam);
+ String code = "turn 0.5; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.5, facade.getOrientation(worm1), EPS);
+ score += 4;
+ }
+
+ @Test
+ public void testTurnStatement_NonDoubleAngle() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "turn null;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void testTurnStatement_AngleOutOfRange() throws ModelException {
+ max_score += 5;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "turn 10.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 5;
+ }
+ }
+
+ @Test
+ public void testTurnStatement_NotEnoughActionPoints() throws ModelException {
+ max_score += 6;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ String code = "turn 1.0; print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ assertEquals(0.0, facade.getOrientation(worm1), EPS);
+ score += 6;
+ }
+
+ @Test
+ public void testMoveStatement_WormMoving() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 6.0 }, PI / 4.0, 1.5, "WormA", theTeam);
+ String code = "move; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertNotEquals(7.5, facade.getLocation(worm1)[0], EPS);
+ score += 4;
+ }
+
+ @Test
+ public void testMoveStatement_WormKeepsPosition() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 7.5 }, PI / 2.0, 1.5, "WormA", theTeam);
+ String code = "move; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(7.5, facade.getLocation(worm1)[0], EPS);
+ assertEquals(7.5, facade.getLocation(worm1)[1], EPS);
+ score += 4;
+ }
+
+ @Test
+ public void testMoveStatement_NotEnoughActionPoints() throws ModelException {
+ max_score += 6;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 2.0 }, PI / 4.0, 1.5, "WormA", theTeam);
+ String code = "move; print 4.0; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ score += 6;
+ }
+
+ @Test
+ public void testJumpStatement_WormJumping() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ String code = "jump; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertNotEquals(7.5, facade.getLocation(worm1)[0], EPS);
+ assertNotEquals(5.5, facade.getLocation(worm1)[1], EPS);
+ score += 4;
+ }
+
+ @Test
+ public void testJumpStatement_NoActionPoints() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ String code = "jump; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ score += 4;
+ }
+
+ @Test
+ public void testJumpStatement_OrientedDown() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 3 * PI / 2.0, 1.5, "WormA", theTeam);
+ String code = "jump; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ }
+ }
+
+ @Test
+ public void testEatStatement_WormEating() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ Food food = facade.createFood(theWorld, new double[] {8.795,5.5});
+ String code = "eat; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertTrue(facade.getRadius(worm1) > 1.5);
+ assertNotEquals(7.5, facade.getLocation(worm1)[0], EPS);
+ assertTrue(facade.isTerminated(food));
+ score += 4;
+ }
+
+ @Test
+ public void testEatStatement_NothingToEat() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ String code = "eat; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.5,facade.getRadius(worm1),EPS);
+ score += 4;
+ }
+
+ @Test
+ public void testEatStatement_NotEnoughActionPoints() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ String code = "eat; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ score += 4;
+ }
+
+ @Test
+ public void testFireStatement_WormFiring() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, PI, 1.5, "WormA", theTeam);
+ String code = "fire; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = {};
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(2,facade.getAllItems(theWorld).size());
+ score += 4;
+ }
+
+ @Test
+ public void testFireStatement_NotEnoughActionPoints() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 7.5, 5.5 }, 7 * PI / 12.0, 1.5, "WormA", theTeam);
+ String code = "fire; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ score += 4;
+ }
+
+ @Test
+ public void testIfStatement_NonBooleanCondition() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "if 3.0 print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ }
+ }
+
+ @Test
+ public void testIfStatement_ThenPartNonInterruptable() throws ModelException {
+ max_score += 6;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; if true { print 2.0; print 3.0; } print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 6;
+ }
+
+ @Test
+ public void testIfStatement_ElsePartNonInterruptable() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; if false print 5.0; else { print 2.0; print 3.0; } print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ }
+
+ @Test
+ public void testIfStatement_ThenPartInterruptable() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ String code = "print 1.0; if true { print 2.0; turn 1.5; print 3.0; } print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.5, facade.getOrientation(worm1), EPS);
+ score += 10;
+ }
+
+ @Test
+ public void testIfStatement_ConditionNotReEvaluated() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ String code = "v := true; print 1.0; if v { print 2.0; v := false; turn 1.5; print 3.0; } print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.5, facade.getOrientation(worm1), EPS);
+ score += 10;
+ }
+
+ @Test
+ public void testIfStatement_ElsePartInterruptable() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ String code = "v := false; print 1.0; if v print 22.0; { print 2.0; v := true; turn 1.5; print 3.0; } print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ assertEquals(1.5, facade.getOrientation(worm1), EPS);
+ score += 10;
+ }
+
+ @Test
+ public void testWhileStatement_NonBooleanCondition() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "while 3.0 print 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ }
+ }
+
+ @Test
+ public void testWhileStatement_ConditionTypeChanges() throws ModelException {
+ max_score += 8;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "v := true; while v v := null;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 8;
+ }
+ }
+
+ @Test
+ public void testWhileSatement_BodyNonInterruptable() throws ModelException {
+ max_score += 18;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; v := 1.0; while v < 8.5 { v := v + 1.0; print v; } print 10.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 18;
+ }
+
+ @Test
+ public void testWhileSatement_BodyInterruptable() throws ModelException {
+ max_score += 25;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; v := 0.0; while v < 0.45 { v := v + 0.1; print v; turn v; } print 1.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ // Finishing the first two iterations.
+ facade.decreaseNbActionPoints(worm1, -3);
+ results = facade.executeProgram(worm1);
+ assertNull(results);
+ // Finishing the next two iterations.
+ facade.decreaseNbActionPoints(worm1, -7);
+ results = facade.executeProgram(worm1);
+ assertNull(results);
+ // Finishing program execution.
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ List finalResults = facade.executeProgram(worm1);
+ double[] expecteds = { 1.0, 0.1, 0.2, 0.3, 0.4, 0.5, 1.0 };
+ IntStream.range(0, expecteds.length)
+ .forEach(i -> org.junit.Assert.assertEquals(expecteds[i], (Double) finalResults.get(i), EPS));
+ score += 25;
+ }
+
+ @Test
+ public void testBreakSatement_DirectlyInWhileBody() throws ModelException {
+ max_score += 14;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; v := 1.0; while true { v := v + 1.0; print v; if 4.5 < v break; } print 10.0;";
+ try {
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 3.0, 4.0, 5.0, 10.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 14;
+ } catch (MustNotImplementException exc) {
+ max_score -= 14;
+ }
+ }
+
+ @Test
+ public void testBreakSatement_IndirectlyInWhileBody() throws ModelException {
+ max_score += 20;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print 1.0; v := 1.0; while true { v := v + 1.0; { print v; if 4.5 < v break; print 0.0;} } print 10.0;";
+ try {
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 2.0, 0.0, 3.0, 0.0, 4.0, 0.0, 5.0, 10.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 20;
+ } catch (MustNotImplementException exc) {
+ max_score -= 20;
+ }
+ }
+
+ @Test
+ public void testBreakStatement_OutOfScope() throws ModelException {
+ max_score += 8;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "v := true; while v {print v; v := false; } break;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 8;
+ }
+ }
+
+ @Test
+ public void testBreakStatement_DirectlyInProcedure() throws ModelException {
+ max_score += 12;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: { print 10.0; break; print 15.0; } print 0.0; invoke p; print 20.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 0.0, 10.0, 20.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 12;
+ } catch (MustNotImplementException exc) {
+ max_score -= 12;
+ }
+ }
+
+ @Test
+ public void testBreakStatement_NestedBreaks() throws ModelException {
+ max_score += 20;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: { print 1.0; while true { print 2.0; break; } print 3.0; break; print 4.0;} def g: { print 10.0; invoke p; print 20.0; break; print 30.0; } print 0.0; invoke g; print 100.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 0.0, 10.0, 1.0, 2.0, 3.0, 20.0, 100.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 20;
+ } catch (MustNotImplementException exc) {
+ max_score -= 20;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_UndefinedProcedure() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "invoke p;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_SimpleProcedure() throws ModelException {
+ max_score += 6;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: print 4.0; print 1.0; invoke p; print 7.0; invoke p; print 10.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 4.0, 7.0, 4.0, 10.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 6;
+ } catch (MustNotImplementException exc) {
+ max_score -= 6;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_SeveralDefsOfProcedure() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: print 4.0; def p: print 8.0; print 1.0; invoke p; print 7.0; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0, 8.0, 7.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_ProcedureIntroduingGlobalVariable() throws ModelException {
+ max_score += 8;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: a := 10; invoke p; print a;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 10.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 8;
+ } catch (MustNotImplementException exc) {
+ max_score -= 8;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_ProcedureChangingGlobalVariable() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: a := a + 10.0; a := 3; invoke p; print a;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 13.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 10;
+ } catch (MustNotImplementException exc) {
+ max_score -= 10;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_ProcedureInvokingOtherProcedure() throws ModelException {
+ max_score += 10;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: print 1.0; def g: { print 2.0; invoke p; print 3.0; } invoke g; ";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 2.0, 1.0, 3.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 10;
+ } catch (MustNotImplementException exc) {
+ max_score -= 10;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_RecursiveProcedure() throws ModelException {
+ max_score += 35;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: { print a; if a < 5.5 { a := a + 1.0; invoke p; } } a := 0.0; invoke p; print a + 1.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 35;
+ } catch (MustNotImplementException exc) {
+ max_score -= 35;
+ }
+ }
+
+ @Test
+ public void testInvokeStatement_Interrupted() throws ModelException {
+ max_score += 25;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "def p: { print a; a := a + 5.0; jump; print a; } a := 10.0; invoke p; print a + 1.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ facade.decreaseNbActionPoints(worm1, facade.getNbActionPoints(worm1));
+ try {
+ List results = facade.executeProgram(worm1);
+ assertNull(results);
+ facade.decreaseNbActionPoints(worm1, -facade.getMaxNbActionPoints(worm1));
+ results = facade.executeProgram(worm1);
+ Object[] expecteds = { 10.0, 15.0, 16.0};
+ assertArrayEquals(expecteds, results.toArray());
+ score += 25;
+ } catch (MustNotImplementException exc) {
+ max_score -= 25;
+ }
+ }
+
+ // break statement
+ // nested break statements
+
+ // Assignment: assignment to variable with same name as procedure.
+
+ /*******************
+ * EXPRESSION TESTS
+ *******************/
+
+ @Test
+ public void testReadVariable_LegalCase() throws ModelException {
+ max_score += 10;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "v := 7.0; print v;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { 7.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 10;
+ }
+
+ @Test
+ public void testReadVariable_IllegalCase() throws ModelException {
+ max_score += 10;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print v;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ try {
+ facade.executeProgram(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 10;
+ }
+ }
+
+ @Test
+ public void testBooleanLiteral() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print true;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { true };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testNull() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print null;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { null };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testSelf() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print self;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { theWorm };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testAddition_LegalCase() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 2.0 + 4.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { 6.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testAddition_IllegalCase() throws ModelException {
+ max_score += 6;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 2.0 + self;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ try {
+ facade.executeProgram(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 6;
+ }
+ }
+
+ @Test
+ public void testConjunction_LegalCase() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print true && false;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testNegation_LegalCase() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print ! true;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testEquality_OperandsOfSameType() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 2.0 == 2.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { true };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testEquality_OperandsOfDifferentType() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print true == self;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testEquality_LeftOperandNull() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print null == self;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testInEquality_OperandsOfProperType() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 2.0 < 1.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testInEquality_IllegalCase() throws ModelException {
+ max_score += 2;
+ Worm theWorm = facade.createWorm(theWorld, new double[] { 7.5, 3.505 }, 3 * PI / 2.0, 1.5, "Worm", null);
+ String code = "print 2.0 < self;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ try {
+ facade.executeProgram(theWorm);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void testSearchObject_SingleObject() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", null);
+ Food foodToSearch = facade.createFood(theWorld, new double[] { 8.795, 7.5 });
+ String code = "print searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { foodToSearch };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ }
+
+ @Test
+ public void testSearchObject_SeveralCandidateObjects() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", null);
+ Worm wormToSearch = facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB",
+ null);
+ facade.createFood(theWorld, new double[] { 8.795, 7.5 });
+ String code = "print searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { wormToSearch };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 4;
+ }
+
+ @Test
+ public void testSearchObject_NoObject() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 3 * PI / 2.0, 1.5, "WormA", null);
+ facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", null);
+ String code = "print searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { null };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testSearchObject_ObjectBehindImpassableTerrain() {
+ max_score += 5;
+ map10x10 = new boolean[][] { { false, true, true, true, true, true, true, true, true, false },
+ { true, false, true, true, false, false, true, true, true, false },
+ { true, true, false, true, true, true, true, true, true, false },
+ { true, true, true, false, true, true, true, true, true, false },
+ { true, true, true, true, false, true, true, true, false, false },
+ { true, true, true, true, true, false, true, true, true, false },
+ { true, true, true, true, true, true, false, true, true, false },
+ { true, true, true, true, true, true, true, false, true, false },
+ { false, true, true, true, true, true, true, true, false, false },
+ { false, false, true, true, true, true, true, true, true, false }, };
+ World otherWorld = facade.createWorld(10.0, 10.0, map10x10);
+ Worm theWorm = facade.createWorm(otherWorld, new double[] { 2.0, 2.0 }, PI / 4.0, 1.0, "WormA", null);
+ Worm wormToSearch = facade.createWorm(otherWorld, new double[] { 8.0, 8.0 }, 0.0, 1.0, "WormB", null);
+ String code = "print searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(theWorm, program, actionHandler);
+ List results = facade.executeProgram(theWorm);
+ Object[] expecteds = { wormToSearch };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 5;
+ }
+
+ @Test
+ public void testSameTeam_TrueCase() throws ModelException {
+ max_score += 5;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", theTeam);
+ String code = "print sameteam searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { true };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 5;
+ } catch (MustNotImplementException exc) {
+ max_score -= 5;
+ }
+ }
+
+ @Test
+ public void testSameTeam_FalseCase() throws ModelException {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", null);
+ String code = "print sameteam searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void testSameTeam_NullCase() throws ModelException {
+ max_score += 3;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print sameteam null;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 3;
+ } catch (MustNotImplementException exc) {
+ max_score -= 3;
+ }
+ }
+
+ @Test
+ public void testSameTeam_IllegalCase() throws ModelException {
+ max_score += 4;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", null);
+ facade.createFood(theWorld, new double[] { 8.795, 7.5 });
+ String code = "print sameteam searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 4;
+ } catch (MustNotImplementException exc) {
+ max_score -= 4;
+ }
+ }
+
+ @Test
+ public void testDistance_LegalCase() throws ModelException {
+ max_score += 5;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", theTeam);
+ String code = "print distance searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { 1.0 };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 5;
+ }
+
+ @Test
+ public void testDistance_NullCase() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print distance null;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void testDistance_IllegalCase() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print distance 3.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ try {
+ facade.executeProgram(worm1);
+ fail();
+ } catch (ModelException exc) {
+ score += 2;
+ }
+ }
+
+ @Test
+ public void testIsWorm_TrueCase() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ facade.createWorm(theWorld, new double[] { 6.0, 7.5 }, FIXTURE_DIRECTION, 1.5, "WormB", null);
+ String code = "print isworm searchobj 0.0;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { true };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+ @Test
+ public void testIsWorm_FalseCase() throws ModelException {
+ max_score += 2;
+ Worm worm1 = facade.createWorm(theWorld, new double[] { 2.0, 7.5 }, 0.0, 1.5, "WormA", theTeam);
+ String code = "print isworm 3.14;";
+ Program program = ProgramParser.parseProgramFromString(code, programFactory);
+ facade.loadProgramOnWorm(worm1, program, actionHandler);
+ List results = facade.executeProgram(worm1);
+ Object[] expecteds = { false };
+ assertArrayEquals(expecteds, results.toArray());
+ score += 2;
+ }
+
+}
diff --git a/OGP1718-Worms/tests/worms/model/PartialPart2FacadeTest.java b/OGP1718-Worms/tests/worms/model/PartialPart2FacadeTest.java
old mode 100644
new mode 100755
diff --git a/OGP1718-Worms/tests/worms/model/SimpleActionHandler.java b/OGP1718-Worms/tests/worms/model/SimpleActionHandler.java
new file mode 100755
index 0000000..cb384af
--- /dev/null
+++ b/OGP1718-Worms/tests/worms/model/SimpleActionHandler.java
@@ -0,0 +1,95 @@
+package worms.model;
+
+import worms.facade.IFacade;
+import worms.internal.gui.GUIConstants;
+import worms.internal.gui.game.IActionHandler;
+import worms.util.ModelException;
+
+/**
+ * A simple action handler that just calls the necessary methods on the facade.
+ * Useful for writing tests; there's no other reason to use this.
+ */
+public class SimpleActionHandler implements IActionHandler {
+
+ private final IFacade facade;
+
+ public SimpleActionHandler(IFacade facade) {
+ this.facade = facade;
+ }
+
+ @Override
+ public boolean turn(Worm worm, double angle) {
+ try {
+ facade.turn(worm, angle);
+ return true;
+ } catch (ModelException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void print(String message) {
+ System.out.println(message);
+ }
+
+ @Override
+ public boolean move(Worm worm) {
+ try {
+ facade.move(worm);
+ if (facade.canFall(worm)) {
+ facade.fall(worm);
+ }
+ return true;
+ } catch (ModelException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean jump(Worm worm) {
+ try {
+ facade.jump(worm, GUIConstants.JUMP_TIME_STEP);
+ if (facade.canFall(worm)) {
+ facade.fall(worm);
+ }
+ return true;
+ } catch (ModelException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean fire(Worm worm) {
+ try {
+ facade.fire(worm);
+ return true;
+ } catch (ModelException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public boolean eat(Worm worm) {
+ try {
+ facade.eat(worm);
+ return true;
+ } catch (ModelException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+}
\ No newline at end of file