diff --git a/src/main/java/inf112/fiasko/roborally/objects/Board.java b/src/main/java/inf112/fiasko/roborally/objects/Board.java index 3550bae..0b633f2 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Board.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Board.java @@ -329,16 +329,18 @@ public class Board { return true; } Position positionInFront = getNewPosition(conveyorBeltPosition, conveyorBeltDirection); - Tile tileInFront = getTileOnPosition(positionInFront); + //The tile in front of the robot is not a conveyor belt and has something on it stopping the conveyor belt + if ((!isValidPosition(positionInFront) && moveIsStoppedByWall(conveyorBeltPosition, positionInFront, + conveyorBeltDirection)) || (isValidPosition(positionInFront) && + !isConveyorBelt(getTileOnPosition(positionInFront)) && + hasFrontConflict(conveyorBeltPosition, positionInFront, conveyorBeltDirection))) { + return false; + } //If a conveyor belt will move the robot outside the map, the move is valid if (!isValidPosition(positionInFront)) { return true; } - //The tile in front of the robot is not a conveyor belt and has something on it stopping the conveyor belt - if (!isConveyorBelt(tileInFront) && - hasFrontConflict(conveyorBeltPosition, positionInFront, conveyorBeltDirection)) { - return false; - } + Tile tileInFront = getTileOnPosition(positionInFront); //There is another robot trying to enter the same crossing if (hasCrossingConflict(positionInFront, conveyorBeltDirection)) { return false; @@ -564,7 +566,7 @@ public class Board { * @param position The position to test * @return True if the position is valid. False otherwise */ - private boolean isValidPosition(Position position) { + public boolean isValidPosition(Position position) { return position.getXCoordinate() >= 0 && position.getXCoordinate() < boardWidth && position.getYCoordinate() >= 0 diff --git a/src/main/java/inf112/fiasko/roborally/objects/DrawableGame.java b/src/main/java/inf112/fiasko/roborally/objects/DrawableGame.java index b506062..2faf1be 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/DrawableGame.java +++ b/src/main/java/inf112/fiasko/roborally/objects/DrawableGame.java @@ -57,4 +57,11 @@ public interface DrawableGame { * @return A list of all robots to draw */ List getRobotsToDraw(); + + /** + * Gets a list of active players to receive information about player names + * + * @return A list of players + */ + List getPlayers(); } diff --git a/src/main/java/inf112/fiasko/roborally/objects/Phase.java b/src/main/java/inf112/fiasko/roborally/objects/Phase.java index f421407..616d23b 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/Phase.java +++ b/src/main/java/inf112/fiasko/roborally/objects/Phase.java @@ -50,6 +50,7 @@ public class Phase { * @throws InterruptedException If interrupted wile trying to sleep */ public void runPhase(int phaseNumber) throws InterruptedException { + sleep(); runProgrammingCards(phaseNumber); moveAllConveyorBelts(); @@ -83,6 +84,7 @@ public class Phase { * @throws InterruptedException If it gets interrupted while trying to sleep */ public void fireAllLasers() throws InterruptedException { + sleep(); gameBoard.fireAllLasers(); sleep(); gameBoard.doLaserCleanup(); @@ -121,15 +123,16 @@ public class Phase { * @throws InterruptedException If interrupted while sleeping. */ public void rotateCogwheels() throws InterruptedException { + sleep(); for (BoardElementContainer cogwheel : cogwheels) { if (!gameBoard.hasRobotOnPosition(cogwheel.getPosition())) { continue; } - sleep(); + RobotID robotAtCogwheel = gameBoard.getRobotOnPosition(cogwheel.getPosition()); if (cogwheel.getElement().getTileType() == TileType.COGWHEEL_RIGHT) { - gameBoard.rotateRobotRight(gameBoard.getRobotOnPosition(cogwheel.getPosition())); + gameBoard.rotateRobotRight(robotAtCogwheel); } else { - gameBoard.rotateRobotLeft(gameBoard.getRobotOnPosition(cogwheel.getPosition())); + gameBoard.rotateRobotLeft(robotAtCogwheel); } } } @@ -267,7 +270,7 @@ public class Phase { Map newPositions, Map moveNormally) { RobotID robotAtConveyorBelt = gameBoard.getRobotOnPosition(conveyorBeltPosition); Position newPosition = gameBoard.getNewPosition(conveyorBeltPosition, conveyorBeltDirection); - if (gameBoard.isConveyorBelt(gameBoard.getTileOnPosition(newPosition))) { + if (gameBoard.isValidPosition(newPosition) && gameBoard.isConveyorBelt(gameBoard.getTileOnPosition(newPosition))) { newPositions.put(robotAtConveyorBelt, newPosition); moveNormally.put(robotAtConveyorBelt, false); Direction newDirection = gameBoard.getTileOnPosition(newPosition).getDirection(); diff --git a/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java b/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java index b4e6023..53bd5ef 100644 --- a/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java +++ b/src/main/java/inf112/fiasko/roborally/objects/RoboRallyGame.java @@ -114,6 +114,11 @@ public class RoboRallyGame implements DrawableGame, InteractableGame { return gameBoard.getAliveRobots(); } + @Override + public List getPlayers() { + return new ArrayList<>(this.playerList); + } + @Override public GameState getGameState() { return gameState; diff --git a/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java b/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java index d2001a2..fb79226 100644 --- a/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java +++ b/src/test/java/inf112/fiasko/roborally/objects/PhaseTest.java @@ -310,4 +310,199 @@ public class PhaseTest { assertEquals(robot5.getRobotId(), board.getRobotOnPosition(new Position(2, 12))); assertEquals(robot6.getRobotId(), board.getRobotOnPosition(new Position(2, 14))); } + + @Test + public void robotsOnConveyorBeltsFacingTheSameEmptyTileDoesNotMove() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(8, 11))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(7, 10))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(8, 11))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(7, 10))); + } + + @Test + public void robotsOnConveyorBeltsFacingTheSameHoleTileDoesNotMove() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(6, 7))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(7, 8))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(6, 7))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(7, 8))); + } + + @Test + public void robotOnConveyorBeltsFacingWallDoesNotMove() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(1, 1))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(1, 1))); + } + + @Test + public void robotBehindAnotherRobotOnConveyorBeltsFacingWallDoesNotMove() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(1, 1))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(1, 2))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(1, 1))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(1, 2))); + } + + @Test + public void robotBehindOtherRobotsOnSlowConveyorBeltsFacingEmptyTilesMoves() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(5, 7))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(5, 8))); + robots.add(new Robot(RobotID.ROBOT_3, new Position(5, 9))); + robots.add(new Robot(RobotID.ROBOT_4, new Position(5, 10))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + players.add(new Player(RobotID.ROBOT_3, "Player 3")); + players.add(new Player(RobotID.ROBOT_4, "Player 4")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(5, 6))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(5, 7))); + assertEquals(RobotID.ROBOT_3, board.getRobotOnPosition(new Position(5, 8))); + assertEquals(RobotID.ROBOT_4, board.getRobotOnPosition(new Position(5, 9))); + } + + @Test + public void robotBehindOtherRobotsOnFastConveyorBeltsFacingEmptyTilesMoves() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(4, 7))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(4, 8))); + robots.add(new Robot(RobotID.ROBOT_3, new Position(4, 9))); + robots.add(new Robot(RobotID.ROBOT_4, new Position(4, 10))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + players.add(new Player(RobotID.ROBOT_3, "Player 3")); + players.add(new Player(RobotID.ROBOT_4, "Player 4")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(4, 5))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(4, 6))); + assertEquals(RobotID.ROBOT_3, board.getRobotOnPosition(new Position(4, 7))); + assertEquals(RobotID.ROBOT_4, board.getRobotOnPosition(new Position(4, 8))); + } + + @Test + public void robotBehindOtherRobotsOnConveyorBeltsShapedAsARoundaboutMoves() { + long startTime = System.currentTimeMillis(); + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(1, 8))); + robots.add(new Robot(RobotID.ROBOT_2, new Position(2, 8))); + robots.add(new Robot(RobotID.ROBOT_3, new Position(2, 9))); + robots.add(new Robot(RobotID.ROBOT_4, new Position(1, 9))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + players.add(new Player(RobotID.ROBOT_2, "Player 2")); + players.add(new Player(RobotID.ROBOT_3, "Player 3")); + players.add(new Player(RobotID.ROBOT_4, "Player 4")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertEquals(RobotID.ROBOT_1, board.getRobotOnPosition(new Position(1, 9))); + assertEquals(RobotID.ROBOT_2, board.getRobotOnPosition(new Position(1, 8))); + assertEquals(RobotID.ROBOT_3, board.getRobotOnPosition(new Position(2, 8))); + assertEquals(RobotID.ROBOT_4, board.getRobotOnPosition(new Position(2, 9))); + int elapsedTime = (int) Math.floor((System.currentTimeMillis() - startTime) / 1000f); + assertTrue(elapsedTime < 1); + } + + @Test + public void robotOnConveyorBeltFacingHoleMovesAndDies() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(6, 7))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertFalse(board.isRobotAlive(RobotID.ROBOT_1)); + assertNull(board.getRobotOnPosition(new Position(6, 7))); + assertNull(board.getRobotOnPosition(new Position(7, 7))); + } + + @Test + public void robotOnConveyorBeltFacingOutOfMapMovesAndDies() { + List robots = new ArrayList<>(); + List players = new ArrayList<>(); + robots.add(new Robot(RobotID.ROBOT_1, new Position(7, 0))); + players.add(new Player(RobotID.ROBOT_1, "Player 1")); + + try { + board = BoardLoaderUtil.loadBoard("boards/test_board.txt", robots); + Phase testPhase = new Phase(board, players, 0, null); + testPhase.moveAllConveyorBelts(); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + assertFalse(board.isRobotAlive(RobotID.ROBOT_1)); + assertNull(board.getRobotOnPosition(new Position(7, 0))); + } } diff --git a/src/test/resources/boards/test_board.txt b/src/test/resources/boards/test_board.txt index 62da8c2..2eaf55c 100644 --- a/src/test/resources/boards/test_board.txt +++ b/src/test/resources/boards/test_board.txt @@ -1,17 +1,17 @@ 12 12 -01;01 05;01 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 01;01 01;01 +01;01 01;01 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 02;01 01;01 01;01 -01;01 05;03 01;01 05;07 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 +01;01 05;01 01;01 05;07 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 11;01 01;01 01;01 01;01 01;01 01;01 01;01 -01;01 01;01 01;01 01;01 01;01 12;07 11;07 01;01 01;01 04;01 01;01 01;01 -01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 +01;01 01;01 01;01 01;01 11;01 12;07 11;07 01;01 01;01 04;01 01;01 01;01 +01;01 01;01 01;01 01;01 11;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 11;01 05;01 05;03 02;01 01;01 03;01 01;01 01;01 01;01 07;05 07;07 01;01 11;01 05;01 01;01 05;01 01;01 01;01 01;01 01;01 01;01 07;03 07;01 01;01 11;01 05;01 01;01 01;01 01;01 01;01 01;01 01;01 -01;01 01;01 01;01 01;01 11;01 05;01 01;01 01;01 01;01 01;01 01;01 01;01 -01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 -0 1;1 0 0 0 0 0 0 0 0 0 0 +01;01 01;01 01;01 01;01 11;01 05;01 01;01 05;03 01;01 01;01 01;01 01;01 +01;01 01;01 01;01 01;01 01;01 01;01 01;01 01;01 05;01 01;01 01;01 01;01 +0 1;5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0