mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final1.git
synced 2024-11-24 09:24:58 +00:00
Implement model 2B
This commit is contained in:
parent
c11fadbb9d
commit
5267177f4e
@ -59,7 +59,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @return the positive identifier of the switch if successful, -1 otherwise
|
* @return the positive identifier of the switch if successful, -1 otherwise
|
||||||
* @throws InvalidInputException if the new switch would be invalid
|
* @throws InvalidInputException if the new switch would be invalid
|
||||||
*/
|
*/
|
||||||
public int addSwitch(final Vector2D start, final Vector2D end1, final Vector2D end2) throws InvalidInputException {
|
public int addSwitch(Vector2D start, Vector2D end1, Vector2D end2) throws InvalidInputException {
|
||||||
return railNetwork.addSwitch(start, end1, end2);
|
return railNetwork.addSwitch(start, end1, end2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,9 +68,9 @@ public class ModelRailwaySimulation {
|
|||||||
* @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
|
||||||
*/
|
*/
|
||||||
public boolean removeRail(final int id) {
|
public boolean removeRail(int id) {
|
||||||
// check whether any trains are on this rail
|
// check whether any trains are on this rail
|
||||||
return !trainManager.anyTrainOnRail(id) && railNetwork.removeRail(id);
|
return !trainManager.anyTrainOnRail(railNetwork.getRail(id)) && railNetwork.removeRail(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,10 +89,10 @@ public class ModelRailwaySimulation {
|
|||||||
* @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) {
|
||||||
boolean success = railNetwork.setSwitch(id, position);
|
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(id);
|
trainManager.removeTrainsOnRail(railNetwork.getRail(id));
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @param newEngine the engine to add to the simulation
|
* @param newEngine the engine to add to the simulation
|
||||||
* @throws InvalidInputException when the identifier is already in use
|
* @throws InvalidInputException when the identifier is already in use
|
||||||
*/
|
*/
|
||||||
public void createEngine(final Engine newEngine) throws InvalidInputException {
|
public void createEngine(Engine newEngine) throws InvalidInputException {
|
||||||
String id = newEngine.getIdentifier();
|
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))) {
|
||||||
@ -134,8 +134,8 @@ public class ModelRailwaySimulation {
|
|||||||
* @return the identifier of the coach if successfully added, -1 if none available
|
* @return the identifier of the coach if successfully added, -1 if none available
|
||||||
* @throws InvalidInputException if user input is invalid (e.g. zero-sized coach)
|
* @throws InvalidInputException if user input is invalid (e.g. zero-sized coach)
|
||||||
*/
|
*/
|
||||||
public int createCoach(final CoachType coachType, final int length,
|
public int createCoach(CoachType coachType, int length,
|
||||||
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException {
|
boolean couplingFront, boolean couplingBack) throws InvalidInputException {
|
||||||
int id = getNextCoachIdentifier();
|
int id = getNextCoachIdentifier();
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -187,7 +187,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @param newTrainSet the train set to add
|
* @param newTrainSet the train set to add
|
||||||
* @throws InvalidInputException if the identifier is already used
|
* @throws InvalidInputException if the identifier is already used
|
||||||
*/
|
*/
|
||||||
public void createTrainSet(final TrainSet newTrainSet) throws InvalidInputException {
|
public void createTrainSet(TrainSet newTrainSet) throws InvalidInputException {
|
||||||
String id = newTrainSet.getIdentifier();
|
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))) {
|
||||||
@ -216,7 +216,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @param id identifier of the rolling stock to remove
|
* @param id identifier of the rolling stock to remove
|
||||||
* @return whether the rolling was successfully removed
|
* @return whether the rolling was successfully removed
|
||||||
*/
|
*/
|
||||||
public boolean deleteRollingStock(final String id) {
|
public boolean deleteRollingStock(String id) {
|
||||||
RollingStock rollingStock = getRollingStock(id);
|
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
|
||||||
@ -229,7 +229,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @param id identifier of the rolling stock to find
|
* @param id identifier of the rolling stock to find
|
||||||
* @return the specified rolling stock, or null if not found
|
* @return the specified rolling stock, or null if not found
|
||||||
*/
|
*/
|
||||||
public RollingStock getRollingStock(final 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));
|
int coachId = Integer.parseInt(id.substring(1));
|
||||||
return coaches.get(coachId);
|
return coaches.get(coachId);
|
||||||
@ -290,7 +290,7 @@ public class ModelRailwaySimulation {
|
|||||||
* @return whether the train was successfully placed
|
* @return whether the train was successfully placed
|
||||||
* @throws InvalidInputException when the train is too long
|
* @throws InvalidInputException when the train is too long
|
||||||
*/
|
*/
|
||||||
public boolean putTrain(final int trainId, final Vector2D position, final Vector2D direction)
|
public boolean putTrain(int trainId, Vector2D position, Vector2D direction)
|
||||||
throws InvalidInputException {
|
throws InvalidInputException {
|
||||||
return trainManager.putTrain(trainId, position, direction);
|
return trainManager.putTrain(trainId, position, direction);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package edu.kit.informatik.model;
|
|||||||
|
|
||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -97,6 +98,15 @@ public class RailwayNetwork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the rail with the specified identifier.
|
||||||
|
* @param id rail identifier to get
|
||||||
|
* @return the rail, or null if not found
|
||||||
|
*/
|
||||||
|
public Rail getRail(int id) {
|
||||||
|
return rails.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@ -236,7 +246,7 @@ public class RailwayNetwork {
|
|||||||
* @param position the position to check
|
* @param position the position to check
|
||||||
* @return the rail that contains the position, null if none found
|
* @return the rail that contains the position, null if none found
|
||||||
*/
|
*/
|
||||||
public Rail findContainingRail(final Vector2D position) {
|
public Rail findContainingRail(Vector2D position) {
|
||||||
return rails.values().stream().filter(rail -> rail.contains(position)).findFirst().orElse(null);
|
return rails.values().stream().filter(rail -> rail.contains(position)).findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +255,7 @@ public class RailwayNetwork {
|
|||||||
* @param position the position to check
|
* @param position the position to check
|
||||||
* @return the rail(s) that touch this position
|
* @return the rail(s) that touch this position
|
||||||
*/
|
*/
|
||||||
public Rail[] findTouchingRails(final Vector2D position) {
|
public Rail[] findTouchingRails(Vector2D position) {
|
||||||
return rails.values().stream().filter(rail -> rail.canConnectTo(position)).toArray(Rail[]::new);
|
return rails.values().stream().filter(rail -> rail.canConnectTo(position)).toArray(Rail[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,11 +126,12 @@ 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. Note that at least one rolling stock has to be on the rail,
|
||||||
* just touching the rail is not enough.
|
* just touching the rail is not enough.
|
||||||
* @param id identifier of a rail
|
* @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(final int id) {
|
public boolean isOnRail(final Rail rail) {
|
||||||
return isPlaced() && occupiedRails.stream().anyMatch(rail -> rail.getIdentifier() == id);
|
return isPlaced() && (occupiedRails.stream().anyMatch(blockedRail -> blockedRail == rail)
|
||||||
|
|| position.stream().anyMatch(rail::canConnectTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,6 +5,7 @@ import edu.kit.informatik.ui.InvalidInputException;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
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.HashSet;
|
||||||
@ -47,19 +48,19 @@ 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 id identfier of 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
|
||||||
*/
|
*/
|
||||||
public boolean anyTrainOnRail(int id) {
|
public boolean anyTrainOnRail(Rail rail) {
|
||||||
return trains.values().stream().anyMatch(train -> train.isOnRail(id));
|
return rail != null && trains.values().stream().anyMatch(train -> train.isOnRail(rail));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove any trains on the rail with the specified identifier.
|
* Remove any trains on the rail with the specified identifier.
|
||||||
* @param id identifier of the rail
|
* @param rail rail to clear
|
||||||
*/
|
*/
|
||||||
public void removeTrainsOnRail(int id) {
|
public void removeTrainsOnRail(Rail rail) {
|
||||||
trains.values().stream().filter(train -> train.isOnRail(id)).forEach(Train::removeFromRails);
|
trains.values().stream().filter(train -> train.isOnRail(rail)).forEach(Train::removeFromRails);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,9 +166,7 @@ public final class TrainManager {
|
|||||||
// attempt to place train
|
// attempt to place train
|
||||||
boolean placed = train.placeOn(railNetwork, position, direction);
|
boolean placed = train.placeOn(railNetwork, position, direction);
|
||||||
// check for collisions
|
// check for collisions
|
||||||
List<Set<Train>> collisions = new ArrayList<>();
|
if (placed && !getPlacementCollisions().isEmpty()) {
|
||||||
getStaticCollisions(collisions);
|
|
||||||
if (placed && !collisions.isEmpty()) { // TODO: implement 2B
|
|
||||||
train.removeFromRails();
|
train.removeFromRails();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -211,6 +210,11 @@ public final class TrainManager {
|
|||||||
.filter(Train::isPlaced)
|
.filter(Train::isPlaced)
|
||||||
.filter(train -> train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
|
.filter(train -> train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
|
||||||
.forEach(collision::add);
|
.forEach(collision::add);
|
||||||
|
if (!collision.isEmpty()) {
|
||||||
|
collision.add(train1);
|
||||||
|
addToSetOrAddNew(collisions, collision);
|
||||||
|
}
|
||||||
|
/*
|
||||||
if (!collision.isEmpty()) {
|
if (!collision.isEmpty()) {
|
||||||
// check for existing collision
|
// check for existing collision
|
||||||
Set<Train> otherCollision = collisions.stream()
|
Set<Train> otherCollision = collisions.stream()
|
||||||
@ -224,6 +228,54 @@ public final class TrainManager {
|
|||||||
collisions.add(collision);
|
collisions.add(collision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the silly *second* collision checking algorithm.
|
||||||
|
* @return list of collisions
|
||||||
|
*/
|
||||||
|
private List<Set<Train>> getPlacementCollisions() {
|
||||||
|
List<Set<Train>> collisions = new ArrayList<>();
|
||||||
|
trains.values().stream().filter(Train::isPlaced).forEach(train1 -> {
|
||||||
|
trains.values().stream().filter(train -> train != train1).filter(Train::isPlaced).forEach(train2 -> {
|
||||||
|
Set<Rail> occupiedByTrain1 = train1.getOccupiedRails();
|
||||||
|
Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getFrontPosition()));
|
||||||
|
Collections.addAll(occupiedByTrain1, railNetwork.findTouchingRails(train1.getRearPosition()));
|
||||||
|
Set<Rail> occupiedByTrain2 = train2.getOccupiedRails();
|
||||||
|
Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getFrontPosition()));
|
||||||
|
Collections.addAll(occupiedByTrain2, railNetwork.findTouchingRails(train2.getRearPosition()));
|
||||||
|
occupiedByTrain2.retainAll(occupiedByTrain1);
|
||||||
|
if (!occupiedByTrain2.isEmpty()) {
|
||||||
|
Set<Train> collision = Stream.of(train1, train2).collect(Collectors.toSet());
|
||||||
|
addToSetOrAddNew(collisions, collision);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return collisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
Set<Train> existing = null;
|
||||||
|
for (int i = 0; i < setList.size(); i++) {
|
||||||
|
Set<Train> otherSet = setList.get(i);
|
||||||
|
if (otherSet.stream().anyMatch(newSet::contains)) {
|
||||||
|
if (existing == null) {
|
||||||
|
existing = otherSet;
|
||||||
|
existing.addAll(newSet);
|
||||||
|
} else {
|
||||||
|
existing.addAll(otherSet);
|
||||||
|
setList.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (existing == null) {
|
||||||
|
setList.add(newSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user