From 25d7ba0dcefbff9646da395fc1947dfe50e61fe2 Mon Sep 17 00:00:00 2001 From: Arne Keller Date: Mon, 17 Feb 2020 20:39:30 +0100 Subject: [PATCH] Correctly handle long tracks and trains --- src/edu/kit/informatik/MainTest.java | 5 ++++ .../model/ModelRailwaySimulation.java | 5 +++- src/edu/kit/informatik/model/Track.java | 25 +++++++++++-------- src/edu/kit/informatik/model/Train.java | 17 ++++++++++--- src/edu/kit/informatik/model/Vector2D.java | 4 +-- src/edu/kit/informatik/ui/CommandLine.java | 19 +++----------- .../kit/informatik/ui/command/Command.java | 4 ++- .../kit/informatik/ui/command/PutTrain.java | 3 ++- 8 files changed, 46 insertions(+), 36 deletions(-) diff --git a/src/edu/kit/informatik/MainTest.java b/src/edu/kit/informatik/MainTest.java index 8c4a78a..54771b1 100644 --- a/src/edu/kit/informatik/MainTest.java +++ b/src/edu/kit/informatik/MainTest.java @@ -73,6 +73,11 @@ class MainTest { cmpInOut("fuzz8_input.txt", "fuzz8_output.txt"); } + @Test + void fuzz9() throws IOException { + cmpInOut("fuzz9_input.txt", "fuzz9_output.txt"); + } + @Test void fuzz10() throws IOException { cmpInOut("fuzz10_input.txt", "fuzz10_output.txt"); diff --git a/src/edu/kit/informatik/model/ModelRailwaySimulation.java b/src/edu/kit/informatik/model/ModelRailwaySimulation.java index 8ffc30e..ab8c4d9 100644 --- a/src/edu/kit/informatik/model/ModelRailwaySimulation.java +++ b/src/edu/kit/informatik/model/ModelRailwaySimulation.java @@ -2,6 +2,7 @@ package edu.kit.informatik.model; import edu.kit.informatik.ui.CoachType; import edu.kit.informatik.Terminal; +import edu.kit.informatik.ui.InvalidInputException; import java.util.ArrayList; import java.util.Arrays; @@ -365,8 +366,10 @@ public class ModelRailwaySimulation { * @param position where to place the train * @param direction direction in which the train should initially go * @return whether the train was successfully placed + * @throws InvalidInputException when the train is too long */ - public boolean putTrain(final int trainId, final Vector2D position, final Vector2D direction) { + public boolean putTrain(final int trainId, final Vector2D position, final Vector2D direction) + throws InvalidInputException { Train train = trains.get(trainId); if (train == null || !train.isProperTrain() || train.isPlaced()) { // can only place valid trains that are not already placed diff --git a/src/edu/kit/informatik/model/Track.java b/src/edu/kit/informatik/model/Track.java index 33d71f6..ae86f68 100644 --- a/src/edu/kit/informatik/model/Track.java +++ b/src/edu/kit/informatik/model/Track.java @@ -41,7 +41,7 @@ public final class Track extends Rail { @Override public boolean canConnectToRail(Rail rail) { if (rail == null) { - System.out.println("hey"); + System.out.println("hey"); // TODO: remove } return rail.canConnectTo(start) || rail.canConnectTo(end); } @@ -59,25 +59,28 @@ public final class Track extends Rail { @Override public boolean contains(Vector2D position) { if (start.getX() == end.getX() && position.getX() == start.getX()) { - int dy0 = Math.abs(start.getY() - end.getY()); - int dy1 = Math.abs(start.getY() - position.getY()); - int dy2 = Math.abs(end.getY() - position.getY()); - return dy1 > 0 && dy2 > 0 && dy1 < dy0 && dy2 < dy0; + int startY = start.getY(); + int endY = end.getY(); + int positionY = position.getY(); + return (startY < positionY && positionY < endY) || (startY > positionY && positionY > endY); } else if (start.getY() == end.getY() && position.getY() == start.getY()) { - int dx0 = Math.abs(start.getX() - end.getX()); - int dx1 = Math.abs(start.getX() - position.getX()); - int dx2 = Math.abs(end.getX() - position.getX()); - return dx1 > 0 && dx2 > 0 && dx1 < dx0 && dx2 < dx0; + int startX = start.getX(); + int endX = end.getX(); + int positionX = position.getX(); + return (startX < positionX && positionX < endX) || (startX > positionX && positionX > endX); } return false; } @Override public Vector2D getDirectionFrom(Vector2D position) { + // have to use long arithmetic here to avoid overflows if (start.equals(position)) { - return new Vector2D(end.getX() - start.getX(), end.getY() - start.getY()).normalized(); + return new Vector2D(Long.signum((long) end.getX() - (long) start.getX()), + Long.signum((long) end.getY() - (long) start.getY())); } else if (end.equals(position)) { - return new Vector2D(start.getX() - end.getX(), start.getY() - end.getY()).normalized(); + return new Vector2D(Long.signum((long) start.getX() - (long) end.getX()), + Long.signum((long) start.getY() - (long) end.getY())); } else { throw new IllegalArgumentException(); } diff --git a/src/edu/kit/informatik/model/Train.java b/src/edu/kit/informatik/model/Train.java index 43518fc..6e7a837 100644 --- a/src/edu/kit/informatik/model/Train.java +++ b/src/edu/kit/informatik/model/Train.java @@ -1,6 +1,7 @@ package edu.kit.informatik.model; import edu.kit.informatik.Terminal; +import edu.kit.informatik.ui.InvalidInputException; import java.util.ArrayList; import java.util.HashSet; @@ -136,10 +137,16 @@ public final class Train { * @param position where to place the train * @param rawDirection direction in which the train should initially go * @return whether the train was successfully placed + * @throws InvalidInputException when the train is too long to place */ - public boolean placeOn(final RailwayNetwork railNetwork, final Vector2D position, final Vector2D rawDirection) { + public boolean placeOn(final RailwayNetwork railNetwork, final Vector2D position, final Vector2D rawDirection) + throws InvalidInputException { Vector2D direction = rawDirection.normalized(); - int length = getLength(); + long length = getLength(); + if (length > Integer.MAX_VALUE) { + // we can not create a position list this long! TODO: await forum answer + throw new InvalidInputException("train length is bigger than 32-bit integer!"); + } LinkedList positions = new LinkedList<>(); positions.add(position); @@ -148,6 +155,8 @@ public final class Train { if (length > 10000) { return false; // TODO: remove! } + // TODO check that the requested direction is equal to the direction of one the tracks + // consider fuzz 9 (0,-1) for (int i = 1; i <= length; i++) { rollingStockPosition = railNetwork.move(rollingStockPosition, positioningDirection); if (rollingStockPosition == null @@ -375,7 +384,7 @@ public final class Train { * Calculate the length of this train, summing the length of all rolling stocks. * @return total length of this train */ - public int getLength() { - return rollingStocks.stream().mapToInt((RollingStock::getLength)).sum(); + public long getLength() { + return rollingStocks.stream().mapToLong((RollingStock::getLength)).sum(); } } diff --git a/src/edu/kit/informatik/model/Vector2D.java b/src/edu/kit/informatik/model/Vector2D.java index 6b7b6f6..8f03497 100644 --- a/src/edu/kit/informatik/model/Vector2D.java +++ b/src/edu/kit/informatik/model/Vector2D.java @@ -58,8 +58,8 @@ public class Vector2D { * @param other the point to measure distance to * @return the manhattan distance */ - public int distanceTo(final Vector2D other) { - return Math.abs(this.x - other.x) + Math.abs(this.y - other.y); + public long distanceTo(final Vector2D other) { + return Math.abs((long) this.x - (long) other.x) + Math.abs((long) this.y - (long) other.y); } /** diff --git a/src/edu/kit/informatik/ui/CommandLine.java b/src/edu/kit/informatik/ui/CommandLine.java index 1f191c8..4564c5a 100644 --- a/src/edu/kit/informatik/ui/CommandLine.java +++ b/src/edu/kit/informatik/ui/CommandLine.java @@ -37,25 +37,12 @@ public class CommandLine { break; } - final Command command; try { - command = CommandFactory.getCommand(input); - } catch (NumberFormatException e) { - Terminal.printError("number too big"); - continue; - } catch (InvalidInputException e) { + Command command = CommandFactory.getCommand(input); + command.apply(simulation); + } catch (NumberFormatException | InvalidInputException e) { Terminal.printError(e.getMessage()); - continue; } - if (command != null) { - try { - command.apply(simulation); - } catch (NumberFormatException e) { - Terminal.printError("number too big"); - // this can happen when trying to add W2147483649 to a train or similar - } - } - // else: error message already printed in parse function } } } diff --git a/src/edu/kit/informatik/ui/command/Command.java b/src/edu/kit/informatik/ui/command/Command.java index a9112ac..4559680 100644 --- a/src/edu/kit/informatik/ui/command/Command.java +++ b/src/edu/kit/informatik/ui/command/Command.java @@ -1,6 +1,7 @@ package edu.kit.informatik.ui.command; import edu.kit.informatik.model.ModelRailwaySimulation; +import edu.kit.informatik.ui.InvalidInputException; /** * Command that can be applied to a simulation. @@ -13,6 +14,7 @@ public abstract class Command { /** * Apply this command to a model railway simulation. * @param simulation simulation to use + * @throws InvalidInputException on invalid user input */ - public abstract void apply(ModelRailwaySimulation simulation); + public abstract void apply(ModelRailwaySimulation simulation) throws InvalidInputException; } diff --git a/src/edu/kit/informatik/ui/command/PutTrain.java b/src/edu/kit/informatik/ui/command/PutTrain.java index bfad67d..085d455 100644 --- a/src/edu/kit/informatik/ui/command/PutTrain.java +++ b/src/edu/kit/informatik/ui/command/PutTrain.java @@ -3,6 +3,7 @@ package edu.kit.informatik.ui.command; import edu.kit.informatik.model.ModelRailwaySimulation; import edu.kit.informatik.model.Vector2D; import edu.kit.informatik.Terminal; +import edu.kit.informatik.ui.InvalidInputException; /** * Command used to put a train on the rail network. @@ -31,7 +32,7 @@ public class PutTrain extends Command { } @Override - public void apply(final ModelRailwaySimulation simulation) { + public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { if (simulation.putTrain(id, point, new Vector2D(x, y))) { Terminal.printLine("OK"); } else {