From 7989a986286c1c0cc0f48ff0991f188b218ca5a3 Mon Sep 17 00:00:00 2001 From: Stanislav Nowogrudski Date: Fri, 21 Apr 2017 22:50:48 +0200 Subject: [PATCH] initial setup and turn strategy is working --- pom.xml | 50 +++++++++++++++ .../de/dj_steam/bot/cli/LoopingConsole.java | 47 ++++++++++++++ .../de/dj_steam/bot/domain/Direction.java | 11 ++++ .../java/de/dj_steam/bot/domain/Position.java | 26 ++++++++ .../java/de/dj_steam/bot/domain/ToyBot.java | 24 +++++++ .../de/dj_steam/bot/domain/ToyBotField.java | 12 ++++ .../de/dj_steam/bot/engine/RobotEngine.java | 50 +++++++++++++++ .../bot/moving/DirectionCalculator.java | 32 ++++++++++ .../bot/moving/LoopedDirectionsArrayList.java | 20 ++++++ .../bot/moving/strategy/ChangingStrategy.java | 11 ++++ .../bot/moving/strategy/TurnStrategy.java | 25 ++++++++ .../java/de/dj_steam/bot/RobotEngineTest.java | 63 +++++++++++++++++++ .../bot/moving/DirectionCalculatorTest.java | 37 +++++++++++ .../moving/LoopedDirectionsArrayListTest.java | 45 +++++++++++++ 14 files changed, 453 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/de/dj_steam/bot/cli/LoopingConsole.java create mode 100644 src/main/java/de/dj_steam/bot/domain/Direction.java create mode 100644 src/main/java/de/dj_steam/bot/domain/Position.java create mode 100644 src/main/java/de/dj_steam/bot/domain/ToyBot.java create mode 100644 src/main/java/de/dj_steam/bot/domain/ToyBotField.java create mode 100644 src/main/java/de/dj_steam/bot/engine/RobotEngine.java create mode 100644 src/main/java/de/dj_steam/bot/moving/DirectionCalculator.java create mode 100644 src/main/java/de/dj_steam/bot/moving/LoopedDirectionsArrayList.java create mode 100644 src/main/java/de/dj_steam/bot/moving/strategy/ChangingStrategy.java create mode 100644 src/main/java/de/dj_steam/bot/moving/strategy/TurnStrategy.java create mode 100644 src/test/java/de/dj_steam/bot/RobotEngineTest.java create mode 100644 src/test/java/de/dj_steam/bot/moving/DirectionCalculatorTest.java create mode 100644 src/test/java/de/dj_steam/bot/moving/LoopedDirectionsArrayListTest.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8860594 --- /dev/null +++ b/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + toy-bot + de.dj_steam.toybot + 1.0-SNAPSHOT + + + + + org.slf4j + slf4j-simple + 1.7.25 + + + + org.projectlombok + lombok + 1.16.14 + + + + junit + junit + 4.12 + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + \ No newline at end of file diff --git a/src/main/java/de/dj_steam/bot/cli/LoopingConsole.java b/src/main/java/de/dj_steam/bot/cli/LoopingConsole.java new file mode 100644 index 0000000..a0be10b --- /dev/null +++ b/src/main/java/de/dj_steam/bot/cli/LoopingConsole.java @@ -0,0 +1,47 @@ +package de.dj_steam.bot.cli; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import de.dj_steam.bot.engine.RobotEngine; + +/** + * @author steam + */ + +public class LoopingConsole { + + private static final String EXIT_COMMAND = "exit"; + + public static void main(final String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + + printUsageBanner(); + + while (true) { + RobotEngine robotEngine = new RobotEngine(); + System.out.print("> "); + String input = br.readLine(); + robotEngine.commandBot(input); + + if (input.trim().toLowerCase().equals(EXIT_COMMAND)) { + System.out.println("exiting"); + return; + } + } + } + + private static void printUsageBanner() { + System.out.println("####################################################"); + System.out.println("Commands:"); + System.out.println("PLACE X,Y,F - place robot on position X,Y - coordinates, and direction (NORTH|SOUTH|WEST|EAST)"); + System.out.println("MOVE - change the robot to the next field in facing direction"); + System.out.println("LEFT - turn the robot to the left"); + System.out.println("RIGHT - turn the robot to the right"); + System.out.println("REPORT - show robots position and facing direction"); + System.out.println("exit - exit the application"); + System.out.println("####################################################"); + System.out.println("Enter a command or '" + EXIT_COMMAND + "' to quit"); + } +} diff --git a/src/main/java/de/dj_steam/bot/domain/Direction.java b/src/main/java/de/dj_steam/bot/domain/Direction.java new file mode 100644 index 0000000..1105363 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/domain/Direction.java @@ -0,0 +1,11 @@ +package de.dj_steam.bot.domain; + +/** + * @author steam + */ +public enum Direction { + NORTH, + EAST, + SOUTH, + WEST +} diff --git a/src/main/java/de/dj_steam/bot/domain/Position.java b/src/main/java/de/dj_steam/bot/domain/Position.java new file mode 100644 index 0000000..4331245 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/domain/Position.java @@ -0,0 +1,26 @@ +package de.dj_steam.bot.domain; + +import lombok.Getter; +import lombok.ToString; + +/** + * @author steam + */ + +@Getter +@ToString +public class Position { + private int x; + private int y; + + public Position() { + this.x = 0; + this.y = 0; + } + + public Position(final int x, final int y) { + this.x = x; + this.y = y; + } + +} diff --git a/src/main/java/de/dj_steam/bot/domain/ToyBot.java b/src/main/java/de/dj_steam/bot/domain/ToyBot.java new file mode 100644 index 0000000..d02e197 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/domain/ToyBot.java @@ -0,0 +1,24 @@ +package de.dj_steam.bot.domain; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * @author steam + */ + +@Getter +@Setter +@ToString +public class ToyBot { + + private Direction direction; + private Position position; + + public ToyBot(final Direction direction, final Position position) { + this.direction = direction; + this.position = position; + } + +} diff --git a/src/main/java/de/dj_steam/bot/domain/ToyBotField.java b/src/main/java/de/dj_steam/bot/domain/ToyBotField.java new file mode 100644 index 0000000..5cfa608 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/domain/ToyBotField.java @@ -0,0 +1,12 @@ +package de.dj_steam.bot.domain; + +import lombok.Getter; + +/** + * @author steam + */ +@Getter +public class ToyBotField { + private int width = 5; + private int height = 5; +} diff --git a/src/main/java/de/dj_steam/bot/engine/RobotEngine.java b/src/main/java/de/dj_steam/bot/engine/RobotEngine.java new file mode 100644 index 0000000..3519b27 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/engine/RobotEngine.java @@ -0,0 +1,50 @@ +package de.dj_steam.bot.engine; + +import java.util.ArrayList; +import java.util.List; + +import de.dj_steam.bot.domain.Direction; +import de.dj_steam.bot.domain.Position; +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.domain.ToyBotField; +import de.dj_steam.bot.moving.strategy.ChangingStrategy; +import de.dj_steam.bot.moving.strategy.TurnStrategy; + +/** + * @author steam + */ +public class RobotEngine { + + public static final String TURN_LEFT = "LEFT"; + public static final String TURN_RIGHT = "RIGHT"; + public static final String MOVE = "MOVE"; + public static final String PLACE = "PLACE"; + public static final String REPORT = "REPORT"; + + private final ToyBotField toyBotField; + private final ToyBot toyBot; + private List changingStrategies; + + public RobotEngine() { + this.toyBot = new ToyBot(Direction.NORTH, new Position()); + this.toyBotField = new ToyBotField(); + initChangingStrategies(); + } + + public RobotEngine(final ToyBotField toyBotField, final ToyBot toyBot) { + this.toyBotField = toyBotField; + this.toyBot = toyBot; + initChangingStrategies(); + } + + public void commandBot(String command) { + for (ChangingStrategy strategy : changingStrategies) { + strategy.change(toyBot, toyBotField, command); + } + } + + private void initChangingStrategies() { + changingStrategies = new ArrayList<>(); + changingStrategies.add(new TurnStrategy()); + } +} diff --git a/src/main/java/de/dj_steam/bot/moving/DirectionCalculator.java b/src/main/java/de/dj_steam/bot/moving/DirectionCalculator.java new file mode 100644 index 0000000..38691d2 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/moving/DirectionCalculator.java @@ -0,0 +1,32 @@ +package de.dj_steam.bot.moving; + +import java.util.Arrays; + +import de.dj_steam.bot.domain.Direction; +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.engine.RobotEngine; + +/** + * @author steam + */ +public class DirectionCalculator { + + private LoopedDirectionsArrayList directions; + + public DirectionCalculator() { + directions = new LoopedDirectionsArrayList(); + directions.addAll(Arrays.asList(Direction.values())); + } + + public Direction calculateNewDirection(ToyBot toyBot, String turnDirection) { + + Direction actualDirection = toyBot.getDirection(); + + if (turnDirection.equals(RobotEngine.TURN_LEFT)) { + return directions.get(directions.indexOf(actualDirection) - 1); + } else if (turnDirection.equals(RobotEngine.TURN_RIGHT)) { + return directions.get(directions.indexOf(actualDirection) + 1); + } + return toyBot.getDirection(); + } +} diff --git a/src/main/java/de/dj_steam/bot/moving/LoopedDirectionsArrayList.java b/src/main/java/de/dj_steam/bot/moving/LoopedDirectionsArrayList.java new file mode 100644 index 0000000..dbf4759 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/moving/LoopedDirectionsArrayList.java @@ -0,0 +1,20 @@ +package de.dj_steam.bot.moving; + +import java.util.ArrayList; + +/** + * @author steam + */ +public class LoopedDirectionsArrayList extends ArrayList { + + @Override + public Direction get(int index) { + if (index < 0) { + return super.get(size() - Math.abs(index)); + } else if (index >= size()) { + return super.get(index - size()); + } else { + return super.get(index); + } + } +} diff --git a/src/main/java/de/dj_steam/bot/moving/strategy/ChangingStrategy.java b/src/main/java/de/dj_steam/bot/moving/strategy/ChangingStrategy.java new file mode 100644 index 0000000..f771ac9 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/moving/strategy/ChangingStrategy.java @@ -0,0 +1,11 @@ +package de.dj_steam.bot.moving.strategy; + +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.domain.ToyBotField; + +/** + * @author steam + */ +public interface ChangingStrategy { + void change(ToyBot toyBot, ToyBotField toyBotField, String command); +} diff --git a/src/main/java/de/dj_steam/bot/moving/strategy/TurnStrategy.java b/src/main/java/de/dj_steam/bot/moving/strategy/TurnStrategy.java new file mode 100644 index 0000000..559d8a2 --- /dev/null +++ b/src/main/java/de/dj_steam/bot/moving/strategy/TurnStrategy.java @@ -0,0 +1,25 @@ +package de.dj_steam.bot.moving.strategy; + +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.domain.ToyBotField; +import de.dj_steam.bot.engine.RobotEngine; +import de.dj_steam.bot.moving.DirectionCalculator; + +/** + * @author steam + */ +public class TurnStrategy implements ChangingStrategy { + + private DirectionCalculator directionCalculator; + + public TurnStrategy() { + directionCalculator = new DirectionCalculator(); + } + + @Override + public void change(ToyBot toyBot, ToyBotField toyBotField, String command) { + if (command.equals(RobotEngine.TURN_LEFT) || command.equals(RobotEngine.TURN_RIGHT)) { + toyBot.setDirection(directionCalculator.calculateNewDirection(toyBot, command)); + } + } +} diff --git a/src/test/java/de/dj_steam/bot/RobotEngineTest.java b/src/test/java/de/dj_steam/bot/RobotEngineTest.java new file mode 100644 index 0000000..b60a91d --- /dev/null +++ b/src/test/java/de/dj_steam/bot/RobotEngineTest.java @@ -0,0 +1,63 @@ +package de.dj_steam.bot; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import de.dj_steam.bot.domain.Direction; +import de.dj_steam.bot.domain.Position; +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.domain.ToyBotField; +import de.dj_steam.bot.engine.RobotEngine; + +/** + * @author steam + */ +public class RobotEngineTest { + + private RobotEngine robotEngine; + private ToyBot toyBot; + + private ToyBotField toyBotField = new ToyBotField(); + + @Before + public void setup() { + toyBot = new ToyBot(Direction.NORTH, new Position()); + robotEngine = new RobotEngine(toyBotField, toyBot); + } + + @Test + public void testTurnLeftCommand() { + assertEquals(Direction.NORTH, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_LEFT); + assertEquals(Direction.WEST, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_LEFT); + assertEquals(Direction.SOUTH, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_LEFT); + assertEquals(Direction.EAST, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_LEFT); + assertEquals(Direction.NORTH, toyBot.getDirection()); + } + + @Test + public void testTurnRightCommand() { + assertEquals(Direction.NORTH, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_RIGHT); + assertEquals(Direction.EAST, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_RIGHT); + assertEquals(Direction.SOUTH, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_RIGHT); + assertEquals(Direction.WEST, toyBot.getDirection()); + + robotEngine.commandBot(RobotEngine.TURN_RIGHT); + assertEquals(Direction.NORTH, toyBot.getDirection()); + } +} \ No newline at end of file diff --git a/src/test/java/de/dj_steam/bot/moving/DirectionCalculatorTest.java b/src/test/java/de/dj_steam/bot/moving/DirectionCalculatorTest.java new file mode 100644 index 0000000..9a33baa --- /dev/null +++ b/src/test/java/de/dj_steam/bot/moving/DirectionCalculatorTest.java @@ -0,0 +1,37 @@ +package de.dj_steam.bot.moving; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import de.dj_steam.bot.domain.Direction; +import de.dj_steam.bot.domain.Position; +import de.dj_steam.bot.domain.ToyBot; +import de.dj_steam.bot.engine.RobotEngine; + +/** + * @author steam + */ +public class DirectionCalculatorTest { + + private DirectionCalculator directionCalculator; + + @Before + public void setup() { + directionCalculator = new DirectionCalculator(); + } + + @Test + public void testCalculateOnTurnLeft() { + ToyBot toyBot = new ToyBot(Direction.NORTH, new Position()); + assertEquals(Direction.WEST, directionCalculator.calculateNewDirection(toyBot, RobotEngine.TURN_LEFT)); + } + + @Test + public void testCalculateOnTurnRight() { + ToyBot toyBot = new ToyBot(Direction.NORTH, new Position()); + assertEquals(Direction.EAST, directionCalculator.calculateNewDirection(toyBot, RobotEngine.TURN_RIGHT)); + } + +} \ No newline at end of file diff --git a/src/test/java/de/dj_steam/bot/moving/LoopedDirectionsArrayListTest.java b/src/test/java/de/dj_steam/bot/moving/LoopedDirectionsArrayListTest.java new file mode 100644 index 0000000..09951be --- /dev/null +++ b/src/test/java/de/dj_steam/bot/moving/LoopedDirectionsArrayListTest.java @@ -0,0 +1,45 @@ +package de.dj_steam.bot.moving; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +import de.dj_steam.bot.domain.Direction; + +/** + * @author steam + */ +public class LoopedDirectionsArrayListTest { + private LoopedDirectionsArrayList directions; + + @Before + public void setup() { + directions = new LoopedDirectionsArrayList(); + directions.addAll(Arrays.asList(Direction.values())); + } + + @Test + public void testLoopedArrayInitialisation() { + assertEquals(Direction.NORTH, directions.get(0)); + assertEquals(Direction.EAST, directions.get(1)); + assertEquals(Direction.SOUTH, directions.get(2)); + assertEquals(Direction.WEST, directions.get(3)); + } + + @Test + public void testBorderOverlapping() { + assertEquals(Direction.NORTH, directions.get(4)); + assertEquals(Direction.EAST, directions.get(5)); + assertEquals(Direction.SOUTH, directions.get(6)); + assertEquals(Direction.WEST, directions.get(7)); + + assertEquals(Direction.WEST, directions.get(-1)); + assertEquals(Direction.SOUTH, directions.get(-2)); + assertEquals(Direction.EAST, directions.get(-3)); + assertEquals(Direction.NORTH, directions.get(-4)); + } + +} \ No newline at end of file