package cat.hack3.codingtests.marsrover; import cat.hack3.codingtests.marsrover.api.RotableRiderRover; import cat.hack3.codingtests.marsrover.api.cartography.Coordinates; import cat.hack3.codingtests.marsrover.api.cartography.Direction; import cat.hack3.codingtests.marsrover.api.cartography.PlanetMap; public class MarsRover implements RotableRiderRover { private final PlanetMap marsMap; private final RoverActionReporter roverActionReporter; private Direction currentDirection; public static class Provider implements RotableRiderRover.Provider { @Override public RotableRiderRover provideWith(PlanetMap map, Direction startingDirection) { return new MarsRover(map, startingDirection); } } private MarsRover(PlanetMap marsMap, Direction startingDirection) { this.marsMap = marsMap; currentDirection = startingDirection; roverActionReporter = new RoverActionReporter(); } @Override public void moveTowards(Direction direction) { Coordinates newPosition = marsMap.getNextPositionTowards(direction); boolean willCollide = marsMap.willCollideWithObstacle(newPosition); if (willCollide) { roverActionReporter.reportObstacle(newPosition); } else { moveTo(direction); marsMap.updateLocation(newPosition); roverActionReporter.reportMovement(direction, newPosition); } } private void moveTo(Direction direction) { //physical move (not implemented) } @Override public void rotateTowards(Rotation rotation) { var newDirection = switch (rotation) { case LEFT -> currentDirection.getNextDirectionRotatingMinus90Degrees(); case RIGHT -> currentDirection.getNextDirectionRotating90Degrees(); }; rotateTo(rotation); updateDirection(newDirection); roverActionReporter.reportRotation(rotation, newDirection); } private void rotateTo(Rotation rotation) { //physical rotation (not implemented) } private void updateDirection(Direction newDirection) { currentDirection = newDirection; } @Override public Coordinates getCurrentCoordinates() { return marsMap.getCurrentPosition(); } @Override public Direction getCurrentDirection() { return currentDirection; } }