diff --git a/src/main/java/inf112/fiasko/roborally/objects/Board.java b/src/main/java/inf112/fiasko/roborally/objects/Board.java index 59009dd..af98a68 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Board.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Board.java @@ -449,7 +449,8 @@ public class Board { for (Robot robot : deadRobots) { if (robot.getAmountOfLives() > 0) { robot.setPosition(robot.getBackupPosition()); - robot.setFacingDirection(Direction.NORTH); + robot.setFacingDirection(GridUtil.getMatchingElements(TileType.FLAG_1, + tiles).get(0).getElement().getDirection()); robot.setDamageTaken(2); robots.put(robot.getRobotId(), robot); } else { diff --git a/src/main/java/inf112/fiasko/roborally/objects/BoardElement.java b/src/main/java/inf112/fiasko/roborally/objects/BoardElement.java index 773bc08..59fdfb7 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/BoardElement.java +++ b/src/main/java/inf112/fiasko/roborally/objects/BoardElement.java @@ -23,4 +23,18 @@ public interface BoardElement { */ Direction getDirection(); + /** + * Changes the direction of the element + * + * @param newDirection The element's new direction + */ + void setDirection(Direction newDirection); + + /** + * Makes a copy of the board element + * + * @return A copy of the element + */ + BoardElement copy(); + } diff --git a/src/main/java/inf112/fiasko/roborally/objects/ListGrid.java b/src/main/java/inf112/fiasko/roborally/objects/ListGrid.java index dac3a55..1f09607 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/ListGrid.java +++ b/src/main/java/inf112/fiasko/roborally/objects/ListGrid.java @@ -84,4 +84,24 @@ public class ListGrid implements Grid { throw new IllegalArgumentException("Coordinates are outside the bounds of the board."); } } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + K element = getElement(i, j); + if (element != null) { + builder.append(element.toString()); + } else { + builder.append(0); + } + if (i < width - 1) { + builder.append(" "); + } + } + builder.append("\n"); + } + return builder.toString(); + } } diff --git a/src/main/java/inf112/fiasko/roborally/objects/Particle.java b/src/main/java/inf112/fiasko/roborally/objects/Particle.java index 5e5dd12..06e9dc2 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Particle.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Particle.java @@ -2,6 +2,7 @@ package inf112.fiasko.roborally.objects; import inf112.fiasko.roborally.elementproperties.Direction; import inf112.fiasko.roborally.elementproperties.ParticleType; +import inf112.fiasko.roborally.utility.StringUtil; /** * This class represents a particle @@ -34,4 +35,20 @@ public class Particle implements BoardElement { public Direction getDirection() { return direction; } + + @Override + public void setDirection(Direction newDirection) { + this.direction = newDirection; + } + + @Override + public BoardElement copy() { + return new Particle(particleType, direction); + } + + @Override + public String toString() { + return StringUtil.addLeadingZeros(particleType.getParticleTypeID(), 2) + ";" + + StringUtil.addLeadingZeros(direction.getDirectionID(), 2); + } } \ No newline at end of file diff --git a/src/main/java/inf112/fiasko/roborally/objects/Tile.java b/src/main/java/inf112/fiasko/roborally/objects/Tile.java index 3e6a166..192e257 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Tile.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Tile.java @@ -2,6 +2,7 @@ package inf112.fiasko.roborally.objects; import inf112.fiasko.roborally.elementproperties.Direction; import inf112.fiasko.roborally.elementproperties.TileType; +import inf112.fiasko.roborally.utility.StringUtil; /** * This class represents a simple tile @@ -34,4 +35,20 @@ public class Tile implements BoardElement { public Direction getDirection() { return direction; } + + @Override + public void setDirection(Direction newDirection) { + this.direction = newDirection; + } + + @Override + public BoardElement copy() { + return new Tile(tileType, direction); + } + + @Override + public String toString() { + return StringUtil.addLeadingZeros(tileType.getTileTypeID(), 2) + ";" + + StringUtil.addLeadingZeros(direction.getDirectionID(), 2); + } } diff --git a/src/main/java/inf112/fiasko/roborally/objects/TwoTuple.java b/src/main/java/inf112/fiasko/roborally/objects/TwoTuple.java new file mode 100644 index 0000000..9ea80a7 --- /dev/null +++ b/src/main/java/inf112/fiasko/roborally/objects/TwoTuple.java @@ -0,0 +1,23 @@ +package inf112.fiasko.roborally.objects; + +/** + * A class which can save a tuple with two values + * + * @param The type of the first value + * @param The type of the second value + */ +public class TwoTuple { + public final T value1; + public final K value2; + + /** + * Instantiates a new 2-tuple + * + * @param value1 The first value of the tuple + * @param value2 The second value of the tuple + */ + public TwoTuple(T value1, K value2) { + this.value1 = value1; + this.value2 = value2; + } +} diff --git a/src/main/java/inf112/fiasko/roborally/objects/Wall.java b/src/main/java/inf112/fiasko/roborally/objects/Wall.java index 9db667f..b2ff61a 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Wall.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Wall.java @@ -8,7 +8,7 @@ import inf112.fiasko.roborally.elementproperties.WallType; */ public class Wall implements BoardElement { private final WallType wallType; - private final Direction direction; + private Direction direction; /** * Initializes a wall @@ -33,4 +33,19 @@ public class Wall implements BoardElement { public Direction getDirection() { return direction; } + + @Override + public void setDirection(Direction newDirection) { + this.direction = newDirection; + } + + @Override + public BoardElement copy() { + return new Wall(wallType, direction); + } + + @Override + public String toString() { + return wallType.getWallTypeID() + ";" + direction.getDirectionID(); + } } diff --git a/src/main/java/inf112/fiasko/roborally/utility/BoardLoaderUtil.java b/src/main/java/inf112/fiasko/roborally/utility/BoardLoaderUtil.java index 1c4d0f1..2e1d62e 100644 --- a/src/main/java/inf112/fiasko/roborally/utility/BoardLoaderUtil.java +++ b/src/main/java/inf112/fiasko/roborally/utility/BoardLoaderUtil.java @@ -4,10 +4,13 @@ import inf112.fiasko.roborally.elementproperties.Direction; import inf112.fiasko.roborally.elementproperties.TileType; import inf112.fiasko.roborally.elementproperties.WallType; import inf112.fiasko.roborally.objects.Board; +import inf112.fiasko.roborally.objects.BoardElement; +import inf112.fiasko.roborally.objects.BoardElementContainer; import inf112.fiasko.roborally.objects.Grid; import inf112.fiasko.roborally.objects.ListGrid; import inf112.fiasko.roborally.objects.Robot; import inf112.fiasko.roborally.objects.Tile; +import inf112.fiasko.roborally.objects.TwoTuple; import inf112.fiasko.roborally.objects.Wall; import java.io.BufferedReader; @@ -24,6 +27,75 @@ public final class BoardLoaderUtil { private BoardLoaderUtil() { } + /** + * Loads and rotates a board described in a file + * + * @param boardFile The file containing the board description + * @param robotList A list of robots on the board + * @param clockwise Whether to rotate the board clockwise + * @return A board + * @throws IOException If the board file cannot be loaded + */ + public static Board loadBoardRotated(String boardFile, List robotList, boolean clockwise) throws IOException { + TwoTuple, Grid> grids = loadBoardGrids(boardFile); + adjustRobotRotationToBoardRotation(grids.value1, robotList); + return new Board(rotateGrid(grids.value1, clockwise), rotateGrid(grids.value2, clockwise), robotList); + } + + /** + * Loads the grids necessary to create a board + * + * @param boardFile The board file to load + * @return A tuple with the tile grid and the wall grid + * @throws IOException If the board cannot be read + */ + private static TwoTuple, Grid> loadBoardGrids(String boardFile) throws IOException { + InputStream fileStream = ResourceUtil.getResourceAsInputStream(boardFile); + BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream)); + String infoLine = reader.readLine(); + String[] infoData = infoLine.split(" "); + int gridWidth = Integer.parseInt(infoData[0]); + int gridHeight = Integer.parseInt(infoData[1]); + Grid tileGrid = loadTileGrid(reader, gridWidth, gridHeight); + Grid wallGrid = loadWallGrid(reader, gridWidth, gridHeight); + return new TwoTuple<>(tileGrid, wallGrid); + } + + /** + * Rotates a grid clockwise or counterclockwise + * + * @param grid The grid to rotate + * @param clockwise Whether to rotate the grid clockwise + * @param The type of the grid to rotate + * @return The rotated board + */ + @SuppressWarnings("unchecked") + private static Grid rotateGrid(Grid grid, boolean clockwise) { + int gridWidth = grid.getWidth(); + int gridHeight = grid.getHeight(); + Grid newGrid = new ListGrid<>(grid.getHeight(), grid.getWidth()); + for (int i = 0; i < gridWidth; i++) { + for (int j = 0; j < gridHeight; j++) { + K element = grid.getElement(i, j); + K copy = null; + if (element != null) { + copy = (K) element.copy(); + if (clockwise) { + copy.setDirection(Direction.getRightRotatedDirection(copy.getDirection())); + } else { + copy.setDirection(Direction.getLeftRotatedDirection(copy.getDirection())); + } + } + if (clockwise) { + newGrid.setElement(gridHeight - j - 1, i, copy); + } else { + newGrid.setElement(j, gridWidth - i - 1, copy); + } + } + } + return newGrid; + } + /** * Loads a board described in a file * @@ -33,16 +105,29 @@ public final class BoardLoaderUtil { * @throws IOException If the board file cannot be loaded */ public static Board loadBoard(String boardFile, List robotList) throws IOException { - InputStream fileStream = ResourceUtil.getResourceAsInputStream(boardFile); - BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream)); - String infoLine = reader.readLine(); - String[] infoData = infoLine.split(" "); - int gridWidth = Integer.parseInt(infoData[0]); - int gridHeight = Integer.parseInt(infoData[1]); + TwoTuple, Grid> grids = loadBoardGrids(boardFile); + adjustRobotRotationToBoardRotation(grids.value1, robotList); + return new Board(grids.value1, grids.value2, robotList); + } - Grid tileGrid = loadTileGrid(reader, gridWidth, gridHeight); - Grid wallGrid = loadWallGrid(reader, gridWidth, gridHeight); - return new Board(tileGrid, wallGrid, robotList); + /** + * Changes the direction of robots to the direction which is up + * + * @param tileGrid The grid containing flags + * @param robotList The list of robots on the board + */ + private static void adjustRobotRotationToBoardRotation(Grid tileGrid, List robotList) { + //The flags are always in the up direction + List> flags = GridUtil.getMatchingElements(TileType.FLAG_1, tileGrid); + Direction boardDirection; + if (flags.size() == 0) { + boardDirection = Direction.NORTH; + } else { + boardDirection = flags.get(0).getElement().getDirection(); + } + for (Robot robot : robotList) { + robot.setFacingDirection(boardDirection); + } } /** diff --git a/src/main/java/inf112/fiasko/roborally/utility/StringUtil.java b/src/main/java/inf112/fiasko/roborally/utility/StringUtil.java new file mode 100644 index 0000000..24ea79e --- /dev/null +++ b/src/main/java/inf112/fiasko/roborally/utility/StringUtil.java @@ -0,0 +1,20 @@ +package inf112.fiasko.roborally.utility; + +public final class StringUtil { + + /** + * Adds zeros to a number until it reaches a set length and converts it to a string + * + * @param number The number to add zeros to + * @param zeros The number of characters in the output + * @return The number as a string with necessary leading zeros + */ + public static String addLeadingZeros(int number, int zeros) { + StringBuilder numberAsString = new StringBuilder(String.valueOf(number)); + for (int i = numberAsString.length(); i < zeros; i++) { + numberAsString.insert(0, "0"); + } + return numberAsString.toString(); + } + +} diff --git a/src/main/resources/boards/Around_The_World.txt b/src/main/resources/boards/Around_The_World.txt index 97c8cc5..255f1f0 100644 --- a/src/main/resources/boards/Around_The_World.txt +++ b/src/main/resources/boards/Around_The_World.txt @@ -1,11 +1,11 @@ 28 12 21;01 01;03 01;03 01;03 01;03 01;03 01;03 01;03 01;03 01;03 01;03 01;03 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;07 01;07 30;07 01;07 01;03 34;07 35;03 01;03 01;03 01;01 01;03 01;03 01;03 35;07 34;01 01;03 01;1 12;3 11;3 11;3 12;5 01;1 01;1 12;3 11;3 11;3 12;5 01;1 01;07 01;07 28;07 01;07 -01;03 35;05 03;01 05;03 05;03 05;03 05;03 05;03 05;03 05;03 35;05 01;03 17;1 11;1 03;1 01;1 11;5 04;1 01;1 11;1 03;1 01;1 11;5 01;1 01;07 01;07 01;07 01;07 +01;03 35;05 03;01 05;03 05;03 05;03 05;03 05;03 05;03 05;03 35;05 01;03 17;7 11;1 03;1 01;1 11;5 04;1 01;1 11;1 03;1 01;1 11;5 01;1 01;07 01;07 01;07 01;07 01;03 01;03 05;01 04;01 05;07 05;07 09;07 05;07 04;01 05;05 01;03 01;03 01;1 11;1 21;1 03;1 11;5 01;1 01;1 11;1 22;1 03;1 11;5 01;1 01;07 01;07 26;07 01;07 01;03 01;03 05;01 05;05 34;07 35;03 05;01 01;03 05;01 05;05 01;03 01;03 01;1 12;1 11;7 11;7 12;7 01;1 04;1 12;1 11;7 11;7 12;7 01;1 01;07 01;07 01;07 01;07 -01;03 18;01 05;01 05;05 35;05 22;01 05;01 01;03 05;01 05;05 01;03 01;03 01;1 01;1 01;1 01;1 04;1 01;1 01;1 01;1 01;1 04;1 01;1 01;1 01;07 01;07 24;07 01;07 -01;03 01;03 05;01 05;05 01;03 05;05 01;03 35;01 05;01 05;05 01;01 01;03 01;1 01;1 04;1 01;1 01;1 01;1 01;1 04;1 01;1 01;1 19;1 01;1 01;07 01;07 23;07 01;07 +01;03 18;07 05;01 05;05 35;05 22;01 05;01 01;03 05;01 05;05 01;03 01;03 01;1 01;1 01;1 01;1 04;1 01;1 01;1 01;1 01;1 04;1 01;1 01;1 01;07 01;07 24;07 01;07 +01;03 01;03 05;01 05;05 01;03 05;05 01;03 35;01 05;01 05;05 01;01 01;03 01;1 01;1 04;1 01;1 01;1 01;1 01;1 04;1 01;1 01;1 19;7 01;1 01;07 01;07 23;07 01;07 01;03 01;03 05;01 05;05 01;03 05;05 35;07 34;03 05;01 05;05 01;03 01;03 01;1 12;3 11;3 11;3 12;5 04;1 01;1 12;3 11;3 11;3 12;5 01;1 01;07 01;07 01;07 01;07 01;03 01;03 05;01 04;01 05;03 09;03 05;03 05;03 04;01 05;05 01;03 01;03 01;1 11;1 03;1 22;1 11;5 01;1 01;1 11;1 03;1 21;1 11;5 01;1 01;07 01;07 25;07 01;07 01;03 35;01 03;01 05;07 05;07 05;07 05;07 05;07 05;07 05;05 35;01 01;03 01;1 11;1 01;1 03;1 11;5 01;1 04;1 11;1 01;1 03;1 11;5 01;1 01;07 01;07 01;07 01;07 diff --git a/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java b/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java index 3fe4616..95b394a 100644 --- a/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java +++ b/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java @@ -176,9 +176,9 @@ public class PhaseTest { robots.add(robot); robots.add(new Robot(RobotID.ROBOT_2, new Position(9, 13))); robots.add(robot3); - robot3.setFacingDirection(Direction.EAST); - Phase testPhase = createPhaseAndLoadBoard(players, robots, "boards/another_test_map.txt"); + robot3.setFacingDirection(Direction.EAST); + assertEquals(0, robot.getDamageTaken()); testPhase.fireAllLasers(); assertEquals(2, robot.getDamageTaken());