Gjør en del endringer som gjør det mulig å rotere den logiske representasjonen av et brett

Endrer rotasjonen til roboter til å tilpasse seg retningen til flaggene
Lager metoder som lar en printe ut grids på samme format som de blir lest fra
This commit is contained in:
Kristian Knarvik 2020-04-29 22:54:25 +02:00
parent 405ed74898
commit 16e7a4d2c2
11 changed files with 228 additions and 16 deletions

View File

@ -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 {

View File

@ -23,4 +23,18 @@ public interface BoardElement<K> {
*/
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<K> copy();
}

View File

@ -84,4 +84,24 @@ public class ListGrid<K> implements Grid<K> {
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();
}
}

View File

@ -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<ParticleType> {
public Direction getDirection() {
return direction;
}
@Override
public void setDirection(Direction newDirection) {
this.direction = newDirection;
}
@Override
public BoardElement<ParticleType> copy() {
return new Particle(particleType, direction);
}
@Override
public String toString() {
return StringUtil.addLeadingZeros(particleType.getParticleTypeID(), 2) + ";" +
StringUtil.addLeadingZeros(direction.getDirectionID(), 2);
}
}

View File

@ -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<TileType> {
public Direction getDirection() {
return direction;
}
@Override
public void setDirection(Direction newDirection) {
this.direction = newDirection;
}
@Override
public BoardElement<TileType> copy() {
return new Tile(tileType, direction);
}
@Override
public String toString() {
return StringUtil.addLeadingZeros(tileType.getTileTypeID(), 2) + ";" +
StringUtil.addLeadingZeros(direction.getDirectionID(), 2);
}
}

View File

@ -0,0 +1,23 @@
package inf112.fiasko.roborally.objects;
/**
* A class which can save a tuple with two values
*
* @param <T> The type of the first value
* @param <K> The type of the second value
*/
public class TwoTuple<T, K> {
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;
}
}

View File

@ -8,7 +8,7 @@ import inf112.fiasko.roborally.elementproperties.WallType;
*/
public class Wall implements BoardElement<WallType> {
private final WallType wallType;
private final Direction direction;
private Direction direction;
/**
* Initializes a wall
@ -33,4 +33,19 @@ public class Wall implements BoardElement<WallType> {
public Direction getDirection() {
return direction;
}
@Override
public void setDirection(Direction newDirection) {
this.direction = newDirection;
}
@Override
public BoardElement<WallType> copy() {
return new Wall(wallType, direction);
}
@Override
public String toString() {
return wallType.getWallTypeID() + ";" + direction.getDirectionID();
}
}

View File

@ -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<Robot> robotList, boolean clockwise) throws IOException {
TwoTuple<Grid<Tile>, Grid<Wall>> 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<Tile>, Grid<Wall>> 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<Tile> tileGrid = loadTileGrid(reader, gridWidth, gridHeight);
Grid<Wall> 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 <K> The type of the grid to rotate
* @return The rotated board
*/
@SuppressWarnings("unchecked")
private static <K extends BoardElement> Grid<K> rotateGrid(Grid<K> grid, boolean clockwise) {
int gridWidth = grid.getWidth();
int gridHeight = grid.getHeight();
Grid<K> 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<Robot> 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<Tile>, Grid<Wall>> grids = loadBoardGrids(boardFile);
adjustRobotRotationToBoardRotation(grids.value1, robotList);
return new Board(grids.value1, grids.value2, robotList);
}
Grid<Tile> tileGrid = loadTileGrid(reader, gridWidth, gridHeight);
Grid<Wall> 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<Tile> tileGrid, List<Robot> robotList) {
//The flags are always in the up direction
List<BoardElementContainer<Tile>> 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);
}
}
/**

View File

@ -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();
}
}

View File

@ -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

View File

@ -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());