Checkstyle and additional test

This commit is contained in:
Arne Keller 2020-03-08 10:37:26 +01:00
parent f0b35e0707
commit a9348c4bdc
8 changed files with 87 additions and 88 deletions

View File

@ -134,6 +134,11 @@ class MainTest {
cmpInOut("fuzz12_input.txt", "fuzz12_output.txt");
}
@Test
void test13() throws IOException {
cmpInOut("test13_input.txt", "test13_output.txt");
}
private void cmpInOut(String in, String out) throws IOException {
System.setIn(new ByteArrayInputStream(readFile(in)));
ByteArrayOutputStream output = new ByteArrayOutputStream();

View File

@ -198,8 +198,8 @@ public class RailwayNetwork {
} else if (touchingRails.length == 1) { // simply move along the rail
return touchingRails[0].move(position, direction, 1);
} // else: check movement along both rails and pick the correct rail
final Vector2D onRailOne = touchingRails[0].move(position, new Vector2D(direction), steps);
final Vector2D onRailTwo = touchingRails[1].move(position, new Vector2D(direction), steps);
final Vector2D onRailOne = touchingRails[0].move(position, direction, steps);
final Vector2D onRailTwo = touchingRails[1].move(position, direction, steps);
// if we are stuck on the first rail
// or derail on the first rail
// or move in the correct direction on the second rail

View File

@ -153,6 +153,6 @@ public final class Switch extends Rail {
@Override
public int hashCode() {
return Objects.hash(positionOne, positionTwo, selection);
return Objects.hash(positionOne, positionTwo);
}
}

View File

@ -78,9 +78,9 @@ public final class Track extends Rail {
if (contains(nextPosition) || connectsTo(nextPosition)) {
return nextPosition;
} else if (direction.equals(getDirectionFrom(start))) {
return new Vector2D(end);
return end;
} else if (direction.equals(getDirectionFrom(end))) {
return new Vector2D(start);
return start;
} else if (position.equals(end) && !direction.equals(getDirectionFrom(start))) {
return move(position, getDirectionFrom(end), steps);
} else if (position.equals(start) && !direction.equals(getDirectionFrom(end))) {
@ -119,7 +119,7 @@ public final class Track extends Rail {
* @return start position of this track
*/
public Vector2D getStart() {
return new Vector2D(start);
return start;
}
/**
@ -128,7 +128,7 @@ public final class Track extends Rail {
* @return end position of this track
*/
public Vector2D getEnd() {
return new Vector2D(end);
return end;
}
@Override

View File

@ -8,7 +8,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
@ -181,19 +180,17 @@ public final class Train implements Comparable<Train> {
}
/**
* @return position of the train head
* @return position of the front of the train
*/
public Vector2D getFrontPosition() {
// make sure caller can not modify internal data
return positions != null ? new Vector2D(positions.getFirst()) : null;
return positions != null ? positions.getFirst() : null;
}
/**
* @return position of the rear of the train
* @return position of the back of the train
*/
public Vector2D getRearPosition() {
// make sure caller can not modify internal data
return positions != null ? new Vector2D(positions.getLast()) : null;
return positions != null ? positions.getLast() : null;
}
/**
@ -217,7 +214,8 @@ public final class Train implements Comparable<Train> {
* @return a set of the rails this train occupies
*/
public Set<Rail> getOccupiedRails() {
// make sure caller can not modify internal state
// need a copy (not a view) because the set will be modified when moving,
// but caller expects *current* state, not some updating state
return new HashSet<>(occupiedRails);
}
@ -229,17 +227,14 @@ public final class Train implements Comparable<Train> {
*/
public void moveTo(RailwayNetwork railNetwork, Vector2D nextPosition) {
final Optional<Rail> railUnderBackOfTrain = railNetwork.findContainingRail(positions.getLast());
positions.getLast().subtractInPlace(getRearDirection());
if (positions.getLast().equals(positions.get(positions.size() - 2))) {
if (!railNetwork.findContainingRail(nextPosition).equals(railUnderBackOfTrain)
|| nextPosition == null) {
positions.set(positions.size() - 1, positions.getLast().subtract(getRearDirection()));
if (positions.getLast().equals(positions.get(positions.size() - 2))) { // left a rail behind
occupiedRails.remove(railUnderBackOfTrain.orElse(null));
}
positions.removeLast();
}
if (nextPosition != null) {
// not derailing
positions.addFirst(new Vector2D(nextPosition));
positions.addFirst(nextPosition);
simplifyPositions(railNetwork);
occupiedRails.add(railNetwork.findRail(positions.get(1), nextPosition).get());
} // else: derailing
@ -255,24 +250,22 @@ public final class Train implements Comparable<Train> {
public void moveBackTo(RailwayNetwork railNetwork, Vector2D backPosition) {
// a common method for both directions would be a huge mess: requires at least six (!) extra parameters
final Optional<Rail> railUnderFrontOfTrain = railNetwork.findContainingRail(positions.getFirst());
positions.getFirst().subtractInPlace(getDirection());
if (positions.getFirst().equals(positions.get(1))) {
if (!railNetwork.findContainingRail(backPosition).equals(railUnderFrontOfTrain)
|| backPosition == null) {
positions.set(0, positions.getFirst().subtract(getDirection()));
if (positions.getFirst().equals(positions.get(1))) { // left a rail behind
occupiedRails.remove(railUnderFrontOfTrain.orElse(null));
}
positions.removeFirst();
}
if (backPosition != null) {
// not derailing
positions.addLast(new Vector2D(backPosition));
positions.addLast(backPosition);
simplifyPositions(railNetwork);
occupiedRails.add(railNetwork.findRail(positions.get(positions.size() - 2), backPosition).get());
} // else: derailing
}
/**
* Simplify internal position data. Removes positions that are contained between two other positions.
* Simplify internal position data.
* Removes positions that are contained between two other positions at the front or back of the train.
*
* @param railNetwork railway network to use
*/

View File

@ -4,19 +4,20 @@ import java.util.Objects;
/**
* A two-dimensional vector, usually a position or movement direction vector.
* An object of this class is immutable.
*
* @author Arne Keller
* @version 1.0
* @version 1.1
*/
public class Vector2D {
/**
* First coordinate of the vector, usually referred to as 'x'.
*/
private long x;
private final long x;
/**
* Second coordinate of the vector, usually referred to as 'y'.
*/
private long y;
private final long y;
/**
* Construct a new vector.
@ -29,16 +30,6 @@ public class Vector2D {
this.y = y;
}
/**
* Copy a vector, creating a new object.
*
* @param other a vector
*/
public Vector2D(Vector2D other) {
this.x = other.x;
this.y = other.y;
}
/**
* @param input two 32-bit numbers separated by a comma
* @return a vector containing the two numbers, null otherwise
@ -98,6 +89,40 @@ public class Vector2D {
|| y == 0 && y == other.y && Long.signum(x) == Long.signum(other.x);
}
/**
* @param movement vector to add
* @return component-wise sum of this vector and the other vector
*/
public Vector2D add(Vector2D movement) {
return new Vector2D(x + movement.x, y + movement.y);
}
/**
* Subtract another vector from this one.
*
* @param other another vector
* @return the difference of this vector and the other vector
*/
public Vector2D subtract(Vector2D other) {
return new Vector2D(x - other.x, y - other.y);
}
/**
* @return (- 1) * this vector
*/
public Vector2D negated() {
return new Vector2D(-x, -y);
}
/**
* Calculate multiplier * this, and return a new vector.
*
* @param multiplier any scalar
* @return scaled vector
*/
public Vector2D scale(long multiplier) {
return new Vector2D(x * multiplier, y * multiplier);
}
/**
* Normalize this vector. Will essentially return a new vector with (x/|x|, y/|y|).
@ -116,51 +141,6 @@ public class Vector2D {
}
}
/**
* @return (- 1) * this vector
*/
public Vector2D negated() {
return new Vector2D(-x, -y);
}
/**
* Subtract another vector from this one.
*
* @param other another vector
* @return the difference of this vector and the other vector
*/
public Vector2D subtract(Vector2D other) {
return new Vector2D(x - other.x, y - other.y);
}
/**
* Subtract another vector from this one, modifying this vector.
*
* @param other another vector
*/
public void subtractInPlace(Vector2D other) {
x -= other.x;
y -= other.y;
}
/**
* @param movement vector to add
* @return component-wise sum of this vector and the other vector
*/
public Vector2D add(Vector2D movement) {
return new Vector2D(x + movement.x, y + movement.y);
}
/**
* Calculate multiplier * this, and return a new vector.
*
* @param multiplier any scalar
* @return scaled vector
*/
public Vector2D scale(long multiplier) {
return new Vector2D(x * multiplier, y * multiplier);
}
/**
* @return the first component of this vector
*/

11
test13_input.txt Normal file
View File

@ -0,0 +1,11 @@
add track (0,0) -> (10,0)
add track (10,0) -> (20,0)
add track (20,0) -> (30,0)
create engine diesel T6 Lux 4 true true
create engine diesel T6 Lumen 4 true false
add train 1 T6-Lux
add train 2 T6-Lumen
put train 1 at (20,0) in direction 1,0
put train 2 at (8,0) in direction 1,0
step 3
exit

10
test13_output.txt Normal file
View File

@ -0,0 +1,10 @@
1
2
3
T6-Lux
T6-Lumen
diesel engine T6-Lux added to train 1
diesel engine T6-Lumen added to train 2
OK
OK
Crash of train 1,2