From e41badefd971e86b6afeb4979dd839d221a2a509 Mon Sep 17 00:00:00 2001 From: Arne Keller Date: Mon, 17 Feb 2020 14:11:55 +0100 Subject: [PATCH] Use a map for storing trains --- .../model/ModelRailwaySimulation.java | 98 ++++++++----------- 1 file changed, 42 insertions(+), 56 deletions(-) diff --git a/src/edu/kit/informatik/model/ModelRailwaySimulation.java b/src/edu/kit/informatik/model/ModelRailwaySimulation.java index 617d493..8ffc30e 100644 --- a/src/edu/kit/informatik/model/ModelRailwaySimulation.java +++ b/src/edu/kit/informatik/model/ModelRailwaySimulation.java @@ -39,7 +39,7 @@ public class ModelRailwaySimulation { /** * List of trains simulated. */ - private final List trains = new ArrayList<>(); + private final Map trains = new HashMap<>(); /** * Add a new track to the rail network of this simulation. @@ -69,7 +69,7 @@ public class ModelRailwaySimulation { */ public boolean removeRail(final int id) { // check whether any trains are on this rail - if (trains.stream().anyMatch(train -> train.isPlaced() && train.isOnRail(id))) { + if (trains.values().stream().anyMatch(train -> train.isPlaced() && train.isOnRail(id))) { return false; } return railNetwork.removeRail(id); @@ -123,7 +123,7 @@ public class ModelRailwaySimulation { } else { engines.sort(Comparator.comparing(Engine::getIdentifier)); engine: for (Engine engine : engines) { - for (Train train : trains) { + for (Train train : trains.values()) { int id = train.getIdentifier(); if (train.contains(engine)) { Terminal.printLine(String.format("%s %s", id, engine)); @@ -176,7 +176,7 @@ public class ModelRailwaySimulation { Terminal.printLine("No coach exists"); } else { coach: for (Coach coach : coaches) { - for (Train train : trains) { + for (Train train : trains.values()) { if (train.contains(coach)) { Terminal.printLine(String.format("%d %s %s %d %b %b", coach.getNumericalIdentifier(), train.getIdentifier(), coach.getType(), @@ -220,7 +220,7 @@ public class ModelRailwaySimulation { } else { trainSets.sort(Comparator.comparing(TrainSet::getIdentifier)); trainset: for (TrainSet trainSet : trainSets) { - for (Train train : trains) { + for (Train train : trains.values()) { if (train.contains(trainSet)) { Terminal.printLine(String.format("%s %s", train.getIdentifier(), trainSet)); continue trainset; @@ -238,7 +238,7 @@ public class ModelRailwaySimulation { */ public boolean deleteRollingStock(final String id) { RollingStock rollingStock = getRollingStock(id); - if (rollingStock == null || trains.stream().anyMatch(train -> train.contains(rollingStock))) { + if (rollingStock == null || trains.values().stream().anyMatch(train -> train.contains(rollingStock))) { // can not delete rolling stock in use return false; } @@ -287,12 +287,12 @@ public class ModelRailwaySimulation { if (rollingStock == null) { return false; } - for (Train train : trains) { + for (Train train : trains.values()) { if (train.contains(rollingStock)) { return false; } } - Train train = getTrain(trainId); + Train train = trains.get(trainId); if (train != null && train.isPlaced()) { return false; } @@ -304,7 +304,7 @@ public class ModelRailwaySimulation { return false; } Train newTrain = new Train(trainId, rollingStock); - trains.add(newTrain); + trains.put(trainId, newTrain); return true; } @@ -313,13 +313,12 @@ public class ModelRailwaySimulation { * @return the next train identfier, or -1 if none available */ private int getNextTrainIdentifier() { - int id = 1; - for (Train train : trains) { - if (train.getIdentifier() == id) { - id++; + for (int id = 1; id > 0; id++) { + if (!trains.containsKey(id)) { + return id; } } - return id; + return -1; } /** @@ -328,23 +327,14 @@ public class ModelRailwaySimulation { * @return whether the train could be deleted */ public boolean deleteTrain(int id) { - Train train = getTrain(id); + Train train = trains.get(id); if (train != null) { - trains.remove(train); + trains.remove(train.getIdentifier()); return true; } return false; } - /** - * Find a train by identifier. - * @param id identifier of the train to find. - * @return the specified train, or null if not found - */ - private Train getTrain(int id) { - return trains.stream().filter((train) -> train.getIdentifier() == id).findFirst().orElse(null); - } - /** * Print a list of trains in the simulation. */ @@ -353,7 +343,7 @@ public class ModelRailwaySimulation { Terminal.printLine("No train exists"); // TODO not in fucking spec return; } - trains.forEach(Terminal::printLine); + trains.values().forEach(Terminal::printLine); } /** @@ -361,7 +351,7 @@ public class ModelRailwaySimulation { * @param id identifier of the train to show */ public void printTrain(int id) { - Train train = getTrain(id); + Train train = trains.get(id); if (train != null) { train.print(); } else { @@ -377,7 +367,7 @@ public class ModelRailwaySimulation { * @return whether the train was successfully placed */ public boolean putTrain(final int trainId, final Vector2D position, final Vector2D direction) { - Train train = getTrain(trainId); + Train train = trains.get(trainId); if (train == null || !train.isProperTrain() || train.isPlaced()) { // can only place valid trains that are not already placed return false; @@ -410,15 +400,15 @@ public class ModelRailwaySimulation { return new ArrayList<>(); } ArrayList> collisions = new ArrayList<>(); - int maxId = trains.get(trains.size() - 1).getIdentifier(); + int maxId = trains.keySet().stream().max(Integer::compareTo).get(); train: for (int id1 = 1; id1 <= maxId; id1++) { - Train train1 = getTrain(id1); + Train train1 = trains.get(id1); if (train1 == null || !train1.isPlaced()) { continue; } HashSet collision = new HashSet<>(); for (int id2 = id1 + 1; id2 <= maxId; id2++) { - Train train2 = getTrain(id2); + Train train2 = trains.get(id2); if (train2 == null || !train2.isPlaced()) { continue; } @@ -450,17 +440,14 @@ public class ModelRailwaySimulation { private ArrayList> getCollisionsOfOneStep() { ArrayList> collisions = new ArrayList<>(); Map> occupiedRails = new HashMap<>(); - for (Train train : trains) { + for (Train train : trains.values()) { if (train.isPlaced()) { occupiedRails.put(train, train.getOccupiedRails()); } } // perform step Map> nextOccupiedRails = new HashMap<>(); - for (Train train : trains) { - if (!train.isPlaced()) { - continue; - } + trains.values().stream().filter(Train::isPlaced).forEach(train -> { Vector2D position = train.getFrontPosition(); Vector2D direction = train.getDirection(); Vector2D nextPosition = railNetwork.move(position, direction); @@ -470,19 +457,16 @@ public class ModelRailwaySimulation { collisions.add(new HashSet<>(Arrays.asList(train))); train.removeFromRails(); nextOccupiedRails.put(train, occupiedRails.get(train)); - continue; + } else { + train.moveTo(railNetwork, nextPosition); + train.setDirection(direction); + nextOccupiedRails.put(train, train.getOccupiedRails()); } - train.moveTo(railNetwork, nextPosition); - train.setDirection(direction); - nextOccupiedRails.put(train, train.getOccupiedRails()); - } + }); // check for block collisions - for (Train train : trains) { - if (!train.isPlaced() || collisions.stream().anyMatch((x) -> x.contains(train))) { - continue; // already included in collision - } + trains.values().stream().filter(train -> train.isPlaced() && collisions.stream().noneMatch((x) -> x.contains(train))).forEach(train -> { Set occupiedByThisTrain = nextOccupiedRails.get(train); - trains.stream().filter((x) -> x != train).forEach((otherTrain) -> { + trains.values().stream().filter((x) -> x != train).forEach((otherTrain) -> { Set occupiedByOtherTrainPreviously = occupiedRails.get(otherTrain); Set occupiedByOtherTrain = nextOccupiedRails.get(otherTrain); if (occupiedByOtherTrain == null || occupiedByOtherTrainPreviously == null) { @@ -509,7 +493,7 @@ public class ModelRailwaySimulation { } } }); - } + }); return collisions; } @@ -520,14 +504,14 @@ public class ModelRailwaySimulation { private ArrayList> getCollisionsOfOneReverseStep() { ArrayList> collisions = new ArrayList<>(); Map> occupiedRails = new HashMap<>(); - for (Train train : trains) { + for (Train train : trains.values()) { if (train.isPlaced()) { occupiedRails.put(train, train.getOccupiedRails()); } } // perform step Map> nextOccupiedRails = new HashMap<>(); - for (Train train : trains) { + for (Train train : trains.values()) { if (!train.isPlaced()) { continue; } @@ -547,12 +531,12 @@ public class ModelRailwaySimulation { nextOccupiedRails.put(train, train.getOccupiedRails()); } // check for block collisions - for (Train train : trains) { + for (Train train : trains.values()) { if (!train.isPlaced() || collisions.stream().anyMatch((x) -> x.contains(train))) { continue; // already included in collision } Set occupiedByThisTrain = nextOccupiedRails.get(train); - trains.stream().filter((x) -> x != train).forEach((otherTrain) -> { + trains.values().stream().filter((x) -> x != train).forEach((otherTrain) -> { Set occupiedByOtherTrainPreviously = occupiedRails.get(otherTrain); Set occupiedByOtherTrain = nextOccupiedRails.get(otherTrain); if (occupiedByOtherTrain == null || occupiedByOtherTrainPreviously == null) { @@ -589,7 +573,7 @@ public class ModelRailwaySimulation { Terminal.printError("rail tracks/switches not set up"); return; } - if (trains.stream().noneMatch(Train::isPlaced)) { + if (trains.values().stream().noneMatch(Train::isPlaced)) { Terminal.printLine("OK"); return; } @@ -606,15 +590,17 @@ public class ModelRailwaySimulation { collisions.addAll(newCollisions); } // (only one of the loops above actually runs) - train: for (Train train : trains) { + train: for (int id : trains.keySet().stream().sorted().collect(Collectors.toList())) { + Train train = trains.get(id); // print collision for (Set collisionSet : collisions) { if (!collisionSet.contains(train)) { continue; } - List collision = collisionSet.stream().sorted(Comparator.comparing(Train::getIdentifier)) - .collect(Collectors.toList()); - if (collision.indexOf(train) == 0) { + int first = collisionSet.stream().min(Comparator.comparing(Train::getIdentifier)).get().getIdentifier(); + if (train.getIdentifier() == first) { // only print each collision once + List collision = collisionSet.stream().sorted(Comparator.comparing(Train::getIdentifier)) + .collect(Collectors.toList()); Terminal.printLine("Crash of train " + String.join(",", collision.stream().map( (x) -> Integer.toString(x.getIdentifier())).toArray(String[]::new)));