Checkstyle

This commit is contained in:
Arne Keller 2020-03-05 10:48:00 +01:00
parent ce63ed3bed
commit 0e56a1c73b
28 changed files with 178 additions and 158 deletions

View File

@ -19,6 +19,10 @@ public abstract class Coach extends RollingStock {
* Regex pattern to match coach identifiers. * Regex pattern to match coach identifiers.
*/ */
public static final Pattern IDENTIFIER_PATTERN = Pattern.compile(IDENTIFIER_PREFIX + "\\+?\\d+"); public static final Pattern IDENTIFIER_PATTERN = Pattern.compile(IDENTIFIER_PREFIX + "\\+?\\d+");
/**
* Regex pattern to match coach type (passenger, freight, or special).
*/
public static final String COACH_TYPE = "passenger|freight|special";
/** /**
* The unique identifier of this coach. * The unique identifier of this coach.
@ -33,8 +37,7 @@ public abstract class Coach extends RollingStock {
* @param couplingBack whether the coach should have a back coupling * @param couplingBack whether the coach should have a back coupling
* @throws InvalidInputException on invalid user input (zero-sized coach) * @throws InvalidInputException on invalid user input (zero-sized coach)
*/ */
public Coach(final int identifier, final int length, public Coach(int identifier, int length, boolean couplingFront, boolean couplingBack) throws InvalidInputException {
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException {
super(length, couplingFront, couplingBack); super(length, couplingFront, couplingBack);
this.identifier = identifier; this.identifier = identifier;
} }

View File

@ -30,8 +30,8 @@ public class DieselEngine extends Engine {
* @param couplingBack whether the engine should have a back coupling * @param couplingBack whether the engine should have a back coupling
* @throws InvalidInputException on invalid user input (e.g. zero-sized engine) * @throws InvalidInputException on invalid user input (e.g. zero-sized engine)
*/ */
public DieselEngine(final String series, final String name, final int length, public DieselEngine(String series, String name, int length,
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException { boolean couplingFront, boolean couplingBack) throws InvalidInputException {
super(series, name, length, couplingFront, couplingBack); super(series, name, length, couplingFront, couplingBack);
} }

View File

@ -32,8 +32,8 @@ public class ElectricalEngine extends Engine {
* @param couplingBack whether the engine should have a back coupling * @param couplingBack whether the engine should have a back coupling
* @throws InvalidInputException on invalid user input (e.g. zero-sized engine) * @throws InvalidInputException on invalid user input (e.g. zero-sized engine)
*/ */
public ElectricalEngine(final String series, final String name, final int length, public ElectricalEngine(String series, String name, int length,
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException { boolean couplingFront, boolean couplingBack) throws InvalidInputException {
super(series, name, length, couplingFront, couplingBack); super(series, name, length, couplingFront, couplingBack);
} }

View File

@ -27,8 +27,8 @@ public abstract class Engine extends RollingStock {
* @param couplingBack whether this engine should have a back coupling * @param couplingBack whether this engine should have a back coupling
* @throws InvalidInputException on invalid user input (zero-sized coach) * @throws InvalidInputException on invalid user input (zero-sized coach)
*/ */
protected Engine(final String series, final String name, final int length, protected Engine(String series, String name, int length,
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException { boolean couplingFront, boolean couplingBack) throws InvalidInputException {
super(length, couplingFront, couplingBack); super(length, couplingFront, couplingBack);
this.series = series; this.series = series;
this.name = name; this.name = name;

View File

@ -47,7 +47,7 @@ public class ModelRailwaySimulation {
* @return the positive identifier of the new track if successful, -1 if none available * @return the positive identifier of the new track if successful, -1 if none available
* @throws InvalidInputException if user input is invalid (e.g. zero length track) * @throws InvalidInputException if user input is invalid (e.g. zero length track)
*/ */
public int addTrack(final Vector2D start, final Vector2D end) throws InvalidInputException { public int addTrack(Vector2D start, Vector2D end) throws InvalidInputException {
return railNetwork.addTrack(start, end); return railNetwork.addTrack(start, end);
} }
@ -90,7 +90,7 @@ public class ModelRailwaySimulation {
* @return whether the switch could be set * @return whether the switch could be set
*/ */
public boolean setSwitch(int id, Vector2D position) { public boolean setSwitch(int id, Vector2D position) {
boolean success = railNetwork.setSwitch(id, position); final boolean success = railNetwork.setSwitch(id, position);
if (success) { // derail trains on switch, explicitly not (!) printing any removed trains (source: forum post) if (success) { // derail trains on switch, explicitly not (!) printing any removed trains (source: forum post)
trainManager.removeTrainsOnRail(railNetwork.getRail(id)); trainManager.removeTrainsOnRail(railNetwork.getRail(id));
} }
@ -102,7 +102,7 @@ public class ModelRailwaySimulation {
* @throws InvalidInputException when the identifier is already in use * @throws InvalidInputException when the identifier is already in use
*/ */
public void createEngine(Engine newEngine) throws InvalidInputException { public void createEngine(Engine newEngine) throws InvalidInputException {
String id = newEngine.getIdentifier(); final String id = newEngine.getIdentifier();
if (Stream.concat(engines.stream(), trainSets.stream()) if (Stream.concat(engines.stream(), trainSets.stream())
.anyMatch(rollingStock -> rollingStock.getIdentifier().equals(id))) { .anyMatch(rollingStock -> rollingStock.getIdentifier().equals(id))) {
throw new InvalidInputException("engine identifier already used"); throw new InvalidInputException("engine identifier already used");
@ -118,7 +118,7 @@ public class ModelRailwaySimulation {
public List<String> listEngines() { public List<String> listEngines() {
engines.sort(Comparator.comparing(Engine::getIdentifier)); engines.sort(Comparator.comparing(Engine::getIdentifier));
return engines.stream().map(engine -> { return engines.stream().map(engine -> {
String trainId = trainManager.getTrainContainingRollingStock(engine) final String trainId = trainManager.getTrainContainingRollingStock(engine)
.map(train -> Integer.toString(train.getIdentifier())) .map(train -> Integer.toString(train.getIdentifier()))
.orElse("none"); .orElse("none");
return String.format("%s %s", trainId, engine); return String.format("%s %s", trainId, engine);
@ -136,7 +136,7 @@ public class ModelRailwaySimulation {
*/ */
public int createCoach(CoachType coachType, int length, public int createCoach(CoachType coachType, int length,
boolean couplingFront, boolean couplingBack) throws InvalidInputException { boolean couplingFront, boolean couplingBack) throws InvalidInputException {
int id = getNextCoachIdentifier(); final int id = getNextCoachIdentifier();
if (id < 0) { if (id < 0) {
return -1; return -1;
} }
@ -172,8 +172,8 @@ public class ModelRailwaySimulation {
*/ */
public List<String> listCoaches() { public List<String> listCoaches() {
return coaches.keySet().stream().sorted().map(coachId -> { return coaches.keySet().stream().sorted().map(coachId -> {
Coach coach = coaches.get(coachId); final Coach coach = coaches.get(coachId);
String trainId = trainManager.getTrainContainingRollingStock(coach) final String trainId = trainManager.getTrainContainingRollingStock(coach)
.map(train -> Integer.toString(train.getIdentifier())) .map(train -> Integer.toString(train.getIdentifier()))
.orElse("none"); .orElse("none");
return String.format("%d %s %s %d %b %b", return String.format("%d %s %s %d %b %b",
@ -188,7 +188,7 @@ public class ModelRailwaySimulation {
* @throws InvalidInputException if the identifier is already used * @throws InvalidInputException if the identifier is already used
*/ */
public void createTrainSet(TrainSet newTrainSet) throws InvalidInputException { public void createTrainSet(TrainSet newTrainSet) throws InvalidInputException {
String id = newTrainSet.getIdentifier(); final String id = newTrainSet.getIdentifier();
if (Stream.concat(engines.stream(), trainSets.stream()) if (Stream.concat(engines.stream(), trainSets.stream())
.anyMatch(rollingStock -> rollingStock.getIdentifier().equals(id))) { .anyMatch(rollingStock -> rollingStock.getIdentifier().equals(id))) {
throw new InvalidInputException("train set identifier already used"); throw new InvalidInputException("train set identifier already used");
@ -217,7 +217,7 @@ public class ModelRailwaySimulation {
* @return whether the rolling was successfully removed * @return whether the rolling was successfully removed
*/ */
public boolean deleteRollingStock(String id) { public boolean deleteRollingStock(String id) {
RollingStock rollingStock = getRollingStock(id); final RollingStock rollingStock = getRollingStock(id);
if (trainManager.getTrainContainingRollingStock(rollingStock).isPresent()) { if (trainManager.getTrainContainingRollingStock(rollingStock).isPresent()) {
return false; // can not delete rolling stock in use return false; // can not delete rolling stock in use
} }
@ -231,7 +231,7 @@ public class ModelRailwaySimulation {
*/ */
public RollingStock getRollingStock(String id) { public RollingStock getRollingStock(String id) {
if (Coach.IDENTIFIER_PATTERN.matcher(id).matches()) { if (Coach.IDENTIFIER_PATTERN.matcher(id).matches()) {
int coachId = Integer.parseInt(id.substring(1)); final int coachId = Integer.parseInt(id.substring(1));
return coaches.get(coachId); return coaches.get(coachId);
} else { } else {
return Stream.concat(engines.stream(), trainSets.stream()) return Stream.concat(engines.stream(), trainSets.stream())
@ -247,7 +247,7 @@ public class ModelRailwaySimulation {
* @throws InvalidInputException if input is incorrect * @throws InvalidInputException if input is incorrect
*/ */
public void addTrain(int trainId, String rollingStockId) throws InvalidInputException { public void addTrain(int trainId, String rollingStockId) throws InvalidInputException {
RollingStock rollingStock = getRollingStock(rollingStockId); final RollingStock rollingStock = getRollingStock(rollingStockId);
if (rollingStock == null) { if (rollingStock == null) {
throw new InvalidInputException("rolling stock not found"); throw new InvalidInputException("rolling stock not found");
} }
@ -300,7 +300,7 @@ public class ModelRailwaySimulation {
* @param speed amount of steps to move the trains * @param speed amount of steps to move the trains
* @throws InvalidInputException if the simulation is not yet ready * @throws InvalidInputException if the simulation is not yet ready
*/ */
public void step(final short speed) throws InvalidInputException { public void step(short speed) throws InvalidInputException {
trainManager.step(speed); trainManager.step(speed);
} }
} }

View File

@ -166,7 +166,7 @@ public class RailwayNetwork {
* @param position position to set the switch to * @param position position to set the switch to
* @return whether the switch could be set * @return whether the switch could be set
*/ */
public boolean setSwitch(final int id, final Vector2D position) { public boolean setSwitch(int id, Vector2D position) {
final Rail toSwitch = rails.get(id); final Rail toSwitch = rails.get(id);
if (toSwitch != null) { if (toSwitch != null) {
return toSwitch.switchTo(position); return toSwitch.switchTo(position);

View File

@ -22,12 +22,13 @@ public final class Track extends Rail {
/** /**
* Construct a new track. Start and end positions have to be on a straight line! * Construct a new track. Start and end positions have to be on a straight line!
*
* @param start start position of the track * @param start start position of the track
* @param end end position of the track * @param end end position of the track
* @param id identifier to use * @param id identifier to use
* @throws InvalidInputException if the positions are not on a straight line * @throws InvalidInputException if the positions are not on a straight line
*/ */
public Track(final Vector2D start, final Vector2D end, final int id) throws InvalidInputException { public Track(Vector2D start, Vector2D end, int id) throws InvalidInputException {
super(id); super(id);
if (start.getX() != end.getX() && start.getY() != end.getY()) { if (start.getX() != end.getX() && start.getY() != end.getY()) {
throw new InvalidInputException("invalid track segment: not a straight line"); throw new InvalidInputException("invalid track segment: not a straight line");
@ -62,15 +63,11 @@ public final class Track extends Rail {
return false; return false;
} }
if (start.getX() == end.getX() && position.getX() == start.getX()) { if (start.getX() == end.getX() && position.getX() == start.getX()) {
long startY = start.getY(); return start.getY() < position.getY() && position.getY() < end.getY()
long endY = end.getY(); || start.getY() > position.getY() && position.getY() > end.getY();
long positionY = position.getY();
return startY < positionY && positionY < endY || startY > positionY && positionY > endY;
} else if (start.getY() == end.getY() && position.getY() == start.getY()) { } else if (start.getY() == end.getY() && position.getY() == start.getY()) {
long startX = start.getX(); return start.getX() < position.getX() && position.getX() < end.getX()
long endX = end.getX(); || start.getX() > position.getX() && position.getX() > end.getX();
long positionX = position.getX();
return startX < positionX && positionX < endX || startX > positionX && positionX > endX;
} }
return false; return false;
} }
@ -82,17 +79,17 @@ public final class Track extends Rail {
@Override @Override
public Vector2D move(Vector2D position, Vector2D direction, long steps) { public Vector2D move(Vector2D position, Vector2D direction, long steps) {
Vector2D nextPosition = position.add(direction.scale(steps)); final Vector2D nextPosition = position.add(direction.scale(steps));
if (contains(nextPosition) || connectsTo(nextPosition)) { if (contains(nextPosition) || connectsTo(nextPosition)) {
return nextPosition; return nextPosition;
} else if (direction.equals(getDirectionFrom(start))) { } else if (direction.equals(getDirectionFrom(start))) {
return new Vector2D(end); return new Vector2D(end);
} else if (direction.equals(getDirectionFrom(end))) { } else if (direction.equals(getDirectionFrom(end))) {
return new Vector2D(start); return new Vector2D(start);
} else if (position.equals(end)) { } else if (position.equals(end) && !direction.equals(getDirectionFrom(start))) {
direction.copyFrom(getDirectionFrom(end)); direction.copyFrom(getDirectionFrom(end));
return move(position, getDirectionFrom(end), steps); return move(position, getDirectionFrom(end), steps);
} else if (position.equals(start)) { } else if (position.equals(start) && !direction.equals(getDirectionFrom(end))) {
direction.copyFrom(getDirectionFrom(start)); direction.copyFrom(getDirectionFrom(start));
return move(position, getDirectionFrom(start), steps); return move(position, getDirectionFrom(start), steps);
} }
@ -101,13 +98,10 @@ public final class Track extends Rail {
@Override @Override
public Vector2D getDirectionFrom(Vector2D position) { public Vector2D getDirectionFrom(Vector2D position) {
// have to use long arithmetic here to avoid overflows
if (start.equals(position)) { if (start.equals(position)) {
return new Vector2D(Long.signum(end.getX() - start.getX()), return new Vector2D(Long.signum(end.getX() - start.getX()), Long.signum(end.getY() - start.getY()));
Long.signum(end.getY() - start.getY()));
} else if (end.equals(position)) { } else if (end.equals(position)) {
return new Vector2D(Long.signum(start.getX() - end.getX()), return new Vector2D(Long.signum(start.getX() - end.getX()), Long.signum(start.getY() - end.getY()));
Long.signum(start.getY() - end.getY()));
} else { } else {
// in the middle of track, simply return direction from start // in the middle of track, simply return direction from start
return getDirectionFrom(start); return getDirectionFrom(start);
@ -116,11 +110,8 @@ public final class Track extends Rail {
@Override @Override
public boolean allowsDirectionFrom(Vector2D position, Vector2D direction) { public boolean allowsDirectionFrom(Vector2D position, Vector2D direction) {
if (contains(position)) { if (contains(position) || connectsTo(position)) {
return true; return getDirectionFrom(position).isParallelTo(direction);
} else if (connectsTo(position)) {
return getDirectionFrom(position).equals(direction)
|| getDirectionFrom(position).negated().equals(direction);
} }
return false; return false;
} }
@ -144,7 +135,7 @@ public final class Track extends Rail {
} }
@Override @Override
public boolean equals(final Object obj) { public boolean equals(Object obj) {
if (obj != null && getClass().equals(obj.getClass())) { if (obj != null && getClass().equals(obj.getClass())) {
final Track track = (Track) obj; final Track track = (Track) obj;

View File

@ -36,7 +36,7 @@ public final class TrainManager {
/** /**
* Construct a new train manager that will operate on the provided rail network. * Construct a new train manager that will operate on the provided rail network.
* *
* @param railNetwork rail network to use * @param railNetwork rail network to use
*/ */
public TrainManager(RailwayNetwork railNetwork) { public TrainManager(RailwayNetwork railNetwork) {
@ -46,7 +46,7 @@ public final class TrainManager {
/** /**
* Check whether a train is on the rail with the specified identifier. Note that a train must be partially on that * Check whether a train is on the rail with the specified identifier. Note that a train must be partially on that
* rail, simply touching one of the end points is not enough. * rail, simply touching one of the end points is not enough.
* *
* @param rail the rail to check * @param rail the rail to check
* @return whether a train is on that rail * @return whether a train is on that rail
*/ */
@ -56,6 +56,7 @@ public final class TrainManager {
/** /**
* Remove any trains on the rail with the specified identifier. * Remove any trains on the rail with the specified identifier.
*
* @param rail rail to clear * @param rail rail to clear
*/ */
public void removeTrainsOnRail(Rail rail) { public void removeTrainsOnRail(Rail rail) {
@ -64,7 +65,7 @@ public final class TrainManager {
/** /**
* Get the train containing the specified rolling stock. * Get the train containing the specified rolling stock.
* *
* @param rollingStock rolling stock to search for * @param rollingStock rolling stock to search for
* @return the train containing the rolling stock * @return the train containing the rolling stock
*/ */
@ -74,7 +75,7 @@ public final class TrainManager {
/** /**
* Add a rolling stock to an existing train or create a new one. * Add a rolling stock to an existing train or create a new one.
* *
* @param trainId train identifier * @param trainId train identifier
* @param rollingStock rolling stock to add * @param rollingStock rolling stock to add
* @throws InvalidInputException on invalid user input (e.g. rolling stock in use) * @throws InvalidInputException on invalid user input (e.g. rolling stock in use)
@ -83,29 +84,30 @@ public final class TrainManager {
if (getTrainContainingRollingStock(rollingStock).isPresent()) { if (getTrainContainingRollingStock(rollingStock).isPresent()) {
throw new InvalidInputException("rolling stock already used"); throw new InvalidInputException("rolling stock already used");
} }
Train train = trains.get(trainId); final Train train = trains.get(trainId);
if (train != null && train.isPlaced()) { if (train != null && train.isPlaced()) {
throw new InvalidInputException("can not add rolling stock to placed train"); throw new InvalidInputException("can not add rolling stock to placed train");
} }
if (train != null) { if (train != null) {
train.add(rollingStock); train.add(rollingStock);
} else { } else {
int correctId = getNextTrainIdentifier(); final int correctId = getNextTrainIdentifier();
if (trainId != correctId) { if (trainId != correctId) {
throw new InvalidInputException("new train identifier must be next free identifier"); throw new InvalidInputException("new train identifier must be next free identifier");
} }
Train newTrain = new Train(trainId, rollingStock); final Train newTrain = new Train(trainId, rollingStock);
trains.put(trainId, newTrain); trains.put(trainId, newTrain);
} }
} }
/** /**
* Delete a train. * Delete a train. Will not delete rolling stock contained in that train.
*
* @param trainId identifier of the train * @param trainId identifier of the train
* @return whether the train could be deleted * @return whether the train could be deleted
*/ */
public boolean deleteTrain(int trainId) { public boolean deleteTrain(int trainId) {
Train train = trains.get(trainId); final Train train = trains.get(trainId);
if (train != null) { if (train != null) {
trains.remove(trainId); trains.remove(trainId);
return true; return true;
@ -133,7 +135,7 @@ public final class TrainManager {
* @throws InvalidInputException if train not found * @throws InvalidInputException if train not found
*/ */
public List<String> showTrain(int trainId) throws InvalidInputException { public List<String> showTrain(int trainId) throws InvalidInputException {
Train train = trains.get(trainId); final Train train = trains.get(trainId);
if (train != null) { if (train != null) {
return train.show(); return train.show();
} else { } else {
@ -150,7 +152,7 @@ public final class TrainManager {
* @throws InvalidInputException when the train is too long * @throws InvalidInputException when the train is too long
*/ */
public boolean putTrain(int trainId, Vector2D position, Vector2D direction) throws InvalidInputException { public boolean putTrain(int trainId, Vector2D position, Vector2D direction) throws InvalidInputException {
Train train = trains.get(trainId); final Train train = trains.get(trainId);
if (train == null) { if (train == null) {
throw new InvalidInputException("train not found"); throw new InvalidInputException("train not found");
} else if (!train.isProperTrain()) { } else if (!train.isProperTrain()) {
@ -163,7 +165,7 @@ public final class TrainManager {
throw new InvalidInputException("switches not set up"); throw new InvalidInputException("switches not set up");
} }
// attempt to place train // attempt to place train
boolean placed = train.placeOn(railNetwork, position, direction); final boolean placed = train.placeOn(railNetwork, position, direction);
// check for collisions // check for collisions
if (placed && !getPlacementCollisions().isEmpty()) { if (placed && !getPlacementCollisions().isEmpty()) {
train.removeFromRails(); train.removeFromRails();
@ -187,28 +189,21 @@ public final class TrainManager {
* @param collisions list of collisions (never null, sometimes empty) * @param collisions list of collisions (never null, sometimes empty)
*/ */
private void getStaticCollisions(List<Set<Train>> collisions) { private void getStaticCollisions(List<Set<Train>> collisions) {
int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0); final int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0);
for (int id1 = 1; id1 <= maxId; id1++) { for (int id = 1; id <= maxId; id++) {
Train train1 = trains.get(id1); final Train train1 = trains.get(id);
if (train1 == null || !train1.isPlaced()) { if (train1 == null || !train1.isPlaced()) {
continue; continue;
} }
HashSet<Train> collision = new HashSet<>(); final Set<Rail> occupiedRails = train1.getOccupiedRails();
// check for same position // check for same position, and rail collisions
IntStream.rangeClosed(id1 + 1, maxId) final Set<Train> collision = IntStream.rangeClosed(id + 1, maxId)
.mapToObj(trains::get) .mapToObj(trains::get)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(Train::isPlaced) .filter(Train::isPlaced)
.filter(train1::touches) .filter(train -> train1.touches(train)
.forEach(collision::add); || train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
// check for rail collisions .collect(Collectors.toSet());
Set<Rail> occupiedRails = train1.getOccupiedRails();
IntStream.rangeClosed(id1 + 1, maxId)
.mapToObj(trains::get)
.filter(Objects::nonNull)
.filter(Train::isPlaced)
.filter(train -> train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
.forEach(collision::add);
if (!collision.isEmpty()) { if (!collision.isEmpty()) {
collision.add(train1); collision.add(train1);
addToSetOrAddNew(collisions, collision); addToSetOrAddNew(collisions, collision);
@ -218,25 +213,27 @@ public final class TrainManager {
/** /**
* Implementation of the silly *second* collision checking algorithm. * Implementation of the silly *second* collision checking algorithm.
* Will put two trains in a collision even if they only touch the same rail.
*
* @return list of collisions * @return list of collisions
*/ */
private List<Set<Train>> getPlacementCollisions() { private List<Set<Train>> getPlacementCollisions() {
List<Set<Train>> collisions = new ArrayList<>(); final List<Set<Train>> collisions = new ArrayList<>();
trains.values().stream().filter(Train::isPlaced).forEach(train1 -> { trains.values().stream().filter(Train::isPlaced).forEach(train1 ->
trains.values().stream().filter(train -> train != train1).filter(Train::isPlaced).forEach(train2 -> { trains.values().stream().filter(train -> train != train1).filter(Train::isPlaced).forEach(train2 -> {
Set<Rail> occupiedByTrain1 = train1.getOccupiedRails(); final Set<Rail> occupiedByTrain1 = train1.getOccupiedRails();
Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getFrontPosition())); Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getFrontPosition()));
Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getRearPosition())); Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getRearPosition()));
Set<Rail> occupiedByTrain2 = train2.getOccupiedRails(); final Set<Rail> occupiedByTrain2 = train2.getOccupiedRails();
Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getFrontPosition())); Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getFrontPosition()));
Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getRearPosition())); Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getRearPosition()));
occupiedByTrain2.retainAll(occupiedByTrain1); // calculate intersection
if (!occupiedByTrain2.isEmpty()) { occupiedByTrain2.retainAll(occupiedByTrain1);
Set<Train> collision = Stream.of(train1, train2).collect(Collectors.toSet()); if (!occupiedByTrain2.isEmpty()) {
addToSetOrAddNew(collisions, collision); final Set<Train> collision = Stream.of(train1, train2).collect(Collectors.toSet());
} addToSetOrAddNew(collisions, collision);
}); }
}); }));
return collisions; return collisions;
} }
@ -266,19 +263,22 @@ public final class TrainManager {
} }
/** /**
* Get collisions of moving the trains one step forward. * Get collisions of moving the trains one step forward, removing crashing trains from the rails in the process.
*
* @return list of collisions (never null, sometimes empty) * @return list of collisions (never null, sometimes empty)
*/ */
private List<Set<Train>> getCollisionsOfOneStep() { private List<Set<Train>> getCollisionsOfOneStep() {
List<Set<Train>> collisions = new ArrayList<>(); final List<Set<Train>> collisions = new ArrayList<>();
trains.values().stream().filter(Train::isPlaced).forEach(train -> { trains.values().stream().filter(Train::isPlaced).forEach(train -> {
Vector2D position = train.getFrontPosition(); final Vector2D position = train.getFrontPosition();
Vector2D direction = train.getDirection(); final Vector2D direction = train.getDirection();
Vector2D nextPosition = railNetwork.move(position, direction, 1); final Vector2D nextPosition = railNetwork.move(position, direction, 1);
if (nextPosition == null || nextPosition.equals(position)) { if (nextPosition == null || nextPosition.equals(position)) {
// train is derailing
train.moveTo(railNetwork, null); train.moveTo(railNetwork, null);
collisions.add(new HashSet<>(Arrays.asList(train))); collisions.add(new HashSet<>(Arrays.asList(train)));
} else { } else {
// train is moving successfully
train.moveTo(railNetwork, nextPosition); train.moveTo(railNetwork, nextPosition);
} }
}); });
@ -288,21 +288,23 @@ public final class TrainManager {
} }
/** /**
* Get collisions of moving the trains one step backward. * Get collisions of moving the trains one step backward, removing crashing trains from the rails in the process.
*
* @return list of collisions (never null, sometimes empty) * @return list of collisions (never null, sometimes empty)
*/ */
private List<Set<Train>> getCollisionsOfOneReverseStep() { private List<Set<Train>> getCollisionsOfOneReverseStep() {
List<Set<Train>> collisions = new ArrayList<>(); final List<Set<Train>> collisions = new ArrayList<>();
// perform step // perform step
trains.values().stream().filter(Train::isPlaced).forEach(train -> { trains.values().stream().filter(Train::isPlaced).forEach(train -> {
Vector2D position = train.getRearPosition(); final Vector2D position = train.getRearPosition();
Vector2D direction = train.getRearDirection(); final Vector2D direction = train.getRearDirection();
Vector2D nextPosition = railNetwork.move(position, direction, 1); final Vector2D nextPosition = railNetwork.move(position, direction, 1);
if (nextPosition == null if (nextPosition == null || nextPosition.equals(position)) {
|| train.isOnPosition(nextPosition) && !train.getRearPosition().equals(train.getFrontPosition())) { // derailing
train.moveBackTo(railNetwork, nextPosition); train.moveBackTo(railNetwork, nextPosition);
collisions.add(new HashSet<>(Arrays.asList(train))); collisions.add(new HashSet<>(Arrays.asList(train)));
} else { } else {
// train moving successfully
train.moveBackTo(railNetwork, nextPosition); train.moveBackTo(railNetwork, nextPosition);
} }
}); });
@ -325,19 +327,21 @@ public final class TrainManager {
return; return;
} }
List<Set<Train>> collisions = IntStream.range(0, Math.abs(speed)) final List<Set<Train>> collisions = IntStream.range(0, Math.abs(speed))
.mapToObj(step -> speed >= 0 ? getCollisionsOfOneStep() : getCollisionsOfOneReverseStep()) .mapToObj(step -> speed >= 0 ? getCollisionsOfOneStep() : getCollisionsOfOneReverseStep())
.flatMap(List::stream).collect(Collectors.toList()); .flatMap(List::stream).collect(Collectors.toList());
for (int id : trains.keySet().stream().sorted().collect(Collectors.toList())) { for (final int id : trains.keySet().stream().sorted().collect(Collectors.toList())) {
Train train = trains.get(id); final Train train = trains.get(id);
Set<Train> collisionSet = collisions.stream() final Set<Train> collisionSet = collisions.stream()
.filter(collision -> collision.contains(train)) .filter(collision -> collision.contains(train))
.findFirst().orElse(null); .findFirst().orElse(null);
if (collisionSet != null) { // print collision if (collisionSet != null) { // print collision
int first = collisionSet.stream().min(Comparator.comparing(Train::getIdentifier)).get().getIdentifier(); final 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)) final List<Train> collision = collisionSet.stream()
.sorted(Comparator.comparing(Train::getIdentifier))
.collect(Collectors.toList()); .collect(Collectors.toList());
Terminal.printLine("Crash of train " + String.join(",", collision.stream() Terminal.printLine("Crash of train " + String.join(",", collision.stream()
.map(crashedTrain -> Integer.toString(crashedTrain.getIdentifier())) .map(crashedTrain -> Integer.toString(crashedTrain.getIdentifier()))

View File

@ -41,7 +41,7 @@ public class Vector2D {
* @param input two 32-bit numbers separated by a comma * @param input two 32-bit numbers separated by a comma
* @return a vector containing the two numbers, null otherwise * @return a vector containing the two numbers, null otherwise
*/ */
public static Vector2D parse(final String input) { public static Vector2D parse(String input) {
final String[] coordinates = input.split(",", 2); final String[] coordinates = input.split(",", 2);
final int x = Integer.parseInt(coordinates[0]); final int x = Integer.parseInt(coordinates[0]);
final int y = Integer.parseInt(coordinates[1]); final int y = Integer.parseInt(coordinates[1]);
@ -62,6 +62,20 @@ public class Vector2D {
return other != null ? Math.abs(this.x - other.x) + Math.abs(this.y - other.y) : 0; return other != null ? Math.abs(this.x - other.x) + Math.abs(this.y - other.y) : 0;
} }
/**
* Check whether this vector is parallel to another vector. Note that this method only works for vectors that
* are parallel to one of the coordinate axes.
*
* @param other the point to measure distance to
* @return the manhattan distance
*/
public boolean isParallelTo(Vector2D other) {
if (other == null) {
return false;
}
return x == 0 && other.x == 0 || y == 0 && other.y == 0;
}
/** /**
* @return a vector with separately (!) normalized components * @return a vector with separately (!) normalized components
*/ */

View File

@ -35,11 +35,11 @@ public class AddSwitch extends Command {
private Vector2D end2; private Vector2D end2;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (start == null) { if (start == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
int id = simulation.addSwitch(start, end1, end2); final int id = simulation.addSwitch(start, end1, end2);
if (id == -1) { if (id == -1) {
Terminal.printError("switch not connected to existing rails"); Terminal.printError("switch not connected to existing rails");
} else { } else {
@ -52,7 +52,7 @@ public class AddSwitch extends Command {
if (input == null || !input.startsWith(ADD_SWITCH)) { if (input == null || !input.startsWith(ADD_SWITCH)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = ADD_SWITCH_ARGUMENTS.matcher(input.substring(ADD_SWITCH.length())); final Matcher matcher = ADD_SWITCH_ARGUMENTS.matcher(input.substring(ADD_SWITCH.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid add switch argument syntax"); throw new InvalidInputException("invalid add switch argument syntax");
} }

View File

@ -31,11 +31,11 @@ public class AddTrack extends Command {
private Vector2D end; private Vector2D end;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (start == null) { if (start == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
int id = simulation.addTrack(start, end); final int id = simulation.addTrack(start, end);
if (id == -1) { if (id == -1) {
Terminal.printError("id space exhausted"); Terminal.printError("id space exhausted");
} else { } else {
@ -48,7 +48,7 @@ public class AddTrack extends Command {
if (input == null || !input.startsWith(ADD_TRACK)) { if (input == null || !input.startsWith(ADD_TRACK)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = ADD_TRACK_ARGUMENTS.matcher(input.substring(ADD_TRACK.length())); final Matcher matcher = ADD_TRACK_ARGUMENTS.matcher(input.substring(ADD_TRACK.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid add track argument syntax"); throw new InvalidInputException("invalid add track argument syntax");
} }

View File

@ -32,12 +32,12 @@ public class AddTrain extends Command {
private String rollingStockId; private String rollingStockId;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (rollingStockId == null) { if (rollingStockId == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
simulation.addTrain(trainId, rollingStockId); simulation.addTrain(trainId, rollingStockId);
RollingStock rollingStock = simulation.getRollingStock(rollingStockId); final RollingStock rollingStock = simulation.getRollingStock(rollingStockId);
Terminal.printLine(String.format("%s %s added to train %d", Terminal.printLine(String.format("%s %s added to train %d",
rollingStock.description(), rollingStock.getIdentifier(), trainId)); rollingStock.description(), rollingStock.getIdentifier(), trainId));
} }
@ -47,7 +47,7 @@ public class AddTrain extends Command {
if (input == null || !input.startsWith(ADD_TRAIN)) { if (input == null || !input.startsWith(ADD_TRAIN)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = ADD_TRAIN_ARGUMENTS.matcher(input.substring(ADD_TRAIN.length())); final Matcher matcher = ADD_TRAIN_ARGUMENTS.matcher(input.substring(ADD_TRAIN.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid add train arguments"); throw new InvalidInputException("invalid add train arguments");
} }

View File

@ -31,6 +31,10 @@ public final class CommandFactory {
*/ */
public static final String ROLLING_STOCK_IDENTIFIER public static final String ROLLING_STOCK_IDENTIFIER
= "(" + ALPHANUMERIC_WORD + "-" + ALPHANUMERIC_WORD + ")|" + Coach.IDENTIFIER_PATTERN; = "(" + ALPHANUMERIC_WORD + "-" + ALPHANUMERIC_WORD + ")|" + Coach.IDENTIFIER_PATTERN;
/**
* Regex to accept one boolean (true or false).
*/
public static final String BOOL = "true|false";
/** /**
* Name of the add track command. * Name of the add track command.
@ -143,9 +147,9 @@ public final class CommandFactory {
* @throws InvalidInputException if user input is invalid * @throws InvalidInputException if user input is invalid
*/ */
public static Command getCommand(String input) throws InvalidInputException { public static Command getCommand(String input) throws InvalidInputException {
for (Map.Entry<String, Supplier<Command>> entry : COMMANDS.entrySet()) { for (final Map.Entry<String, Supplier<Command>> entry : COMMANDS.entrySet()) {
if (input.startsWith(entry.getKey())) { if (input.startsWith(entry.getKey())) {
Command command = entry.getValue().get(); final Command command = entry.getValue().get();
command.parse(input); command.parse(input);
return command; return command;
} }

View File

@ -8,6 +8,8 @@ import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static edu.kit.informatik.model.Coach.COACH_TYPE;
import static edu.kit.informatik.ui.command.CommandFactory.BOOL;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_COACH; import static edu.kit.informatik.ui.command.CommandFactory.CREATE_COACH;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER; import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
@ -19,7 +21,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
*/ */
public class CreateCoach extends Command { public class CreateCoach extends Command {
private static final Pattern CREATE_COACH_ARGUMENTS private static final Pattern CREATE_COACH_ARGUMENTS
= Pattern.compile(" (passenger|freight|special) (" + NUMBER + ") (true|false) (true|false)"); = Pattern.compile(" (" + COACH_TYPE + ") (" + NUMBER + ") (" + BOOL + ") (" + BOOL + ")");
/** /**
* Type of the new coach. * Type of the new coach.
@ -39,11 +41,11 @@ public class CreateCoach extends Command {
private boolean couplingBack; private boolean couplingBack;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (type == null) { if (type == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
int id = simulation.createCoach(type, length, couplingFront, couplingBack); final int id = simulation.createCoach(type, length, couplingFront, couplingBack);
if (id == -1) { if (id == -1) {
Terminal.printError("id space exhausted"); Terminal.printError("id space exhausted");
} else { } else {
@ -56,7 +58,7 @@ public class CreateCoach extends Command {
if (input == null || !input.startsWith(CREATE_COACH)) { if (input == null || !input.startsWith(CREATE_COACH)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = CREATE_COACH_ARGUMENTS.matcher(input.substring(CREATE_COACH.length())); final Matcher matcher = CREATE_COACH_ARGUMENTS.matcher(input.substring(CREATE_COACH.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid create coach arguments"); throw new InvalidInputException("invalid create coach arguments");
} }

View File

@ -14,6 +14,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD; import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD;
import static edu.kit.informatik.ui.command.CommandFactory.BOOL;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_ENGINE; import static edu.kit.informatik.ui.command.CommandFactory.CREATE_ENGINE;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER; import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
@ -26,7 +27,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
public class CreateEngine extends Command { public class CreateEngine extends Command {
private static final Pattern CREATE_ENGINE_ARGUMENTS private static final Pattern CREATE_ENGINE_ARGUMENTS
= Pattern.compile(" (electrical|diesel|steam) (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" = Pattern.compile(" (electrical|diesel|steam) (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") ("
+ NUMBER + ") (true|false) (true|false)"); + NUMBER + ") (" + BOOL + ") (" + BOOL + ")");
/** /**
* Type of the new engine. * Type of the new engine.
@ -54,11 +55,11 @@ public class CreateEngine extends Command {
private boolean couplingBack; private boolean couplingBack;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (type == null) { if (type == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
Engine engine; final Engine engine;
switch (type) { switch (type) {
case ELECTRICAL: case ELECTRICAL:
engine = new ElectricalEngine(series, name, length, couplingFront, couplingBack); engine = new ElectricalEngine(series, name, length, couplingFront, couplingBack);
@ -70,7 +71,7 @@ public class CreateEngine extends Command {
engine = new DieselEngine(series, name, length, couplingFront, couplingBack); engine = new DieselEngine(series, name, length, couplingFront, couplingBack);
break; break;
default: default:
throw new IllegalStateException("engine type is null!"); throw new IllegalStateException("command not initialized");
} }
simulation.createEngine(engine); simulation.createEngine(engine);
Terminal.printLine(engine.getIdentifier()); Terminal.printLine(engine.getIdentifier());
@ -81,7 +82,7 @@ public class CreateEngine extends Command {
if (input == null || !input.startsWith(CREATE_ENGINE)) { if (input == null || !input.startsWith(CREATE_ENGINE)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = CREATE_ENGINE_ARGUMENTS.matcher(input.substring(CREATE_ENGINE.length())); final Matcher matcher = CREATE_ENGINE_ARGUMENTS.matcher(input.substring(CREATE_ENGINE.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid create engine argument syntax"); throw new InvalidInputException("invalid create engine argument syntax");
} }

View File

@ -10,6 +10,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD; import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD;
import static edu.kit.informatik.ui.command.CommandFactory.BOOL;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_TRAIN_SET; import static edu.kit.informatik.ui.command.CommandFactory.CREATE_TRAIN_SET;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER; import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
@ -22,7 +23,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
public class CreateTrainSet extends Command { public class CreateTrainSet extends Command {
private static final Pattern CREATE_TRAIN_SET_ARGUMENTS private static final Pattern CREATE_TRAIN_SET_ARGUMENTS
= Pattern.compile(" (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" = Pattern.compile(" (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") ("
+ NUMBER + ") (true|false) (true|false)"); + NUMBER + ") (" + BOOL + ") (" + BOOL + ")");
/** /**
* Series (class) of the new train set. * Series (class) of the new train set.
@ -46,11 +47,11 @@ public class CreateTrainSet extends Command {
private boolean couplingBack; private boolean couplingBack;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (name == null) { if (name == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
TrainSet trainSet = new TrainSet(series, name, length, couplingFront, couplingBack); final TrainSet trainSet = new TrainSet(series, name, length, couplingFront, couplingBack);
simulation.createTrainSet(trainSet); simulation.createTrainSet(trainSet);
Terminal.printLine(trainSet.getIdentifier()); Terminal.printLine(trainSet.getIdentifier());
} }
@ -60,7 +61,7 @@ public class CreateTrainSet extends Command {
if (input == null || !input.startsWith(CREATE_TRAIN_SET)) { if (input == null || !input.startsWith(CREATE_TRAIN_SET)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = CREATE_TRAIN_SET_ARGUMENTS.matcher(input.substring(CREATE_TRAIN_SET.length())); final Matcher matcher = CREATE_TRAIN_SET_ARGUMENTS.matcher(input.substring(CREATE_TRAIN_SET.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid create train-set arguments"); throw new InvalidInputException("invalid create train-set arguments");
} }

View File

@ -17,8 +17,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.ROLLING_STOCK_IDENTIF
* @version 1.0 * @version 1.0
*/ */
public class DeleteRollingStock extends Command { public class DeleteRollingStock extends Command {
private static final Pattern DELETE_ROLLING_STOCK_ARGUMENT private static final Pattern DELETE_ROLLING_STOCK_ARGUMENT = Pattern.compile(" (" + ROLLING_STOCK_IDENTIFIER + ")");
= Pattern.compile(" (" + ROLLING_STOCK_IDENTIFIER + ")");
/** /**
* Identifier of the rolling stock to delete. * Identifier of the rolling stock to delete.
@ -26,7 +25,7 @@ public class DeleteRollingStock extends Command {
private String id; private String id;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
if (id == null) { if (id == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
@ -42,7 +41,7 @@ public class DeleteRollingStock extends Command {
if (input == null || !input.startsWith(DELETE_ROLLING_STOCK)) { if (input == null || !input.startsWith(DELETE_ROLLING_STOCK)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = DELETE_ROLLING_STOCK_ARGUMENT.matcher(input.substring(DELETE_ROLLING_STOCK.length())); final Matcher matcher = DELETE_ROLLING_STOCK_ARGUMENT.matcher(input.substring(DELETE_ROLLING_STOCK.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid delete rolling stock argument"); throw new InvalidInputException("invalid delete rolling stock argument");
} }

View File

@ -20,7 +20,7 @@ public class DeleteTrack extends Command {
private int id; private int id;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
if (simulation.removeRail(id)) { if (simulation.removeRail(id)) {
Terminal.printLine("OK"); Terminal.printLine("OK");
} else { } else {
@ -33,7 +33,7 @@ public class DeleteTrack extends Command {
if (input == null || !input.startsWith(DELETE_TRACK)) { if (input == null || !input.startsWith(DELETE_TRACK)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
String argument = input.substring(DELETE_TRACK.length()); final String argument = input.substring(DELETE_TRACK.length());
if (!argument.matches(" " + NUMBER)) { if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid/missing delete track argument"); throw new InvalidInputException("invalid/missing delete track argument");
} }

View File

@ -20,7 +20,7 @@ public class DeleteTrain extends Command {
private int id; private int id;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
if (simulation.deleteTrain(id)) { if (simulation.deleteTrain(id)) {
Terminal.printLine("OK"); Terminal.printLine("OK");
} else { } else {
@ -33,7 +33,7 @@ public class DeleteTrain extends Command {
if (input == null || !input.startsWith(DELETE_TRAIN)) { if (input == null || !input.startsWith(DELETE_TRAIN)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
String argument = input.substring(DELETE_TRAIN.length()); final String argument = input.substring(DELETE_TRAIN.length());
if (!argument.matches(" " + NUMBER)) { if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid delete train argument"); throw new InvalidInputException("invalid delete train argument");
} }

View File

@ -16,8 +16,8 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_COACHES;
*/ */
public class ListCoaches extends Command { public class ListCoaches extends Command {
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
List<String> coaches = simulation.listCoaches(); final List<String> coaches = simulation.listCoaches();
if (coaches.isEmpty()) { if (coaches.isEmpty()) {
Terminal.printLine("No coach exists"); Terminal.printLine("No coach exists");
} else { } else {

View File

@ -16,8 +16,8 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_ENGINES;
*/ */
public class ListEngines extends Command { public class ListEngines extends Command {
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
List<String> engines = simulation.listEngines(); final List<String> engines = simulation.listEngines();
if (engines.isEmpty()) { if (engines.isEmpty()) {
Terminal.printLine("No engine exists"); Terminal.printLine("No engine exists");
} else { } else {

View File

@ -16,8 +16,8 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRACKS;
*/ */
public class ListTracks extends Command { public class ListTracks extends Command {
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
List<String> tracks = simulation.listTracks(); final List<String> tracks = simulation.listTracks();
if (tracks.isEmpty()) { if (tracks.isEmpty()) {
Terminal.printLine("No track exists"); Terminal.printLine("No track exists");
} else { } else {

View File

@ -16,8 +16,8 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAIN_SETS;
*/ */
public class ListTrainSets extends Command { public class ListTrainSets extends Command {
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
List<String> trainSets = simulation.listTrainSets(); final List<String> trainSets = simulation.listTrainSets();
if (trainSets.isEmpty()) { if (trainSets.isEmpty()) {
Terminal.printLine("No train-set exists"); Terminal.printLine("No train-set exists");
} else { } else {

View File

@ -16,8 +16,8 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAINS;
*/ */
public class ListTrains extends Command { public class ListTrains extends Command {
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
List<String> trains = simulation.listTrains(); final List<String> trains = simulation.listTrains();
if (trains.isEmpty()) { if (trains.isEmpty()) {
Terminal.printLine("No train exists"); Terminal.printLine("No train exists");
} else { } else {

View File

@ -36,7 +36,7 @@ public class PutTrain extends Command {
private Vector2D direction; private Vector2D direction;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
if (point == null) { if (point == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
@ -52,7 +52,7 @@ public class PutTrain extends Command {
if (input == null || !input.startsWith(PUT_TRAIN)) { if (input == null || !input.startsWith(PUT_TRAIN)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = PUT_TRAIN_ARGUMENTS.matcher(input.substring(PUT_TRAIN.length())); final Matcher matcher = PUT_TRAIN_ARGUMENTS.matcher(input.substring(PUT_TRAIN.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid put train arguments"); throw new InvalidInputException("invalid put train arguments");
} }

View File

@ -32,7 +32,7 @@ public class SetSwitch extends Command {
private Vector2D point; private Vector2D point;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) { public void apply(ModelRailwaySimulation simulation) {
if (point == null) { if (point == null) {
throw new IllegalStateException("command not initialized"); throw new IllegalStateException("command not initialized");
} }
@ -48,7 +48,7 @@ public class SetSwitch extends Command {
if (input == null || !input.startsWith(SET_SWITCH)) { if (input == null || !input.startsWith(SET_SWITCH)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
Matcher matcher = SET_SWITCH_ARGUMENTS.matcher(input.substring(SET_SWITCH.length())); final Matcher matcher = SET_SWITCH_ARGUMENTS.matcher(input.substring(SET_SWITCH.length()));
if (!matcher.matches()) { if (!matcher.matches()) {
throw new InvalidInputException("invalid set switch argument syntax"); throw new InvalidInputException("invalid set switch argument syntax");
} }

View File

@ -20,7 +20,7 @@ public class ShowTrain extends Command {
private int id; private int id;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
simulation.showTrain(id).forEach(Terminal::printLine); simulation.showTrain(id).forEach(Terminal::printLine);
} }
@ -29,7 +29,7 @@ public class ShowTrain extends Command {
if (input == null || !input.startsWith(SHOW_TRAIN)) { if (input == null || !input.startsWith(SHOW_TRAIN)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
String argument = input.substring(SHOW_TRAIN.length()); final String argument = input.substring(SHOW_TRAIN.length());
if (!argument.matches(" " + NUMBER)) { if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid show train argument"); throw new InvalidInputException("invalid show train argument");
} }

View File

@ -3,6 +3,7 @@ package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation; import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException; import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
import static edu.kit.informatik.ui.command.CommandFactory.STEP; import static edu.kit.informatik.ui.command.CommandFactory.STEP;
/** /**
@ -18,7 +19,7 @@ public class Step extends Command {
private short speed; private short speed;
@Override @Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException { public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
simulation.step(speed); simulation.step(speed);
} }
@ -27,8 +28,8 @@ public class Step extends Command {
if (input == null || !input.startsWith(STEP)) { if (input == null || !input.startsWith(STEP)) {
throw new InvalidInputException("unknown command"); throw new InvalidInputException("unknown command");
} }
String argument = input.substring(STEP.length()); final String argument = input.substring(STEP.length());
if (!argument.matches(" [+-]?\\d+")) { if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid step argument"); throw new InvalidInputException("invalid step argument");
} }
speed = Short.parseShort(argument.substring(1)); speed = Short.parseShort(argument.substring(1));