diff --git a/src/edu/kit/informatik/model/RailwayNetwork.java b/src/edu/kit/informatik/model/RailwayNetwork.java index 5f0dde2..f9ac268 100644 --- a/src/edu/kit/informatik/model/RailwayNetwork.java +++ b/src/edu/kit/informatik/model/RailwayNetwork.java @@ -47,18 +47,17 @@ public class RailwayNetwork { rails.put(1, newTrack); return newTrack.getIdentifier(); } else { - for (final Rail rail : rails.values()) { - if (rail.canConnectTo(start) || rail.canConnectTo(end)) { - final int id = getNextRailIdentifier(); - if (id < 0) { - return -1; - } - final Track newTrack = new Track(start, end, id); - rails.put(id, newTrack); - return newTrack.getIdentifier(); + if (rails.values().stream().anyMatch(rail -> rail.canConnectTo(start) || rail.canConnectTo(end))) { + final int id = getNextRailIdentifier(); + if (id < 0) { + return -1; } + final Track newTrack = new Track(start, end, id); + rails.put(id, newTrack); + return newTrack.getIdentifier(); + } else { + throw new InvalidInputException("track is not connected to other tracks"); } - throw new InvalidInputException("track is not connected to other tracks"); } } @@ -122,29 +121,20 @@ public class RailwayNetwork { if (toRemove == null) { return false; } - // locate one connected rail - Rail otherRail = null; - for (final Rail anotherRail : rails.values()) { - if (anotherRail.getIdentifier() != id && anotherRail.canConnectToRail(toRemove)) { - otherRail = anotherRail; - break; - } - } - - // last rail left, can always remove - if (otherRail == null) { - rails.clear(); + final Optional otherRail = rails.values().stream() + .filter(rail -> rail.getIdentifier() != toRemove.getIdentifier() && rail.canConnectToRail(toRemove)) + .findFirst(); + if (!otherRail.isPresent()) { + rails.clear(); // last rail left, can always remove return true; } - // check that rails would still be connected after removing this rail final Set connectedRails = new HashSet<>(); - connectedRails.add(otherRail); + connectedRails.add(otherRail.get()); final Queue toProcess = new LinkedList<>(); - toProcess.add(otherRail); - - // basically breadth-first search, using a queue + toProcess.add(otherRail.get()); + // basically breadth-first search (using a queue) while (!toProcess.isEmpty()) { final Rail connected = toProcess.poll(); @@ -155,13 +145,7 @@ public class RailwayNetwork { } } } - - if (connectedRails.size() == rails.size() - 1) { - rails.remove(id); - return true; - } else { - return false; - } + return connectedRails.size() == rails.size() - 1 && rails.remove(id) != null; } /** @@ -173,10 +157,7 @@ public class RailwayNetwork { */ public boolean setSwitch(int id, Vector2D position) { final Rail toSwitch = rails.get(id); - if (toSwitch != null) { - return toSwitch.switchTo(position); - } - return false; + return toSwitch != null && toSwitch.switchTo(position); } /** @@ -202,33 +183,31 @@ public class RailwayNetwork { * Move a position along the rails of this rail network in the specified direction. * * @param position the position to move - * @param direction has to be (0,1) (0,-1) (1,0) (-1,0), will be modified if turn is necessary + * @param direction has to be (0,1) (0,-1) (1,0) or (-1,0) * @param steps amount of steps to go * @return next position, null if off the rails after single step */ public Vector2D move(Vector2D position, Vector2D direction, long steps) { final Optional containingRail = findContainingRail(position); - if (containingRail.isPresent()) { + if (containingRail.isPresent()) { // if position is on a rail, simply move along that rail return containingRail.get().move(position, direction, steps); } final Rail[] touchingRails = findTouchingRails(position); if (touchingRails.length == 0) { - return null; - } else if (touchingRails.length == 1) { + return null; // there is no rail to move on + } else if (touchingRails.length == 1) { // simply move along the rail return touchingRails[0].move(position, direction, 1); - } + } // else: we check movement along both rails and pick the correct rail final Vector2D onRailOne = touchingRails[0].move(position, new Vector2D(direction), steps); final Vector2D onRailTwo = touchingRails[1].move(position, new Vector2D(direction), steps); + // if we are stuck on the first rail + // or derail on the first rail + // or move in the correct direction on the second rail if (position.equals(onRailOne) || onRailOne == null || onRailTwo != null && onRailTwo.subtract(position).directionEquals(direction)) { - // we are moving on rail two - final Vector2D newDirection = touchingRails[1].getDirectionFrom(position); - direction.copyFrom(newDirection); - return onRailTwo; + return onRailTwo; // return that position } else if (position.equals(onRailTwo) || onRailTwo == null || onRailOne.subtract(position).directionEquals(direction)) { - final Vector2D newDirection = touchingRails[0].getDirectionFrom(position); - direction.copyFrom(newDirection); return onRailOne; } else { // this case: https://ilias.studium.kit.edu/goto.php?client_id=produktiv&target=frm_996924_139074_534267 @@ -277,6 +256,16 @@ public class RailwayNetwork { return rails.values().stream().filter(rail -> rail.contains(position)).findFirst(); } + /** + * Find all rails that *touch* (not contain) this position. + * + * @param position the position to check + * @return the rail(s) that touch this position + */ + public Rail[] findTouchingRails(Vector2D position) { + return rails.values().stream().filter(rail -> rail.canConnectTo(position)).toArray(Rail[]::new); + } + /** * Find a rail that connects to or contains the first position and connects to or contains the second position. * @@ -291,16 +280,6 @@ public class RailwayNetwork { .findFirst(); } - /** - * Find all rails that *touch* (not contain) this position. - * - * @param position the position to check - * @return the rail(s) that touch this position - */ - public Rail[] findTouchingRails(Vector2D position) { - return rails.values().stream().filter(rail -> rail.canConnectTo(position)).toArray(Rail[]::new); - } - /** * Check whether the rail network is ready for trains (all switches set, etc.). * diff --git a/src/edu/kit/informatik/model/Track.java b/src/edu/kit/informatik/model/Track.java index 69749f5..6f48d8d 100644 --- a/src/edu/kit/informatik/model/Track.java +++ b/src/edu/kit/informatik/model/Track.java @@ -82,10 +82,8 @@ public final class Track extends Rail { } else if (direction.equals(getDirectionFrom(end))) { return new Vector2D(start); } else if (position.equals(end) && !direction.equals(getDirectionFrom(start))) { - direction.copyFrom(getDirectionFrom(end)); return move(position, getDirectionFrom(end), steps); } else if (position.equals(start) && !direction.equals(getDirectionFrom(end))) { - direction.copyFrom(getDirectionFrom(start)); return move(position, getDirectionFrom(start), steps); } return null; diff --git a/src/edu/kit/informatik/model/Train.java b/src/edu/kit/informatik/model/Train.java index 0f5f91b..a7e8e8b 100644 --- a/src/edu/kit/informatik/model/Train.java +++ b/src/edu/kit/informatik/model/Train.java @@ -136,6 +136,8 @@ public final class Train implements Comparable { // successfully placed part of the train length -= distanceToLastPosition; + // update direction + positioningDirection.copyFrom(rollingStockPosition.subtract(positionList.getLast()).normalized()); final Rail occupiedRail = railNetwork.findRail(positionList.getLast(), rollingStockPosition).get(); if (occupiedRailsSet.contains(occupiedRail) && positionList.size() > 4) {