mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final1.git
synced 2024-11-09 02:10:40 +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
|
||||
* @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);
|
||||
}
|
||||
|
||||
@ -68,9 +68,9 @@ public class ModelRailwaySimulation {
|
||||
* @param id identifier of the rail to remove
|
||||
* @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
|
||||
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
|
||||
* @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);
|
||||
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;
|
||||
}
|
||||
@ -101,7 +101,7 @@ public class ModelRailwaySimulation {
|
||||
* @param newEngine the engine to add to the simulation
|
||||
* @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();
|
||||
if (Stream.concat(engines.stream(), trainSets.stream())
|
||||
.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
|
||||
* @throws InvalidInputException if user input is invalid (e.g. zero-sized coach)
|
||||
*/
|
||||
public int createCoach(final CoachType coachType, final int length,
|
||||
final boolean couplingFront, final boolean couplingBack) throws InvalidInputException {
|
||||
public int createCoach(CoachType coachType, int length,
|
||||
boolean couplingFront, boolean couplingBack) throws InvalidInputException {
|
||||
int id = getNextCoachIdentifier();
|
||||
if (id < 0) {
|
||||
return -1;
|
||||
@ -187,7 +187,7 @@ public class ModelRailwaySimulation {
|
||||
* @param newTrainSet the train set to add
|
||||
* @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();
|
||||
if (Stream.concat(engines.stream(), trainSets.stream())
|
||||
.anyMatch(rollingStock -> rollingStock.getIdentifier().equals(id))) {
|
||||
@ -216,7 +216,7 @@ public class ModelRailwaySimulation {
|
||||
* @param id identifier of the rolling stock to remove
|
||||
* @return whether the rolling was successfully removed
|
||||
*/
|
||||
public boolean deleteRollingStock(final String id) {
|
||||
public boolean deleteRollingStock(String id) {
|
||||
RollingStock rollingStock = getRollingStock(id);
|
||||
if (trainManager.getTrainContainingRollingStock(rollingStock).isPresent()) {
|
||||
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
|
||||
* @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()) {
|
||||
int coachId = Integer.parseInt(id.substring(1));
|
||||
return coaches.get(coachId);
|
||||
@ -290,7 +290,7 @@ public class ModelRailwaySimulation {
|
||||
* @return whether the train was successfully placed
|
||||
* @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 {
|
||||
return trainManager.putTrain(trainId, position, direction);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package edu.kit.informatik.model;
|
||||
|
||||
import edu.kit.informatik.ui.InvalidInputException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
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.
|
||||
* @param id identifier of the rail to remove
|
||||
@ -236,7 +246,7 @@ public class RailwayNetwork {
|
||||
* @param position the position to check
|
||||
* @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);
|
||||
}
|
||||
|
||||
@ -245,7 +255,7 @@ public class RailwayNetwork {
|
||||
* @param position the position to check
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
* 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
|
||||
*/
|
||||
public boolean isOnRail(final int id) {
|
||||
return isPlaced() && occupiedRails.stream().anyMatch(rail -> rail.getIdentifier() == id);
|
||||
public boolean isOnRail(final Rail rail) {
|
||||
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.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
public boolean anyTrainOnRail(int id) {
|
||||
return trains.values().stream().anyMatch(train -> train.isOnRail(id));
|
||||
public boolean anyTrainOnRail(Rail rail) {
|
||||
return rail != null && trains.values().stream().anyMatch(train -> train.isOnRail(rail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
trains.values().stream().filter(train -> train.isOnRail(id)).forEach(Train::removeFromRails);
|
||||
public void removeTrainsOnRail(Rail rail) {
|
||||
trains.values().stream().filter(train -> train.isOnRail(rail)).forEach(Train::removeFromRails);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,9 +166,7 @@ public final class TrainManager {
|
||||
// attempt to place train
|
||||
boolean placed = train.placeOn(railNetwork, position, direction);
|
||||
// check for collisions
|
||||
List<Set<Train>> collisions = new ArrayList<>();
|
||||
getStaticCollisions(collisions);
|
||||
if (placed && !collisions.isEmpty()) { // TODO: implement 2B
|
||||
if (placed && !getPlacementCollisions().isEmpty()) {
|
||||
train.removeFromRails();
|
||||
return false;
|
||||
} else {
|
||||
@ -211,6 +210,11 @@ public final class TrainManager {
|
||||
.filter(Train::isPlaced)
|
||||
.filter(train -> train.getOccupiedRails().stream().anyMatch(occupiedRails::contains))
|
||||
.forEach(collision::add);
|
||||
if (!collision.isEmpty()) {
|
||||
collision.add(train1);
|
||||
addToSetOrAddNew(collisions, collision);
|
||||
}
|
||||
/*
|
||||
if (!collision.isEmpty()) {
|
||||
// check for existing collision
|
||||
Set<Train> otherCollision = collisions.stream()
|
||||
@ -224,6 +228,54 @@ public final class TrainManager {
|
||||
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