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

View File

@ -61,3 +61,12 @@ add track (1,0) -> (10,0)
put train 1 at (7,0) in direction -1,0 put train 1 at (7,0) in direction -1,0
put train 5 at (0,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 OK
Crash of train 1 Crash of train 1
Crash of train 5 Crash of train 5
OK
OK
1
2
3
OK
OK
OK
Crash of train 1,2,5