Checkstyle and SonarQube

This commit is contained in:
Arne Keller 2020-02-19 23:54:33 +01:00
parent c40e635cb8
commit aa8f43b251
6 changed files with 79 additions and 99 deletions

View File

@ -14,6 +14,7 @@ add train 1 W3
show train 1 show train 1
put train 1 at (0,0) in direction 1,0 put train 1 at (0,0) in direction 1,0
step 64 step 64
step -64
delete track 1 delete track 1
delete track 2 delete track 2
delete track 3 delete track 3

View File

@ -18,6 +18,7 @@ passenger coach W3 added to train 1
(O)(O) (O)(O) (O) (O) (O) (O) (O) (O) (O)(O) (O)(O) (O) (O) (O) (O) (O) (O)
OK OK
Train 1 at (0,0) Train 1 at (0,0)
Train 1 at (0,0)
Error, could not delete rail segment Error, could not delete rail segment
Error, could not delete rail segment Error, could not delete rail segment
Error, could not delete rail segment Error, could not delete rail segment

View File

@ -13,6 +13,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* Model railway simulation. Can simulate trains on a railway network. * Model railway simulation. Can simulate trains on a railway network.
@ -109,12 +110,12 @@ public class ModelRailwaySimulation {
String id = newEngine.getIdentifier(); String id = newEngine.getIdentifier();
for (Engine engine : engines) { for (Engine engine : engines) {
if (engine.getIdentifier().equals(id)) { if (engine.getIdentifier().equals(id)) {
throw new InvalidInputException("identifier already used"); throw new InvalidInputException("engine identifier already used by engine");
} }
} }
for (TrainSet trainSet : trainSets) { for (TrainSet trainSet : trainSets) {
if (trainSet.getIdentifier().equals(id)) { if (trainSet.getIdentifier().equals(id)) {
throw new InvalidInputException("identifier already used"); throw new InvalidInputException("engine identifier already used by train set");
} }
} }
engines.add(newEngine); engines.add(newEngine);
@ -128,15 +129,13 @@ public class ModelRailwaySimulation {
Terminal.printLine("No engine exists"); Terminal.printLine("No engine exists");
} else { } else {
engines.sort(Comparator.comparing(Engine::getIdentifier)); engines.sort(Comparator.comparing(Engine::getIdentifier));
engine: for (Engine engine : engines) { for (Engine engine : engines) {
for (Train train : trains.values()) { Train train = trains.values().stream().filter(x -> x.contains(engine)).findFirst().orElse(null);
int id = train.getIdentifier(); if (train != null) {
if (train.contains(engine)) { Terminal.printLine(String.format("%s %s", train.getIdentifier(), engine));
Terminal.printLine(String.format("%s %s", id, engine)); } else {
continue engine; Terminal.printLine(String.format("none %s", engine));
}
} }
Terminal.printLine(String.format("none %s", engine));
} }
} }
} }
@ -192,18 +191,17 @@ public class ModelRailwaySimulation {
if (coaches.isEmpty()) { if (coaches.isEmpty()) {
Terminal.printLine("No coach exists"); Terminal.printLine("No coach exists");
} else { } else {
coach: for (Integer identifier : coaches.keySet().stream().sorted().collect(Collectors.toList())) { for (Integer identifier : coaches.keySet().stream().sorted().collect(Collectors.toList())) {
Coach coach = coaches.get(identifier); Coach coach = coaches.get(identifier);
for (Train train : trains.values()) { Train train = trains.values().stream().filter(x -> x.contains(coach)).findFirst().orElse(null);
if (train.contains(coach)) { if (train != null) {
Terminal.printLine(String.format("%d %s %s %d %b %b", Terminal.printLine(String.format("%d %s %s %d %b %b",
coach.getNumericalIdentifier(), train.getIdentifier(), coach.getType(), coach.getNumericalIdentifier(), train.getIdentifier(), coach.getType(),
coach.getLength(), coach.hasCouplingFront(), coach.hasCouplingBack())); coach.getLength(), coach.hasCouplingFront(), coach.hasCouplingBack()));
continue coach; } else {
} Terminal.printLine(String.format("%d none %s %d %b %b", coach.getNumericalIdentifier(),
coach.getType(), coach.getLength(), coach.hasCouplingFront(), coach.hasCouplingBack()));
} }
Terminal.printLine(String.format("%d none %s %d %b %b", coach.getNumericalIdentifier(), coach.getType(),
coach.getLength(), coach.hasCouplingFront(), coach.hasCouplingBack()));
} }
} }
} }
@ -217,12 +215,12 @@ public class ModelRailwaySimulation {
String id = newTrainSet.getIdentifier(); String id = newTrainSet.getIdentifier();
for (Engine engine : engines) { for (Engine engine : engines) {
if (engine.getIdentifier().equals(id)) { if (engine.getIdentifier().equals(id)) {
throw new InvalidInputException("identifier already used"); throw new InvalidInputException("train set identifier already used by engine");
} }
} }
for (TrainSet trainSet : trainSets) { for (TrainSet trainSet : trainSets) {
if (trainSet.getIdentifier().equals(id)) { if (trainSet.getIdentifier().equals(id)) {
throw new InvalidInputException("identifier already used"); throw new InvalidInputException("train set identifier already used by train set");
} }
} }
trainSets.add(newTrainSet); trainSets.add(newTrainSet);
@ -236,14 +234,13 @@ public class ModelRailwaySimulation {
Terminal.printLine("No train-set exists"); Terminal.printLine("No train-set exists");
} else { } else {
trainSets.sort(Comparator.comparing(TrainSet::getIdentifier)); trainSets.sort(Comparator.comparing(TrainSet::getIdentifier));
trainset: for (TrainSet trainSet : trainSets) { for (TrainSet trainSet : trainSets) {
for (Train train : trains.values()) { Train train = trains.values().stream().filter(x -> x.contains(trainSet)).findFirst().orElse(null);
if (train.contains(trainSet)) { if (train != null) {
Terminal.printLine(String.format("%s %s", train.getIdentifier(), trainSet)); Terminal.printLine(String.format("%s %s", train.getIdentifier(), trainSet));
continue trainset; } else {
} Terminal.printLine(String.format("none %s", trainSet));
} }
Terminal.printLine(String.format("none %s", trainSet));
} }
} }
} }
@ -273,24 +270,12 @@ public class ModelRailwaySimulation {
public RollingStock getRollingStock(final String id) { public RollingStock getRollingStock(final String id) {
if (id.matches("W\\+?\\d+")) { if (id.matches("W\\+?\\d+")) {
int coachId = Integer.parseInt(id.substring(1)); int coachId = Integer.parseInt(id.substring(1));
for (Coach coach : coaches.values()) { return coaches.get(coachId);
if (coach.getNumericalIdentifier() == coachId) {
return coach;
}
}
} else { } else {
for (Engine engine : engines) { return Stream.concat(engines.stream(), trainSets.stream())
if (engine.getIdentifier().equals(id)) { .filter(rollingStock -> rollingStock.getIdentifier().equals(id))
return engine; .findFirst().orElse(null);
}
}
for (TrainSet trainSet : trainSets) {
if (trainSet.getIdentifier().equals(id)) {
return trainSet;
}
}
} }
return null;
} }
/** /**
@ -416,7 +401,7 @@ public class ModelRailwaySimulation {
private List<HashSet<Train>> getStaticCollisions() { private List<HashSet<Train>> getStaticCollisions() {
List<HashSet<Train>> collisions = new ArrayList<>(); List<HashSet<Train>> collisions = new ArrayList<>();
int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0); int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0);
train: for (int id1 = 1; id1 <= maxId; id1++) { for (int id1 = 1; id1 <= maxId; id1++) {
Train train1 = trains.get(id1); Train train1 = trains.get(id1);
if (train1 == null || !train1.isPlaced()) { if (train1 == null || !train1.isPlaced()) {
continue; continue;
@ -434,15 +419,16 @@ public class ModelRailwaySimulation {
} }
if (!collision.isEmpty()) { if (!collision.isEmpty()) {
// check for existing collision // check for existing collision
for (HashSet<Train> otherCollision : collisions) { Set<Train> otherCollision = collisions.stream()
if (otherCollision.stream().anyMatch(collision::contains)) { .filter(x -> x.stream().anyMatch(collision::contains))
otherCollision.addAll(collision); .findFirst().orElse(null);
continue train; if (otherCollision != null) { // add to that collision
} otherCollision.add(train1);
otherCollision.addAll(collision);
} else { // create a new collision
collision.add(train1);
collisions.add(collision);
} }
// else, create a new collision
collision.add(train1);
collisions.add(collision);
} }
} }
return collisions; return collisions;
@ -532,25 +518,22 @@ public class ModelRailwaySimulation {
} }
// perform step // perform step
Map<Train, Set<Rail>> nextOccupiedRails = new HashMap<>(); Map<Train, Set<Rail>> nextOccupiedRails = new HashMap<>();
for (Train train : trains.values()) { trains.values().stream().filter(Train::isPlaced).forEach(train -> {
if (!train.isPlaced()) {
continue;
}
Vector2D front = train.getFrontPosition(); Vector2D front = train.getFrontPosition();
Vector2D position = train.getRearPosition(); Vector2D position = train.getRearPosition();
Vector2D direction = train.getRearDirection(); Vector2D direction = train.getRearDirection();
Vector2D nextPosition = railNetwork.move(position, direction); Vector2D nextPosition = railNetwork.move(position, direction);
if (nextPosition == null if (nextPosition == null
|| train.isOnPosition(nextPosition) && !train.getFrontPosition().equals(nextPosition)) { || train.isOnPosition(nextPosition) && !train.getRearPosition().equals(train.getFrontPosition())) {
collisions.add(new HashSet<>(Arrays.asList(train))); collisions.add(new HashSet<>(Arrays.asList(train)));
train.removeFromRails(); train.removeFromRails();
nextOccupiedRails.put(train, occupiedRails.get(train)); nextOccupiedRails.put(train, occupiedRails.get(train));
continue; } else {
train.moveBackTo(railNetwork, nextPosition);
train.setDirection(front.subtract(train.getFrontPosition()));
nextOccupiedRails.put(train, train.getOccupiedRails());
} }
train.moveBackTo(railNetwork, nextPosition); });
train.setDirection(front.subtract(train.getFrontPosition()));
nextOccupiedRails.put(train, train.getOccupiedRails());
}
// check for block collisions // check for block collisions
for (Train train : trains.values()) { for (Train train : trains.values()) {
if (!train.isPlaced() || collisions.stream().anyMatch(x -> x.contains(train))) { if (!train.isPlaced() || collisions.stream().anyMatch(x -> x.contains(train))) {
@ -610,26 +593,22 @@ public class ModelRailwaySimulation {
List<Set<Train>> newCollisions = getCollisionsOfOneReverseStep(); List<Set<Train>> newCollisions = getCollisionsOfOneReverseStep();
collisions.addAll(newCollisions); collisions.addAll(newCollisions);
} }
// (only one of the loops above actually runs) // TODO (only one of the loops above actually runs)
train: for (int id : trains.keySet().stream().sorted().collect(Collectors.toList())) { for (int id : trains.keySet().stream().sorted().collect(Collectors.toList())) {
Train train = trains.get(id); Train train = trains.get(id);
// print collision Set<Train> collisionSet = collisions.stream()
for (Set<Train> collisionSet : collisions) { .filter(collision -> collision.contains(train))
if (!collisionSet.contains(train)) { .findFirst().orElse(null);
continue; if (collisionSet != null) { // print collision
}
int first = collisionSet.stream().min(Comparator.comparing(Train::getIdentifier)).get().getIdentifier(); int first = collisionSet.stream().min(Comparator.comparing(Train::getIdentifier)).get().getIdentifier();
if (train.getIdentifier() == first) { // only print each collision once if (train.getIdentifier() == first) { // only print each collision once
List<Train> collision = collisionSet.stream().sorted(Comparator.comparing(Train::getIdentifier)) List<Train> collision = collisionSet.stream().sorted(Comparator.comparing(Train::getIdentifier))
.collect(Collectors.toList()); .collect(Collectors.toList());
Terminal.printLine("Crash of train " + String.join(",", Terminal.printLine("Crash of train " + String.join(",", collision.stream()
collision.stream().map( .map(crashedTrain -> Integer.toString(crashedTrain.getIdentifier()))
x -> Integer.toString(x.getIdentifier())).toArray(String[]::new))); .toArray(String[]::new)));
} }
continue train; } else if (train.isPlaced()) { // or position, if not in collision
}
// or position, if not in collision
if (train.isPlaced()) {
Terminal.printLine(String.format("Train %d at %s", train.getIdentifier(), train.getFrontPosition())); Terminal.printLine(String.format("Train %d at %s", train.getIdentifier(), train.getFrontPosition()));
} }
} }

View File

@ -82,18 +82,18 @@ public class RailwayNetwork {
if (startPossibleConnections == 2 || end1PossibleConnections == 2 || end2PossibleConnections == 2) { if (startPossibleConnections == 2 || end1PossibleConnections == 2 || end2PossibleConnections == 2) {
throw new InvalidInputException("switch endpoint would connect to two other rails"); throw new InvalidInputException("switch endpoint would connect to two other rails");
} }
for (Rail rail : rails.values()) { if (rails.values().stream()
if (rail.canConnectTo(start) || rail.canConnectTo(end1) || rail.canConnectTo(end2)) { .anyMatch(rail -> rail.canConnectTo(start) || rail.canConnectTo(end1) || rail.canConnectTo(end2))) {
int id = getNextRailIdentifier(); int id = getNextRailIdentifier();
if (id < 0) { if (id < 0) {
return -1; return -1;
}
Switch newSwitch = new Switch(start, end1, end2, id);
rails.put(id, newSwitch);
return newSwitch.getIdentifier();
} }
Switch newSwitch = new Switch(start, end1, end2, id);
rails.put(id, newSwitch);
return newSwitch.getIdentifier();
} else {
throw new InvalidInputException("switch not connected to other rails");
} }
throw new InvalidInputException("switch not connected to other rails");
} }
} }
@ -103,16 +103,12 @@ public class RailwayNetwork {
* @return whether the rail could be successfully removed * @return whether the rail could be successfully removed
*/ */
public boolean removeRail(final int id) { public boolean removeRail(final int id) {
if (rails.isEmpty()) {
return false;
}
Rail toRemove = rails.get(id); Rail toRemove = rails.get(id);
if (toRemove == null) { if (toRemove == null) {
return false; return false;
} }
Set<Rail> connectedRails = new HashSet<>();
// locate one other rail: TODO use rail.connectedrails // locate one other rail: TODO use rail.connectedrails?
Rail otherRail = null; Rail otherRail = null;
for (Rail anotherRail : rails.values()) { for (Rail anotherRail : rails.values()) {
if (anotherRail.getIdentifier() != id && anotherRail.canConnectToRail(toRemove)) { if (anotherRail.getIdentifier() != id && anotherRail.canConnectToRail(toRemove)) {
@ -121,15 +117,19 @@ public class RailwayNetwork {
} }
} }
// last rail left, can always remove
if (otherRail == null) { if (otherRail == null) {
rails.clear(); rails.clear();
return true; return true;
} }
// check that rails would still be connected after removing this rail
Set<Rail> connectedRails = new HashSet<>();
connectedRails.add(otherRail); connectedRails.add(otherRail);
Queue<Rail> toProcess = new LinkedList<>(); Queue<Rail> toProcess = new LinkedList<>();
toProcess.add(otherRail); toProcess.add(otherRail);
// basically breadth-first search, using a queue
while (!toProcess.isEmpty()) { while (!toProcess.isEmpty()) {
Rail connected = toProcess.poll(); Rail connected = toProcess.poll();

View File

@ -15,9 +15,8 @@ public abstract class Command {
* Apply this command to a model railway simulation. * Apply this command to a model railway simulation.
* @param simulation simulation to use * @param simulation simulation to use
* @throws InvalidInputException on invalid user input * @throws InvalidInputException on invalid user input
* @throws IllegalStateException if the command is not yet initialized
*/ */
public abstract void apply(ModelRailwaySimulation simulation) throws InvalidInputException, IllegalStateException; public abstract void apply(ModelRailwaySimulation simulation) throws InvalidInputException;
/** /**
* Parse user input into this command object. * Parse user input into this command object.

View File

@ -38,11 +38,11 @@ OK
2 2
OK OK
Crash of train 2 Crash of train 2
Error, identifier already used Error, engine identifier already used by engine
T2-Epsilon T2-Epsilon
Error, identifier already used Error, engine identifier already used by train set
Error, identifier already used Error, train set identifier already used by train set
Error, identifier already used Error, train set identifier already used by engine
T2-Lambda T2-Lambda
train-set T2-Lambda added to train 3 train-set T2-Lambda added to train 3
++ ++