mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final1.git
synced 2024-11-27 18:55:55 +00:00
Move step output in UI
This commit is contained in:
parent
54708c2198
commit
0e298492a3
@ -9,6 +9,8 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.SortedSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -66,6 +68,7 @@ public class ModelRailwaySimulation {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the specified rail from the rail network.
|
* Remove the specified rail from the rail network.
|
||||||
|
*
|
||||||
* @param id identifier of the rail to remove
|
* @param id identifier of the rail to remove
|
||||||
* @return whether the rail could be successfully removed
|
* @return whether the rail could be successfully removed
|
||||||
*/
|
*/
|
||||||
@ -275,12 +278,22 @@ public class ModelRailwaySimulation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of trains (their text representation) in the simulation.
|
* Get the trains (their text representation) in the simulation.
|
||||||
*
|
*
|
||||||
* @return list of trains
|
* @return sorted collection of trains
|
||||||
*/
|
*/
|
||||||
public List<String> listTrains() {
|
public SortedMap<Integer, String> getTrains() {
|
||||||
return trainManager.listTrains();
|
return trainManager.getTrains();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the front position of a train.
|
||||||
|
*
|
||||||
|
* @param trainId train identifier
|
||||||
|
* @return position of the train, or null if not found or placed
|
||||||
|
*/
|
||||||
|
public Vector2D getTrainPosition(int trainId) {
|
||||||
|
return trainManager.getPosition(trainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -307,11 +320,13 @@ public class ModelRailwaySimulation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the trains in this simulation, printing their new positions and any collisions.
|
* Move the trains in this simulation.
|
||||||
|
*
|
||||||
* @param speed amount of steps to move the trains
|
* @param speed amount of steps to move the trains
|
||||||
|
* @return train collisions, null if no trains are placed
|
||||||
* @throws InvalidInputException if the simulation is not yet ready
|
* @throws InvalidInputException if the simulation is not yet ready
|
||||||
*/
|
*/
|
||||||
public void step(short speed) throws InvalidInputException {
|
public List<SortedSet<Integer>> step(short speed) throws InvalidInputException {
|
||||||
trainManager.step(speed);
|
return trainManager.step(speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,7 @@ import java.util.stream.Collectors;
|
|||||||
* @author Arne Keller
|
* @author Arne Keller
|
||||||
* @version 1.1
|
* @version 1.1
|
||||||
*/
|
*/
|
||||||
public final class Train {
|
public final class Train implements Comparable {
|
||||||
/**
|
/**
|
||||||
* Separator between rolling stocks in {@link #show()}.
|
* Separator between rolling stocks in {@link #show()}.
|
||||||
*/
|
*/
|
||||||
@ -85,13 +85,14 @@ public final class Train {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether this train is on a particular rail. Note that at least one rolling stock has to be on the rail,
|
* Check whether this train is on a particular rail. Just touching the rail is enough.
|
||||||
* just touching the rail is not enough.
|
*
|
||||||
* @param rail the rail to check
|
* @param rail the rail to check
|
||||||
* @return whether this train is on that rail
|
* @return whether this train is on that rail
|
||||||
*/
|
*/
|
||||||
public boolean isOnRail(Rail rail) {
|
public boolean isOnRail(Rail rail) {
|
||||||
return isPlaced() && (occupiedRails.stream().anyMatch(blockedRail -> blockedRail == rail)
|
return isPlaced()
|
||||||
|
&& (occupiedRails.stream().anyMatch(blockedRail -> blockedRail == rail)
|
||||||
|| positions.stream().anyMatch(rail::canConnectTo));
|
|| positions.stream().anyMatch(rail::canConnectTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,4 +368,9 @@ public final class Train {
|
|||||||
}
|
}
|
||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Object o) {
|
||||||
|
return Integer.compare(this.identifier, ((Train) o).identifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
package edu.kit.informatik.model;
|
package edu.kit.informatik.model;
|
||||||
|
|
||||||
import edu.kit.informatik.Terminal;
|
|
||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static edu.kit.informatik.ui.CommandLine.OK;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Train manager, used for processing train placements and movement on a rail network.
|
* Train manager, used for processing train placements and movement on a rail network.
|
||||||
*
|
*
|
||||||
@ -32,7 +31,7 @@ public final class TrainManager {
|
|||||||
*/
|
*/
|
||||||
private final RailwayNetwork railNetwork;
|
private final RailwayNetwork railNetwork;
|
||||||
/**
|
/**
|
||||||
* Map of trains simulated.
|
* Map of trains simulated. The train identifier is used as key.
|
||||||
*/
|
*/
|
||||||
private final Map<Integer, Train> trains = new HashMap<>();
|
private final Map<Integer, Train> trains = new HashMap<>();
|
||||||
|
|
||||||
@ -46,8 +45,8 @@ 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. Trains only touching the end of the rail
|
||||||
* rail, simply touching one of the end points is not enough.
|
* will also be considered.
|
||||||
*
|
*
|
||||||
* @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
|
||||||
@ -87,21 +86,31 @@ public final class TrainManager {
|
|||||||
throw new InvalidInputException("rolling stock already used");
|
throw new InvalidInputException("rolling stock already used");
|
||||||
}
|
}
|
||||||
final Train train = trains.get(trainId);
|
final Train train = trains.get(trainId);
|
||||||
if (train != null && train.isPlaced()) {
|
if (train == null) { // create new train
|
||||||
throw new InvalidInputException("can not add rolling stock to placed train");
|
|
||||||
}
|
|
||||||
if (train != null) {
|
|
||||||
train.add(rollingStock);
|
|
||||||
} else {
|
|
||||||
final 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");
|
||||||
}
|
}
|
||||||
final Train newTrain = new Train(trainId, rollingStock);
|
final Train newTrain = new Train(trainId, rollingStock);
|
||||||
trains.put(trainId, newTrain);
|
trains.put(trainId, newTrain);
|
||||||
|
} else {
|
||||||
|
if (train.isPlaced()) {
|
||||||
|
throw new InvalidInputException("can not add rolling stock to placed train");
|
||||||
|
}
|
||||||
|
train.add(rollingStock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the next available train identifier. Will fill 'holes' in the identifier list first.
|
||||||
|
*
|
||||||
|
* @return the next train identifier, or -1 if none available
|
||||||
|
*/
|
||||||
|
private int getNextTrainIdentifier() {
|
||||||
|
return IntStream.rangeClosed(1, Integer.MAX_VALUE)
|
||||||
|
.filter(id -> !trains.containsKey(id)).findFirst().orElse(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a train. Will not delete rolling stock contained in that train.
|
* Delete a train. Will not delete rolling stock contained in that train.
|
||||||
*
|
*
|
||||||
@ -118,20 +127,20 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a sorted list of trains (their text representation) in the simulation.
|
* Get the trains (their text representation) in the simulation.
|
||||||
*
|
*
|
||||||
* @return list of trains
|
* @return sorted collection of trains
|
||||||
*/
|
*/
|
||||||
public List<String> listTrains() {
|
public SortedMap<Integer, String> getTrains() {
|
||||||
return trains.keySet().stream()
|
return trains.keySet().stream()
|
||||||
.sorted()
|
.sorted()
|
||||||
.map(trains::get)
|
.map(trains::get)
|
||||||
.map(Object::toString)
|
.collect(Collectors.toMap(Train::getIdentifier, Object::toString, (id1, id2) -> id1, TreeMap::new));
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ASCII art representation of a train.
|
* Get the ASCII art representation of a train.
|
||||||
|
*
|
||||||
* @param trainId identifier of the train to show
|
* @param trainId identifier of the train to show
|
||||||
* @return ASCII art representation of said train
|
* @return ASCII art representation of said train
|
||||||
* @throws InvalidInputException if train not found
|
* @throws InvalidInputException if train not found
|
||||||
@ -179,19 +188,12 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the next available train identifier.
|
* Get collisions of trains currently placed. This implements the first collision checking algorithm (1A):
|
||||||
* @return the next train identifier, or -1 if none available
|
* trains collide if they partially occupy the same rail or touch each other.
|
||||||
|
*
|
||||||
|
* @param collisions list of collisions to expand
|
||||||
*/
|
*/
|
||||||
private int getNextTrainIdentifier() {
|
private void getStaticCollisions(List<SortedSet<Train>> collisions) {
|
||||||
return IntStream.rangeClosed(1, Integer.MAX_VALUE)
|
|
||||||
.filter(id -> !trains.containsKey(id)).findFirst().orElse(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get collisions of trains currently placed.
|
|
||||||
* @param collisions list of collisions (never null, sometimes empty)
|
|
||||||
*/
|
|
||||||
private void getStaticCollisions(List<Set<Train>> collisions) {
|
|
||||||
final int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0);
|
final int maxId = trains.keySet().stream().max(Integer::compareTo).orElse(0);
|
||||||
for (int id = 1; id <= maxId; id++) {
|
for (int id = 1; id <= maxId; id++) {
|
||||||
final Train train1 = trains.get(id);
|
final Train train1 = trains.get(id);
|
||||||
@ -200,13 +202,13 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
final Set<Rail> occupiedRails = train1.getOccupiedRails();
|
final Set<Rail> occupiedRails = train1.getOccupiedRails();
|
||||||
// check for same position, and rail collisions
|
// check for same position, and rail collisions
|
||||||
final Set<Train> collision = IntStream.rangeClosed(id + 1, maxId)
|
final SortedSet<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(train -> train1.touches(train)
|
.filter(train -> train1.touches(train)
|
||||||
|| train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
|
|| train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toCollection(TreeSet::new));
|
||||||
if (!collision.isEmpty()) {
|
if (!collision.isEmpty()) {
|
||||||
collision.add(train1);
|
collision.add(train1);
|
||||||
addToSetOrAddNew(collisions, collision);
|
addToSetOrAddNew(collisions, collision);
|
||||||
@ -215,15 +217,15 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the silly *second* collision checking algorithm.
|
* Implementation of the silly second collision checking algorithm (2B):
|
||||||
* Will put two trains in a collision even if they only touch the same rail.
|
* two trains collide if they touch the same rail or position.
|
||||||
*
|
*
|
||||||
* @return list of collisions
|
* @return list of collisions
|
||||||
*/
|
*/
|
||||||
private List<Set<Train>> getPlacementCollisions() {
|
private List<SortedSet<Train>> getPlacementCollisions() {
|
||||||
final List<Set<Train>> collisions = new ArrayList<>();
|
final List<SortedSet<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::isPlaced).forEach(train2 -> {
|
trains.values().stream().filter(train -> train != train1).filter(Train::isPlaced).forEach(train2 -> {
|
||||||
final 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()));
|
||||||
@ -233,7 +235,8 @@ public final class TrainManager {
|
|||||||
// calculate intersection
|
// calculate intersection
|
||||||
occupiedByTrain2.retainAll(occupiedByTrain1);
|
occupiedByTrain2.retainAll(occupiedByTrain1);
|
||||||
if (!occupiedByTrain2.isEmpty()) {
|
if (!occupiedByTrain2.isEmpty()) {
|
||||||
final Set<Train> collision = Stream.of(train1, train2).collect(Collectors.toSet());
|
final SortedSet<Train> collision
|
||||||
|
= Stream.of(train1, train2).collect(Collectors.toCollection(TreeSet::new));
|
||||||
addToSetOrAddNew(collisions, collision);
|
addToSetOrAddNew(collisions, collision);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@ -243,7 +246,7 @@ public final class TrainManager {
|
|||||||
/**
|
/**
|
||||||
* Add the set to an existing set (and merge sets), or add it to the list.
|
* Add the set to an existing set (and merge sets), or add it to the list.
|
||||||
*/
|
*/
|
||||||
private void addToSetOrAddNew(List<Set<Train>> setList, Set<Train> newSet) {
|
private void addToSetOrAddNew(List<SortedSet<Train>> setList, SortedSet<Train> newSet) {
|
||||||
Set<Train> existing = null;
|
Set<Train> existing = null;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < setList.size()) {
|
while (i < setList.size()) {
|
||||||
@ -265,13 +268,23 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the front position of the specified train.
|
||||||
|
*
|
||||||
|
* @param trainId train identifier
|
||||||
|
* @return front position of that train
|
||||||
|
*/
|
||||||
|
public Vector2D getPosition(int trainId) {
|
||||||
|
return trains.get(trainId).getFrontPosition();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get collisions of moving the trains one step forward, removing crashing trains from the rails in the process.
|
* 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<SortedSet<Train>> getCollisionsOfOneStep() {
|
||||||
final List<Set<Train>> collisions = new ArrayList<>();
|
final List<SortedSet<Train>> collisions = new ArrayList<>();
|
||||||
trains.values().stream().filter(Train::isPlaced).forEach(train -> {
|
trains.values().stream().filter(Train::isPlaced).forEach(train -> {
|
||||||
final Vector2D position = train.getFrontPosition();
|
final Vector2D position = train.getFrontPosition();
|
||||||
final Vector2D direction = train.getDirection();
|
final Vector2D direction = train.getDirection();
|
||||||
@ -279,7 +292,7 @@ public final class TrainManager {
|
|||||||
if (nextPosition == null || nextPosition.equals(position)) {
|
if (nextPosition == null || nextPosition.equals(position)) {
|
||||||
// train is derailing
|
// train is derailing
|
||||||
train.moveTo(railNetwork, null);
|
train.moveTo(railNetwork, null);
|
||||||
collisions.add(new HashSet<>(Arrays.asList(train)));
|
collisions.add(Stream.of(train).collect(Collectors.toCollection(TreeSet::new)));
|
||||||
} else {
|
} else {
|
||||||
// train is moving successfully
|
// train is moving successfully
|
||||||
train.moveTo(railNetwork, nextPosition);
|
train.moveTo(railNetwork, nextPosition);
|
||||||
@ -295,8 +308,8 @@ public final class TrainManager {
|
|||||||
*
|
*
|
||||||
* @return list of collisions (never null, sometimes empty)
|
* @return list of collisions (never null, sometimes empty)
|
||||||
*/
|
*/
|
||||||
private List<Set<Train>> getCollisionsOfOneReverseStep() {
|
private List<SortedSet<Train>> getCollisionsOfOneReverseStep() {
|
||||||
final List<Set<Train>> collisions = new ArrayList<>();
|
final List<SortedSet<Train>> collisions = new ArrayList<>();
|
||||||
// perform step
|
// perform step
|
||||||
trains.values().stream().filter(Train::isPlaced).forEach(train -> {
|
trains.values().stream().filter(Train::isPlaced).forEach(train -> {
|
||||||
final Vector2D position = train.getRearPosition();
|
final Vector2D position = train.getRearPosition();
|
||||||
@ -305,7 +318,7 @@ public final class TrainManager {
|
|||||||
if (nextPosition == null || nextPosition.equals(position)) {
|
if (nextPosition == null || nextPosition.equals(position)) {
|
||||||
// derailing
|
// derailing
|
||||||
train.moveBackTo(railNetwork, nextPosition);
|
train.moveBackTo(railNetwork, nextPosition);
|
||||||
collisions.add(new HashSet<>(Arrays.asList(train)));
|
collisions.add(Stream.of(train).collect(Collectors.toCollection(TreeSet::new)));
|
||||||
} else {
|
} else {
|
||||||
// train moving successfully
|
// train moving successfully
|
||||||
train.moveBackTo(railNetwork, nextPosition);
|
train.moveBackTo(railNetwork, nextPosition);
|
||||||
@ -317,42 +330,27 @@ public final class TrainManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the trains in this simulation, printing their new positions and any collisions.
|
* Move the trains in this simulation.
|
||||||
|
*
|
||||||
* @param speed amount of steps to move the trains
|
* @param speed amount of steps to move the trains
|
||||||
|
* @return train collisions, null if no trains are placed
|
||||||
* @throws InvalidInputException if simulation is not yet ready
|
* @throws InvalidInputException if simulation is not yet ready
|
||||||
*/
|
*/
|
||||||
public void step(short speed) throws InvalidInputException {
|
public List<SortedSet<Integer>> step(short speed) throws InvalidInputException {
|
||||||
if (!railNetwork.isReadyForTrains()) {
|
if (!railNetwork.isReadyForTrains()) {
|
||||||
throw new InvalidInputException("rail tracks/switches not set up");
|
throw new InvalidInputException("rail tracks/switches not set up");
|
||||||
}
|
}
|
||||||
if (trains.values().stream().noneMatch(Train::isPlaced)) {
|
if (trains.values().stream().noneMatch(Train::isPlaced)) {
|
||||||
Terminal.printLine(OK);
|
return null;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Set<Train>> collisions = IntStream.range(0, Math.abs(speed))
|
return IntStream.range(0, Math.abs(speed))
|
||||||
.mapToObj(step -> speed >= 0 ? getCollisionsOfOneStep() : getCollisionsOfOneReverseStep())
|
.mapToObj(step -> speed >= 0 ? getCollisionsOfOneStep() : getCollisionsOfOneReverseStep())
|
||||||
.flatMap(List::stream).collect(Collectors.toList());
|
// replace train references with identifiers to prevent modification by caller
|
||||||
|
.flatMap(collisions -> collisions.stream()
|
||||||
for (final int id : trains.keySet().stream().sorted().collect(Collectors.toList())) {
|
.map(collision -> collision.stream().map(Train::getIdentifier)
|
||||||
final Train train = trains.get(id);
|
.collect(Collectors.toCollection(TreeSet::new))))
|
||||||
final Set<Train> collisionSet = collisions.stream()
|
.sorted(Comparator.comparing(TreeSet::first))
|
||||||
.filter(collision -> collision.contains(train))
|
.collect(Collectors.toList());
|
||||||
.findFirst().orElse(null);
|
|
||||||
if (collisionSet != null) { // print collision
|
|
||||||
final int first = collisionSet.stream()
|
|
||||||
.min(Comparator.comparing(Train::getIdentifier)).get().getIdentifier();
|
|
||||||
if (train.getIdentifier() == first) { // only print each collision once
|
|
||||||
final List<Train> collision = collisionSet.stream()
|
|
||||||
.sorted(Comparator.comparing(Train::getIdentifier))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
Terminal.printLine("Crash of train " + String.join(",", collision.stream()
|
|
||||||
.map(crashedTrain -> Integer.toString(crashedTrain.getIdentifier()))
|
|
||||||
.toArray(String[]::new)));
|
|
||||||
}
|
|
||||||
} else if (train.isPlaced()) { // or position, if not in collision
|
|
||||||
Terminal.printLine(String.format("Train %d at %s", train.getIdentifier(), train.getFrontPosition()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import edu.kit.informatik.Terminal;
|
|||||||
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 java.util.List;
|
import java.util.SortedMap;
|
||||||
|
|
||||||
import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAINS;
|
import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAINS;
|
||||||
|
|
||||||
@ -17,11 +17,11 @@ 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(ModelRailwaySimulation simulation) {
|
public void apply(ModelRailwaySimulation simulation) {
|
||||||
final List<String> trains = simulation.listTrains();
|
final SortedMap<Integer, String> trains = simulation.getTrains();
|
||||||
if (trains.isEmpty()) {
|
if (trains.isEmpty()) {
|
||||||
Terminal.printLine("No train exists");
|
Terminal.printLine("No train exists");
|
||||||
} else {
|
} else {
|
||||||
trains.forEach(Terminal::printLine);
|
trains.values().forEach(Terminal::printLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package edu.kit.informatik.ui.command;
|
package edu.kit.informatik.ui.command;
|
||||||
|
|
||||||
|
import edu.kit.informatik.Terminal;
|
||||||
import edu.kit.informatik.model.ModelRailwaySimulation;
|
import edu.kit.informatik.model.ModelRailwaySimulation;
|
||||||
|
import edu.kit.informatik.model.Vector2D;
|
||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import static edu.kit.informatik.ui.CommandLine.OK;
|
||||||
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
|
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;
|
||||||
|
|
||||||
@ -20,7 +26,25 @@ public class Step extends Command {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
|
public void apply(ModelRailwaySimulation simulation) throws InvalidInputException {
|
||||||
simulation.step(speed);
|
final List<SortedSet<Integer>> collisions = simulation.step(speed);
|
||||||
|
if (collisions == null) {
|
||||||
|
Terminal.printLine(OK);
|
||||||
|
} else {
|
||||||
|
for (final int id : simulation.getTrains().keySet()) {
|
||||||
|
final SortedSet<Integer> collisionSet = collisions.stream()
|
||||||
|
.filter(collision -> collision.first() == id)
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
if (collisionSet != null) { // print collision
|
||||||
|
Terminal.printLine("Crash of train " + String.join(",",
|
||||||
|
collisionSet.stream().map(Object::toString).toArray(String[]::new)));
|
||||||
|
} else { // or position, if not in collision
|
||||||
|
final Vector2D position = simulation.getTrainPosition(id);
|
||||||
|
if (position != null) { // only print placed trains
|
||||||
|
Terminal.printLine(String.format("Train %d at %s", id, position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user