Correctly handle crashes of more than two trains

This commit is contained in:
Arne Keller 2020-02-18 14:35:39 +01:00
parent 16ddc708ef
commit 302b755ee6
3 changed files with 52 additions and 28 deletions

View File

@ -466,36 +466,42 @@ public class ModelRailwaySimulation {
}
});
// check for block collisions
trains.values().stream().filter(train -> train.isPlaced() && collisions.stream().noneMatch((x) -> x.contains(train))).forEach(train -> {
Set<Rail> occupiedByThisTrain = nextOccupiedRails.get(train);
trains.values().stream().filter((x) -> x != train).forEach((otherTrain) -> {
Set<Rail> occupiedByOtherTrainPreviously = occupiedRails.get(otherTrain);
Set<Rail> occupiedByOtherTrain = nextOccupiedRails.get(otherTrain);
if (occupiedByOtherTrain == null || occupiedByOtherTrainPreviously == null) {
return;
}
boolean anyIntersection = occupiedByOtherTrain.stream().anyMatch(occupiedByThisTrain::contains)
|| occupiedByOtherTrainPreviously.stream().anyMatch(occupiedByThisTrain::contains);
if (anyIntersection) {
train.removeFromRails();
// try to find/merge existing collisions
Set<Train> existingCollision = null;
for (Set<Train> collision : collisions) {
if (collision.contains(otherTrain)) {
trains.values().stream().filter(train -> train.isPlaced()
&& collisions.stream().noneMatch((x) -> x.contains(train))).forEach(train -> {
Set<Rail> occupiedByThisTrain = nextOccupiedRails.get(train);
trains.values().stream().filter((x) -> x != train).forEach((otherTrain) -> {
Set<Rail> occupiedByOtherTrainPreviously = occupiedRails.get(otherTrain);
Set<Rail> occupiedByOtherTrain = nextOccupiedRails.get(otherTrain);
if (occupiedByOtherTrain == null || occupiedByOtherTrainPreviously == null) {
return;
}
boolean anyIntersection = occupiedByOtherTrain.stream().anyMatch(occupiedByThisTrain::contains)
|| occupiedByOtherTrainPreviously.stream().anyMatch(occupiedByThisTrain::contains);
if (anyIntersection) {
train.removeFromRails();
// try to find/merge existing collisions
Set<Train> existingCollision = null;
for (Set<Train> collision : collisions) {
if (collision.contains(otherTrain) || collision.contains(train)) {
if (existingCollision == null) {
existingCollision = collision;
collision.add(train);
collision.add(otherTrain);
} else {
existingCollision.addAll(collision);
existingCollision.add(train);
existingCollision.add(otherTrain);
collisions.remove(collision);
break;
}
}
}
if (existingCollision == null) {
existingCollision = collision;
collision.add(train);
} else {
existingCollision.addAll(collision);
collisions.add(new HashSet<>(Arrays.asList(train, otherTrain)));
}
}
}
if (existingCollision == null) {
collisions.add(new HashSet<>(Arrays.asList(train, otherTrain)));
}
}
});
});
});
});
return collisions;
}

View File

@ -60,4 +60,13 @@ add train 2 T2-Rho
add track (1,0) -> (10,0)
put train 1 at (7,0) in direction -1,0
put train 5 at (0,0) in direction -1,0
step 8
step 8
delete track 1
delete track 2
add track (0,0) -> (10,0)
add track (10,0) -> (20,0)
add track (20,0) -> (30,0)
put train 1 at (10,0) in direction 1,0
put train 2 at (15,0) in direction 1,0
put train 5 at (20,0) in direction -1,0
step 1

View File

@ -78,3 +78,12 @@ OK
OK
Crash of train 1
Crash of train 5
OK
OK
1
2
3
OK
OK
OK
Crash of train 1,2,5