diff --git a/SOLUTION.md b/SOLUTION.md index 7627f64..221d939 100644 --- a/SOLUTION.md +++ b/SOLUTION.md @@ -1,4 +1,7 @@ # MY SOLUTION -## Current design +## Current design with JPMS -![Current design](misc/images/mars-rover_design.png) \ No newline at end of file +![Current design](misc/images/mars-rover_design_JPMS.png) + +## Previous design +![Previous design](misc/images/mars-rover_design.png) \ No newline at end of file diff --git a/mars-station/pom.xml b/mars-station/pom.xml index 21d8c06..95257ba 100644 --- a/mars-station/pom.xml +++ b/mars-station/pom.xml @@ -11,6 +11,13 @@ mars-station 2.0 + + + cat.hack3.codingtests + rover-api + 1.0 + + 17 diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/MarsRover.java b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/MarsRover.java index 2f8b991..21091cb 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/MarsRover.java +++ b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/MarsRover.java @@ -1,16 +1,24 @@ package cat.hack3.codingtests.marsrover; -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; -import cat.hack3.codingtests.marsrover.cartography.MarsMap; +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{ +public class MarsRover implements RotableRiderRover { - private final MarsMap marsMap; + private final PlanetMap marsMap; private final RoverActionReporter roverActionReporter; private Direction currentDirection; - public MarsRover(MarsMap marsMap, Direction startingDirection) { + 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(); diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RotableRiderRover.java b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RotableRiderRover.java deleted file mode 100644 index c4a899a..0000000 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RotableRiderRover.java +++ /dev/null @@ -1,16 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; - -public interface RotableRiderRover { - enum Rotation {LEFT, RIGHT} - - void moveTowards(Direction direction); - - void rotateTowards(Rotation rotation); - - Coordinates getCurrentCoordinates(); - - Direction getCurrentDirection(); -} diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RoverActionReporter.java b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RoverActionReporter.java index 26efc68..276594b 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RoverActionReporter.java +++ b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/RoverActionReporter.java @@ -1,8 +1,8 @@ package cat.hack3.codingtests.marsrover; -import cat.hack3.codingtests.marsrover.RotableRiderRover.Rotation; -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; +import cat.hack3.codingtests.marsrover.api.RotableRiderRover.Rotation; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates; +import cat.hack3.codingtests.marsrover.api.cartography.Direction; import java.util.logging.Logger; diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MapIncrementalPositionResolver.java b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MapIncrementalPositionResolver.java similarity index 87% rename from mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MapIncrementalPositionResolver.java rename to mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MapIncrementalPositionResolver.java index 2e7557d..31ce2ab 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MapIncrementalPositionResolver.java +++ b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MapIncrementalPositionResolver.java @@ -1,7 +1,7 @@ -package cat.hack3.codingtests.marsrover.cartography; +package cat.hack3.codingtests.marsrover.gps; -import cat.hack3.codingtests.marsrover.cartography.Coordinates.Latitude; -import cat.hack3.codingtests.marsrover.cartography.Coordinates.Longitude; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates.Latitude; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates.Longitude; public class MapIncrementalPositionResolver { diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MarsMap.java b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MarsMap.java similarity index 72% rename from mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MarsMap.java rename to mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MarsMap.java index bd3b799..2b963a4 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/MarsMap.java +++ b/mars-station/src/main/java/cat/hack3/codingtests/marsrover/gps/MarsMap.java @@ -1,7 +1,10 @@ -package cat.hack3.codingtests.marsrover.cartography; +package cat.hack3.codingtests.marsrover.gps; -import cat.hack3.codingtests.marsrover.cartography.Coordinates.Latitude; -import cat.hack3.codingtests.marsrover.cartography.Coordinates.Longitude; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates.Latitude; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates.Longitude; +import cat.hack3.codingtests.marsrover.api.cartography.Direction; +import cat.hack3.codingtests.marsrover.api.cartography.PlanetMap; import java.util.List; @@ -14,7 +17,7 @@ import java.util.List; * 2 2-1 2-2 2-3 * 3 3-1 3-2 3-3 */ -public class MarsMap { +public class MarsMap implements PlanetMap { private static final int FIRST_POSITION_IN_MAP = 1; private static final int INCREMENT_UNIT = 1; @@ -24,13 +27,21 @@ public class MarsMap { private final MapIncrementalPositionResolver positionResolver; + public static class Provider implements PlanetMap.Provider { + @Override + public PlanetMap provideWith(int height, int width, Coordinates startingCoordinates, List obstaclesLocalizations) { + return new MarsMap(height, width, startingCoordinates, obstaclesLocalizations); + } + } + @SafeVarargs - public MarsMap(int height, int width, Coordinates startingCoordinates, List... obstaclesLocalizations) { + private MarsMap(int height, int width, Coordinates startingCoordinates, List... obstaclesLocalizations) { currentPosition = startingCoordinates; this.obstaclesLocalizations = obstaclesLocalizations.length > 0 ? obstaclesLocalizations[0] : List.of(); positionResolver = new MapIncrementalPositionResolver(FIRST_POSITION_IN_MAP, INCREMENT_UNIT, height, width); } + @Override public Coordinates getNextPositionTowards(Direction direction) { return switch (direction) { case NORTH -> getDecrementLatitude(); @@ -64,14 +75,17 @@ public class MarsMap { return currentPosition.withUpdated(Longitude.of(newLongitude)); } + @Override public synchronized void updateLocation(Coordinates newPosition) { currentPosition = newPosition; } + @Override public boolean willCollideWithObstacle(Coordinates newCoordinates) { return obstaclesLocalizations.contains(newCoordinates); } + @Override public Coordinates getCurrentPosition() { return currentPosition; } diff --git a/mars-station/src/main/java/module-info.java b/mars-station/src/main/java/module-info.java new file mode 100644 index 0000000..ea4c32a --- /dev/null +++ b/mars-station/src/main/java/module-info.java @@ -0,0 +1,15 @@ +import cat.hack3.codingtests.marsrover.MarsRover; +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.cartography.PlanetMap; +import cat.hack3.codingtests.marsrover.gps.MarsMap; + +module mars.station { + requires rover.api; + requires java.logging; + + provides PlanetMap.Provider + with MarsMap.Provider; + + provides RotableRiderRover.Provider + with MarsRover.Provider; +} \ No newline at end of file diff --git a/misc/images/mars-rover_design.png b/misc/images/mars-rover_design.png index 0930a74..0b50509 100644 Binary files a/misc/images/mars-rover_design.png and b/misc/images/mars-rover_design.png differ diff --git a/misc/images/mars-rover_design_JPMS.png b/misc/images/mars-rover_design_JPMS.png new file mode 100644 index 0000000..b54008a Binary files /dev/null and b/misc/images/mars-rover_design_JPMS.png differ diff --git a/pom.xml b/pom.xml index e924a80..08014b6 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,8 @@ mars-station user-interface-console rover-commands + rover-api + tests-suite diff --git a/rover-api/pom.xml b/rover-api/pom.xml new file mode 100644 index 0000000..120ff4c --- /dev/null +++ b/rover-api/pom.xml @@ -0,0 +1,20 @@ + + + + mars-rover + cat.hack3.codingtests + 10.0 + + 4.0.0 + + rover-api + 1.0 + + + 17 + 17 + + + \ No newline at end of file diff --git a/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/RotableRiderRover.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/RotableRiderRover.java new file mode 100644 index 0000000..75a4840 --- /dev/null +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/RotableRiderRover.java @@ -0,0 +1,21 @@ +package cat.hack3.codingtests.marsrover.api; + +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 interface RotableRiderRover { + enum Rotation {LEFT, RIGHT} + + void moveTowards(Direction direction); + + void rotateTowards(Rotation rotation); + + Coordinates getCurrentCoordinates(); + + Direction getCurrentDirection(); + + interface Provider { + RotableRiderRover provideWith(PlanetMap map, Direction startingDirection); + } +} diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Coordinates.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Coordinates.java similarity index 77% rename from mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Coordinates.java rename to rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Coordinates.java index 3a99576..4a096aa 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Coordinates.java +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Coordinates.java @@ -1,4 +1,4 @@ -package cat.hack3.codingtests.marsrover.cartography; +package cat.hack3.codingtests.marsrover.api.cartography; public record Coordinates(Latitude latitude, Longitude longitude) { @@ -14,8 +14,8 @@ public record Coordinates(Latitude latitude, Longitude longitude) { return Coordinates.of(latitude.pointer, newLongitude.pointer); } - record Latitude(long pointer) { - static Latitude of(long pointer) { + public record Latitude(long pointer) { + public static Latitude of(long pointer) { return new Latitude(pointer); } @Override @@ -23,8 +23,8 @@ public record Coordinates(Latitude latitude, Longitude longitude) { return String.valueOf(pointer); } } - record Longitude(long pointer) { - static Longitude of(long pointer) { + public record Longitude(long pointer) { + public static Longitude of(long pointer) { return new Longitude(pointer); } @Override diff --git a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Direction.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Direction.java similarity index 92% rename from mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Direction.java rename to rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Direction.java index 6e2205c..ad117df 100644 --- a/mars-station/src/main/java/cat/hack3/codingtests/marsrover/cartography/Direction.java +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/Direction.java @@ -1,4 +1,4 @@ -package cat.hack3.codingtests.marsrover.cartography; +package cat.hack3.codingtests.marsrover.api.cartography; public enum Direction { NORTH, SOUTH, EAST, WEST; diff --git a/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/PlanetMap.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/PlanetMap.java new file mode 100644 index 0000000..41ec642 --- /dev/null +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/cartography/PlanetMap.java @@ -0,0 +1,18 @@ +package cat.hack3.codingtests.marsrover.api.cartography; + +import java.util.List; + +public interface PlanetMap { + + Coordinates getNextPositionTowards(Direction direction); + + void updateLocation(Coordinates newPosition); + + boolean willCollideWithObstacle(Coordinates newCoordinates); + + Coordinates getCurrentPosition(); + + interface Provider { + PlanetMap provideWith(int height, int width, Coordinates startingCoordinates, List obstaclesLocalizations); + } +} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/RoverCommand.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommand.java similarity index 69% rename from rover-commands/src/main/java/cat/hack3/codingtests/marsrover/RoverCommand.java rename to rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommand.java index 27e65ce..12d2fff 100644 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/RoverCommand.java +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommand.java @@ -1,4 +1,4 @@ -package cat.hack3.codingtests.marsrover; +package cat.hack3.codingtests.marsrover.api.commands; public interface RoverCommand { enum Type {MOVE_FORWARD, MOVE_BACKWARDS, TURN_LEFT, TURN_RIGHT} diff --git a/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommandFactory.java b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommandFactory.java new file mode 100644 index 0000000..376eff8 --- /dev/null +++ b/rover-api/src/main/java/cat/hack3/codingtests/marsrover/api/commands/RoverCommandFactory.java @@ -0,0 +1,11 @@ +package cat.hack3.codingtests.marsrover.api.commands; + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; + +public interface RoverCommandFactory { + RoverCommand create(RoverCommand.Type type); + + interface Provider { + RoverCommandFactory provideWith(RotableRiderRover rover); + } +} diff --git a/rover-api/src/main/java/module-info.java b/rover-api/src/main/java/module-info.java new file mode 100644 index 0000000..09b4d8e --- /dev/null +++ b/rover-api/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module rover.api { + exports cat.hack3.codingtests.marsrover.api; + exports cat.hack3.codingtests.marsrover.api.cartography; + exports cat.hack3.codingtests.marsrover.api.commands; +} \ No newline at end of file diff --git a/rover-commands/pom.xml b/rover-commands/pom.xml index 04962eb..45f943a 100644 --- a/rover-commands/pom.xml +++ b/rover-commands/pom.xml @@ -12,17 +12,17 @@ rover-commands 2.0 + + + cat.hack3.codingtests + rover-api + 1.0 + + + 17 17 - - - cat.hack3.codingtests - mars-station - 2.0 - - - \ No newline at end of file diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/CommandFactory.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/CommandFactory.java deleted file mode 100644 index 77104cb..0000000 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/CommandFactory.java +++ /dev/null @@ -1,18 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -public class CommandFactory { - private final RotableRiderRover rover; - - public CommandFactory(RotableRiderRover rover) { - this.rover = rover; - } - - public RoverCommand createCommand(RoverCommand.Type type) { - return switch (type) { - case MOVE_FORWARD -> new MoveForwardCommand(rover); - case MOVE_BACKWARDS -> new MoveBackwardsCommand(rover); - case TURN_LEFT -> new TurnLeftCommand(rover); - case TURN_RIGHT -> new TurnRightCommand(rover); - }; - } -} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveForwardCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveForwardCommand.java deleted file mode 100644 index 2f2d11b..0000000 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveForwardCommand.java +++ /dev/null @@ -1,13 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -class MoveForwardCommand implements RoverCommand { - private final RotableRiderRover rover; - - public MoveForwardCommand(RotableRiderRover rover) { - this.rover = rover; - } - - public void execute() { - rover.moveTowards(rover.getCurrentDirection()); - } -} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnLeftCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnLeftCommand.java deleted file mode 100644 index 065082d..0000000 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnLeftCommand.java +++ /dev/null @@ -1,16 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -import static cat.hack3.codingtests.marsrover.RotableRiderRover.Rotation.LEFT; - -class TurnLeftCommand implements RoverCommand { - private final RotableRiderRover rover; - - public TurnLeftCommand(RotableRiderRover rover) { - this.rover = rover; - } - - @Override - public void execute() { - rover.rotateTowards(LEFT); - } -} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnRightCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnRightCommand.java deleted file mode 100644 index a4273e6..0000000 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/TurnRightCommand.java +++ /dev/null @@ -1,16 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -import static cat.hack3.codingtests.marsrover.RotableRiderRover.Rotation.RIGHT; - -class TurnRightCommand implements RoverCommand { - private final RotableRiderRover rover; - - public TurnRightCommand(RotableRiderRover rover) { - this.rover = rover; - } - - @Override - public void execute() { - rover.rotateTowards(RIGHT); - } -} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveBackwardsCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveBackwardsCommand.java similarity index 51% rename from rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveBackwardsCommand.java rename to rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveBackwardsCommand.java index de9ac8c..053ab11 100644 --- a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/MoveBackwardsCommand.java +++ b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveBackwardsCommand.java @@ -1,6 +1,10 @@ -package cat.hack3.codingtests.marsrover; +package cat.hack3.codingtests.marsrover.commands; -class MoveBackwardsCommand implements RoverCommand { + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; + +public class MoveBackwardsCommand implements RoverCommand { private final RotableRiderRover rover; public MoveBackwardsCommand(RotableRiderRover rover) { diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveForwardCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveForwardCommand.java new file mode 100644 index 0000000..b5b0467 --- /dev/null +++ b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/MoveForwardCommand.java @@ -0,0 +1,17 @@ +package cat.hack3.codingtests.marsrover.commands; + + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; + +public class MoveForwardCommand implements RoverCommand { + private final RotableRiderRover rover; + + public MoveForwardCommand(RotableRiderRover rover) { + this.rover = rover; + } + + public void execute() { + rover.moveTowards(rover.getCurrentDirection()); + } +} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/RoverCommandFactoryImpl.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/RoverCommandFactoryImpl.java new file mode 100644 index 0000000..167dca3 --- /dev/null +++ b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/RoverCommandFactoryImpl.java @@ -0,0 +1,31 @@ +package cat.hack3.codingtests.marsrover.commands; + + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; + +public class RoverCommandFactoryImpl implements RoverCommandFactory { + private final RotableRiderRover rover; + + public static class Provider implements RoverCommandFactory.Provider { + @Override + public RoverCommandFactory provideWith(RotableRiderRover rover) { + return new RoverCommandFactoryImpl(rover); + } + } + + private RoverCommandFactoryImpl(RotableRiderRover rover) { + this.rover = rover; + } + + @Override + public RoverCommand create(RoverCommand.Type type) { + return switch (type) { + case MOVE_FORWARD -> new MoveForwardCommand(rover); + case MOVE_BACKWARDS -> new MoveBackwardsCommand(rover); + case TURN_LEFT -> new TurnLeftCommand(rover); + case TURN_RIGHT -> new TurnRightCommand(rover); + }; + } +} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnLeftCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnLeftCommand.java new file mode 100644 index 0000000..10211f0 --- /dev/null +++ b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnLeftCommand.java @@ -0,0 +1,20 @@ +package cat.hack3.codingtests.marsrover.commands; + + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; + +import static cat.hack3.codingtests.marsrover.api.RotableRiderRover.Rotation.LEFT; + +public class TurnLeftCommand implements RoverCommand { + private final RotableRiderRover rover; + + public TurnLeftCommand(RotableRiderRover rover) { + this.rover = rover; + } + + @Override + public void execute() { + rover.rotateTowards(LEFT); + } +} diff --git a/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnRightCommand.java b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnRightCommand.java new file mode 100644 index 0000000..5f834e6 --- /dev/null +++ b/rover-commands/src/main/java/cat/hack3/codingtests/marsrover/commands/TurnRightCommand.java @@ -0,0 +1,20 @@ +package cat.hack3.codingtests.marsrover.commands; + + +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; + +import static cat.hack3.codingtests.marsrover.api.RotableRiderRover.Rotation.RIGHT; + +public class TurnRightCommand implements RoverCommand { + private final RotableRiderRover rover; + + public TurnRightCommand(RotableRiderRover rover) { + this.rover = rover; + } + + @Override + public void execute() { + rover.rotateTowards(RIGHT); + } +} diff --git a/rover-commands/src/main/java/module-info.java b/rover-commands/src/main/java/module-info.java new file mode 100644 index 0000000..d7b0e81 --- /dev/null +++ b/rover-commands/src/main/java/module-info.java @@ -0,0 +1,9 @@ +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; +import cat.hack3.codingtests.marsrover.commands.RoverCommandFactoryImpl; + +module rover.commands { + requires rover.api; + + provides RoverCommandFactory.Provider + with RoverCommandFactoryImpl.Provider; +} \ No newline at end of file diff --git a/rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverWithObstaclesTest.java b/rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverWithObstaclesTest.java deleted file mode 100644 index eef547b..0000000 --- a/rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverWithObstaclesTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package cat.hack3.codingtests.marsrover; - -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; -import cat.hack3.codingtests.marsrover.cartography.MarsMap; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.util.List; - -import static cat.hack3.codingtests.marsrover.RoverCommand.Type.*; -import static cat.hack3.codingtests.marsrover.cartography.Direction.SOUTH; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotEquals; - -public class MarsRoverWithObstaclesTest { - - private MarsRover rover; - - private RoverCommand moveForwardCommand; - private RoverCommand turnLeftCommand; - private RoverCommand turnRightCommand; - - @BeforeMethod - public void setUp() { - int mapWidth = 10; - int mapHeight = 10; - int latitudeStartingPoint = 2; - int longitudeStartingPoint = 3; - var startingCoordinates = Coordinates.of(latitudeStartingPoint, longitudeStartingPoint); - List obstaclesLocalizations = List.of( - Coordinates.of(3, 3), - Coordinates.of(5, 5), - Coordinates.of(7, 7), - Coordinates.of(9, 9), - Coordinates.of(10, 10) - ); - var marsMap = new MarsMap(mapHeight, mapWidth, startingCoordinates, obstaclesLocalizations); - rover = new MarsRover(marsMap, SOUTH); - - var commandFactory = new CommandFactory(rover); - moveForwardCommand = commandFactory.createCommand(MOVE_FORWARD); - turnLeftCommand = commandFactory.createCommand(TURN_LEFT); - turnRightCommand = commandFactory.createCommand(TURN_RIGHT); - } - - @Test - public void findAnObstacleAtFirstMove() { - Coordinates originalCoordinates = rover.getCurrentCoordinates(); - Direction originalDirection = rover.getCurrentDirection(); - - moveForwardCommand.execute(); - - assertEquals(rover.getCurrentCoordinates(), originalCoordinates); - assertEquals(rover.getCurrentDirection(), originalDirection); - } - - @Test - public void afterFindingObstacleWalkAroundUntilFindingNext() { - moveForwardCommand.execute(); - Coordinates oneStepForward = rover.getCurrentCoordinates(); - assertNotEquals(oneStepForward, Coordinates.of(3, 3)); - - turnLeftCommand.execute(); - moveForwardCommand.execute(); - moveForwardCommand.execute(); - turnRightCommand.execute(); - moveForwardCommand.execute(); - moveForwardCommand.execute(); - var currentPosition = Coordinates.of(4, 5); - assertEquals(rover.getCurrentCoordinates(), currentPosition); - moveForwardCommand.execute(); - var positionAfterMove = Coordinates.of(5, 4); - assertNotEquals(rover.getCurrentCoordinates(), positionAfterMove); - } - -} diff --git a/tests-suite/pom.xml b/tests-suite/pom.xml new file mode 100644 index 0000000..e89adff --- /dev/null +++ b/tests-suite/pom.xml @@ -0,0 +1,39 @@ + + + + mars-rover + cat.hack3.codingtests + 10.0 + + 4.0.0 + + tests-suite + + + cat.hack3.codingtests + rover-api + 1.0 + test + + + cat.hack3.codingtests + rover-commands + 2.0 + test + + + cat.hack3.codingtests + mars-station + 2.0 + test + + + + + 17 + 17 + + + \ No newline at end of file diff --git a/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/CommonTests.java b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/CommonTests.java new file mode 100644 index 0000000..c3f4f14 --- /dev/null +++ b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/CommonTests.java @@ -0,0 +1,64 @@ +package cat.hack3.codingtests.marsrover.test; + +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; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; + +import java.util.List; +import java.util.ServiceLoader; +import java.util.stream.IntStream; + +import static cat.hack3.codingtests.marsrover.api.cartography.Direction.SOUTH; +import static cat.hack3.codingtests.marsrover.api.commands.RoverCommand.Type.*; + +public class CommonTests { + + public static final Direction STARTING_DIRECTION = SOUTH; + + protected RotableRiderRover rover; + protected RoverCommand moveForwardCommand; + protected RoverCommand moveBackwardsCommand; + protected RoverCommand turnLeftCommand; + protected RoverCommand turnRightCommand; + + protected void setup() { + int mapWidth = 10; + int mapHeight = 10; + int latitudeStartingPoint = 2; + int longitudeStartingPoint = 3; + var startingCoordinates = Coordinates.of(latitudeStartingPoint, longitudeStartingPoint); + + var marsMap = getImplProviderOf(PlanetMap.Provider.class) + .provideWith(mapHeight, mapWidth, startingCoordinates, getObstacles()); + + rover = getImplProviderOf(RotableRiderRover.Provider.class) + .provideWith(marsMap, CommonTests.STARTING_DIRECTION); + + var commandFactory = getImplProviderOf(RoverCommandFactory.Provider.class) + .provideWith(rover); + + moveForwardCommand = commandFactory.create(MOVE_FORWARD); + moveBackwardsCommand = commandFactory.create(MOVE_BACKWARDS); + turnLeftCommand = commandFactory.create(TURN_LEFT); + turnRightCommand = commandFactory.create(TURN_RIGHT); + } + + private T getImplProviderOf(Class interfaceProvider) { + return ServiceLoader + .load(interfaceProvider) + .findFirst() + .orElseThrow(); + } + + protected List getObstacles() { + return List.of(); + } + + protected void repeatAction(int times, Runnable actionToRepeat) { + IntStream.rangeClosed(1, times) + .forEach(i -> actionToRepeat.run()); + } +} diff --git a/rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverTest.java b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverTest.java similarity index 74% rename from rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverTest.java rename to tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverTest.java index 53b8398..a909bcf 100644 --- a/rover-commands/src/test/java/cat/hack3/codingtests/marsrover/MarsRoverTest.java +++ b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverTest.java @@ -1,41 +1,18 @@ -package cat.hack3.codingtests.marsrover; +package cat.hack3.codingtests.marsrover.test; -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; -import cat.hack3.codingtests.marsrover.cartography.MarsMap; +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates; +import cat.hack3.codingtests.marsrover.api.cartography.Direction; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import java.util.stream.IntStream; - -import static cat.hack3.codingtests.marsrover.RoverCommand.Type.*; -import static cat.hack3.codingtests.marsrover.cartography.Direction.*; +import static cat.hack3.codingtests.marsrover.api.cartography.Direction.*; import static org.testng.Assert.assertEquals; -public class MarsRoverTest { - - private MarsRover rover; - - private RoverCommand moveForwardCommand; - private RoverCommand moveBackwardsCommand; - private RoverCommand turnLeftCommand; - private RoverCommand turnRightCommand; +public class MarsRoverTest extends CommonTests { @BeforeMethod public void setUp() { - int mapWidth = 10; - int mapHeight = 10; - int latitudeStartingPoint = 2; - int longitudeStartingPoint = 3; - var startingCoordinates = Coordinates.of(latitudeStartingPoint, longitudeStartingPoint); - var marsMap = new MarsMap(mapHeight, mapWidth, startingCoordinates); - rover = new MarsRover(marsMap, SOUTH); - - var commandFactory = new CommandFactory(rover); - moveForwardCommand = commandFactory.createCommand(MOVE_FORWARD); - moveBackwardsCommand = commandFactory.createCommand(MOVE_BACKWARDS); - turnLeftCommand = commandFactory.createCommand(TURN_LEFT); - turnRightCommand = commandFactory.createCommand(TURN_RIGHT); + setup(); } @Test @@ -154,8 +131,4 @@ public class MarsRoverTest { assertEquals(rover.getCurrentDirection(), EAST); } - private void repeatAction(int times, Runnable actionToRepeat) { - IntStream.rangeClosed(1, times) - .forEach(i -> actionToRepeat.run()); - } } diff --git a/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverWithObstaclesTest.java b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverWithObstaclesTest.java new file mode 100644 index 0000000..76be79d --- /dev/null +++ b/tests-suite/src/test/java/cat/hack3/codingtests/marsrover/test/MarsRoverWithObstaclesTest.java @@ -0,0 +1,55 @@ +package cat.hack3.codingtests.marsrover.test; + +import cat.hack3.codingtests.marsrover.api.cartography.Coordinates; +import cat.hack3.codingtests.marsrover.api.cartography.Direction; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.List; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; + +public class MarsRoverWithObstaclesTest extends CommonTests { + + @BeforeMethod + public void setUp() { + super.setup(); + } + + @Test + public void findAnObstacleAtFirstMove() { + Coordinates originalCoordinates = rover.getCurrentCoordinates(); + Direction originalDirection = rover.getCurrentDirection(); + + moveForwardCommand.execute(); + + assertEquals(rover.getCurrentCoordinates(), originalCoordinates); + assertEquals(rover.getCurrentDirection(), originalDirection); + } + + @Test + public void afterFindingObstacleWalkAroundUntilFindingNext() { + moveForwardCommand.execute(); + Coordinates oneStepForward = rover.getCurrentCoordinates(); + assertNotEquals(oneStepForward, Coordinates.of(3, 3)); + assertEquals(oneStepForward, Coordinates.of(2, 3)); + + turnLeftCommand.execute(); + repeatAction(2, () -> moveForwardCommand.execute()); + turnRightCommand.execute(); + repeatAction(2, () -> moveForwardCommand.execute()); + assertEquals(rover.getCurrentCoordinates(), Coordinates.of(4, 5)); + moveForwardCommand.execute(); + assertNotEquals(rover.getCurrentCoordinates(), Coordinates.of(5, 5)); + assertEquals(rover.getCurrentCoordinates(), Coordinates.of(4, 5)); + } + + @Override + protected List getObstacles() { + return List.of( + Coordinates.of(3, 3), + Coordinates.of(5, 5) + ); + } +} diff --git a/tests-suite/src/test/java/module-info.java b/tests-suite/src/test/java/module-info.java new file mode 100644 index 0000000..1e2403a --- /dev/null +++ b/tests-suite/src/test/java/module-info.java @@ -0,0 +1,17 @@ +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.cartography.PlanetMap; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; + +module tests.suite { + requires rover.api; + requires mars.station; + requires rover.commands; + + uses PlanetMap.Provider; + uses RotableRiderRover.Provider; + uses RoverCommandFactory.Provider; + + requires org.testng; + + exports cat.hack3.codingtests.marsrover.test; +} \ No newline at end of file diff --git a/user-interface-console/pom.xml b/user-interface-console/pom.xml index dbcd0fd..3c88194 100644 --- a/user-interface-console/pom.xml +++ b/user-interface-console/pom.xml @@ -10,23 +10,31 @@ 4.0.0 user-interface-console + + + cat.hack3.codingtests + rover-api + 1.0 + compile + + + cat.hack3.codingtests + mars-station + 2.0 + compile + + + cat.hack3.codingtests + rover-commands + 2.0 + compile + + + 17 17 - - - cat.hack3.codingtests - mars-station - 2.0 - - - cat.hack3.codingtests - rover-commands - 2.0 - - - \ No newline at end of file diff --git a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/ClientCommandInterface.java b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/ClientCommandInterface.java index 0309ede..d4feed6 100644 --- a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/ClientCommandInterface.java +++ b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/ClientCommandInterface.java @@ -1,6 +1,6 @@ package cat.hack3.codingtests.marsrover.ui.console; -import cat.hack3.codingtests.marsrover.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; import java.util.Scanner; @@ -26,8 +26,8 @@ public class ClientCommandInterface { private void start() { output(PresentationMessage.INTRO); - //RotableRiderRover rover = roverInitializer.autoInitialize(); - RotableRiderRover rover = roverInitializer.initializeFromUserInputs(); + RotableRiderRover rover = roverInitializer.autoInitialize(); + //RotableRiderRover rover = roverInitializer.initializeFromUserInputs(); var commandsPerformer = new RoverCommandsPerformer(reader, rover); commandsPerformer.acceptCommandsUntilExitSignal(); diff --git a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/DirectionRetriever.java b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/DirectionRetriever.java index 2d6d16e..1f0baa9 100644 --- a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/DirectionRetriever.java +++ b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/DirectionRetriever.java @@ -1,7 +1,7 @@ package cat.hack3.codingtests.marsrover.ui.console; -import cat.hack3.codingtests.marsrover.cartography.Direction; +import cat.hack3.codingtests.marsrover.api.cartography.Direction; import java.util.Scanner; diff --git a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverCommandsPerformer.java b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverCommandsPerformer.java index ba40194..18dcf40 100644 --- a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverCommandsPerformer.java +++ b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverCommandsPerformer.java @@ -1,19 +1,18 @@ package cat.hack3.codingtests.marsrover.ui.console; -import cat.hack3.codingtests.marsrover.CommandFactory; -import cat.hack3.codingtests.marsrover.RotableRiderRover; -import cat.hack3.codingtests.marsrover.RoverCommand; +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommand; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; import java.util.Scanner; -import static cat.hack3.codingtests.marsrover.RoverCommand.Type.*; +import static cat.hack3.codingtests.marsrover.api.commands.RoverCommand.Type.*; import static cat.hack3.codingtests.marsrover.ui.console.UICommons.isNotExitSignal; import static cat.hack3.codingtests.marsrover.ui.console.UICommons.output; public class RoverCommandsPerformer { private final Scanner reader; - CommandFactory commandFactory; private final RoverCommand moveForwardCommand; private final RoverCommand moveBackwardsCommand; private final RoverCommand turnLeftCommand; @@ -21,11 +20,13 @@ public class RoverCommandsPerformer { public RoverCommandsPerformer(Scanner reader, RotableRiderRover rover) { this.reader = reader; - commandFactory = new CommandFactory(rover); - moveForwardCommand = commandFactory.createCommand(MOVE_FORWARD); - moveBackwardsCommand = commandFactory.createCommand(MOVE_BACKWARDS); - turnLeftCommand = commandFactory.createCommand(TURN_LEFT); - turnRightCommand = commandFactory.createCommand(TURN_RIGHT); + var roverCommandFactory = UICommons + .getImplProviderOf(RoverCommandFactory.Provider.class) + .provideWith(rover); + moveForwardCommand = roverCommandFactory.create(MOVE_FORWARD); + moveBackwardsCommand = roverCommandFactory.create(MOVE_BACKWARDS); + turnLeftCommand = roverCommandFactory.create(TURN_LEFT); + turnRightCommand = roverCommandFactory.create(TURN_RIGHT); } public void acceptCommandsUntilExitSignal() { diff --git a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverInitializer.java b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverInitializer.java index cbc8ac1..7b6b999 100644 --- a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverInitializer.java +++ b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/RoverInitializer.java @@ -1,10 +1,9 @@ package cat.hack3.codingtests.marsrover.ui.console; -import cat.hack3.codingtests.marsrover.MarsRover; -import cat.hack3.codingtests.marsrover.RotableRiderRover; -import cat.hack3.codingtests.marsrover.cartography.Coordinates; -import cat.hack3.codingtests.marsrover.cartography.Direction; -import cat.hack3.codingtests.marsrover.cartography.MarsMap; +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; import java.util.InputMismatchException; import java.util.List; @@ -36,7 +35,7 @@ public class RoverInitializer { Direction startingDirection = directionRetriever.retrieveDirection(); - RotableRiderRover rover = deployRover(mapHeight, mapWidth, latitudeStartingPoint, longitudeStartingPoint, startingDirection); + RotableRiderRover rover = deployRover(mapHeight, mapWidth, latitudeStartingPoint, longitudeStartingPoint, startingDirection, List.of()); output(PresentationMessage.READY_MESSAGE); reader.next(); //input ignored @@ -65,10 +64,12 @@ public class RoverInitializer { return deployRover(10, 10, 2, 3, Direction.SOUTH, obstacles); } - @SafeVarargs - private RotableRiderRover deployRover(int mapHeight, int mapWidth, int latitudeStartingPoint, int longitudeStartingPoint, Direction startingDirection, List... obstaclesLocalizations) { + private RotableRiderRover deployRover(int mapHeight, int mapWidth, int latitudeStartingPoint, int longitudeStartingPoint, Direction startingDirection, List obstaclesLocalizations) { var startingCoordinates = Coordinates.of(latitudeStartingPoint, longitudeStartingPoint); - var marsMap = new MarsMap(mapHeight, mapWidth, startingCoordinates, obstaclesLocalizations); - return new MarsRover(marsMap, startingDirection); + + var mapProvider = UICommons.getImplProviderOf(PlanetMap.Provider.class); + var roverProvider = UICommons.getImplProviderOf(RotableRiderRover.Provider.class); + var marsMap = mapProvider.provideWith(mapHeight, mapWidth, startingCoordinates, obstaclesLocalizations); + return roverProvider.provideWith(marsMap, startingDirection); } } diff --git a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/UICommons.java b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/UICommons.java index 982cb08..5a7b5dd 100644 --- a/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/UICommons.java +++ b/user-interface-console/src/main/java/cat/hack3/codingtests/marsrover/ui/console/UICommons.java @@ -1,5 +1,7 @@ package cat.hack3.codingtests.marsrover.ui.console; +import java.util.ServiceLoader; + public class UICommons { public static final String QUIT_COMMAND_TEXT = "q"; @@ -15,4 +17,11 @@ public class UICommons { static void output(String message) { System.out.println(message); } + + static T getImplProviderOf(Class interfaceProvider) { + return ServiceLoader + .load(interfaceProvider) + .findFirst() + .orElseThrow(); + } } diff --git a/user-interface-console/src/main/java/module-info.java b/user-interface-console/src/main/java/module-info.java new file mode 100644 index 0000000..1ae39a7 --- /dev/null +++ b/user-interface-console/src/main/java/module-info.java @@ -0,0 +1,13 @@ +import cat.hack3.codingtests.marsrover.api.RotableRiderRover; +import cat.hack3.codingtests.marsrover.api.cartography.PlanetMap; +import cat.hack3.codingtests.marsrover.api.commands.RoverCommandFactory; + +module ui.console { + requires rover.api; + requires mars.station; + requires rover.commands; + + uses PlanetMap.Provider; + uses RotableRiderRover.Provider; + uses RoverCommandFactory.Provider; +} \ No newline at end of file