Do not teleport across gaps of size one

This commit is contained in:
Arne Keller 2020-03-06 08:43:22 +01:00
parent 726bf0b0d6
commit 2649cd85e2
3 changed files with 25 additions and 11 deletions

View File

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

View File

@ -2,6 +2,7 @@ package edu.kit.informatik.model;
import edu.kit.informatik.ui.InvalidInputException; import edu.kit.informatik.ui.InvalidInputException;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
@ -207,13 +208,6 @@ public class RailwayNetwork {
return containingRail.get().move(position, direction, steps); return containingRail.get().move(position, direction, steps);
} }
final Rail[] touchingRails = findTouchingRails(position); final Rail[] touchingRails = findTouchingRails(position);
final Vector2D nextPossiblePosition = position.add(direction);
final Optional<Rail> possibleContainingRail = findRailPotentiallyContaining(nextPossiblePosition);
if (possibleContainingRail.isPresent()
&& !possibleContainingRail.get().contains(position.subtract(direction))) {
return possibleContainingRail.get().move(position, direction, steps);
}
if (touchingRails.length == 0) { if (touchingRails.length == 0) {
return null; return null;
} else if (touchingRails.length == 1) { } else if (touchingRails.length == 1) {
@ -221,12 +215,14 @@ public class RailwayNetwork {
} }
final Vector2D onRailOne = touchingRails[0].move(position, new Vector2D(direction), steps); final Vector2D onRailOne = touchingRails[0].move(position, new Vector2D(direction), steps);
final Vector2D onRailTwo = touchingRails[1].move(position, new Vector2D(direction), steps); final Vector2D onRailTwo = touchingRails[1].move(position, new Vector2D(direction), steps);
if (position.equals(onRailOne) || onRailOne == null) { if (position.equals(onRailOne) || onRailOne == null
|| (onRailTwo != null && onRailTwo.subtract(position).directionEquals(direction))) {
// we are moving on rail two // we are moving on rail two
final Vector2D newDirection = touchingRails[1].getDirectionFrom(position); final Vector2D newDirection = touchingRails[1].getDirectionFrom(position);
direction.copyFrom(newDirection); direction.copyFrom(newDirection);
return onRailTwo; return onRailTwo;
} else if (position.equals(onRailTwo) || onRailTwo == null) { } else if (position.equals(onRailTwo) || onRailTwo == null
|| onRailOne.subtract(position).directionEquals(direction)) {
final Vector2D newDirection = touchingRails[0].getDirectionFrom(position); final Vector2D newDirection = touchingRails[0].getDirectionFrom(position);
direction.copyFrom(newDirection); direction.copyFrom(newDirection);
return onRailOne; return onRailOne;

View File

@ -67,13 +67,26 @@ public class Vector2D {
* Check whether this vector is parallel to another vector. Note that this method only works for vectors that * Check whether this vector is parallel to another vector. Note that this method only works for vectors that
* are parallel to one of the coordinate axes. * are parallel to one of the coordinate axes.
* *
* @param other the point to measure distance to * @param other vector to compare
* @return the manhattan distance * @return whether both are parallel
*/ */
public boolean isParallelTo(Vector2D other) { public boolean isParallelTo(Vector2D other) {
return x == 0 && other.x == 0 || y == 0 && other.y == 0; return x == 0 && other.x == 0 || y == 0 && other.y == 0;
} }
/**
* Calculate whether this vector points in the same direction as another. Note that this method only works for
* vectors that are parallel to one of the coordinate axes.
*
* @param other vector to compare
* @return whether they represent the same direction
*/
public boolean directionEquals(Vector2D other) {
return x == 0 && x == other.x && Long.signum(y) == Long.signum(other.y)
|| y == 0 && y == other.y && Long.signum(x) == Long.signum(other.x);
}
/** /**
* Normalize this vector. Will essentially return a new vector with (x/|x|, y/|y|). * Normalize this vector. Will essentially return a new vector with (x/|x|, y/|y|).
* *