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