mirror of
				https://github.com/inf112-v20/Fiasko.git
				synced 2025-11-03 19:23:45 +01:00 
			
		
		
		
	Merge branch 'master' of https://github.com/inf112-v20/Fiasko
This commit is contained in:
		@@ -42,7 +42,6 @@ public class CardChoiceScreen extends InputAdapter implements Screen {
 | 
			
		||||
    private final List<CardRectangle> chosenCards;
 | 
			
		||||
    private final int maxCards;
 | 
			
		||||
    private final Stage stage;
 | 
			
		||||
    final TextButton confirmCards;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Initializes a new card choice screen
 | 
			
		||||
@@ -72,7 +71,7 @@ public class CardChoiceScreen extends InputAdapter implements Screen {
 | 
			
		||||
        stage = new Stage();
 | 
			
		||||
        inputMultiplexer.addProcessor(stage);
 | 
			
		||||
 | 
			
		||||
        confirmCards = new SimpleButton("Confirm cards", roboRallyWrapper.font).getButton();
 | 
			
		||||
        TextButton confirmCards = new SimpleButton("Confirm cards", roboRallyWrapper.font).getButton();
 | 
			
		||||
        stage.addActor(confirmCards);
 | 
			
		||||
        confirmCards.setY(viewport.getWorldHeight() + 60);
 | 
			
		||||
        confirmCards.setX(15);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
 | 
			
		||||
 * This class generates a simple text button using a default skin
 | 
			
		||||
 */
 | 
			
		||||
public class SimpleButton {
 | 
			
		||||
    private TextButton button;
 | 
			
		||||
    private final TextButton button;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new simple button
 | 
			
		||||
 
 | 
			
		||||
@@ -167,6 +167,137 @@ public class Board {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether a given tile is a conveyor belt
 | 
			
		||||
     * @param tile The tile to check
 | 
			
		||||
     * @return True if the tile is a conveyor belt
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isConveyorBelt(Tile tile) {
 | 
			
		||||
        if (tile == null) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        switch (tile.getTileType()) {
 | 
			
		||||
            case CONVEYOR_BELT_SLOW:
 | 
			
		||||
            case CONVEYOR_BELT_FAST:
 | 
			
		||||
            case CONVEYOR_BELT_FAST_LEFT:
 | 
			
		||||
            case CONVEYOR_BELT_FAST_RIGHT:
 | 
			
		||||
            case CONVEYOR_BELT_FAST_SIDE_ENTRANCE_LEFT:
 | 
			
		||||
            case CONVEYOR_BELT_FAST_SIDE_ENTRANCE_RIGHT:
 | 
			
		||||
            case CONVEYOR_BELT_FAST_SIDE_ENTRANCES:
 | 
			
		||||
            case CONVEYOR_BELT_SLOW_LEFT:
 | 
			
		||||
            case CONVEYOR_BELT_SLOW_RIGHT:
 | 
			
		||||
            case CONVEYOR_BELT_SLOW_SIDE_ENTRANCE_LEFT:
 | 
			
		||||
            case CONVEYOR_BELT_SLOW_SIDE_ENTRANCE_RIGHT:
 | 
			
		||||
            case CONVEYOR_BELT_SLOW_SIDE_ENTRANCES:
 | 
			
		||||
                return true;
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Teleports a robot to some position without verification
 | 
			
		||||
     *
 | 
			
		||||
     * Be quite careful about using this method. No validation will me done. The robot will magically disappear from
 | 
			
		||||
     * one position and appear on another, hence the name. This method should only be used when the new position has
 | 
			
		||||
     * been confirmed available.
 | 
			
		||||
     *
 | 
			
		||||
     * @param robotID The id of the robot to teleport
 | 
			
		||||
     * @param newPosition The position the robot should teleport to
 | 
			
		||||
     */
 | 
			
		||||
    public void teleportRobot(RobotID robotID, Position newPosition) {
 | 
			
		||||
        robots.get(robotID).setPosition(newPosition);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether a given conveyor belt is able to move in its direction
 | 
			
		||||
     * @param conveyorBelt The conveyor belt to move
 | 
			
		||||
     * @return True if nothing is blocking its movement
 | 
			
		||||
     */
 | 
			
		||||
    public boolean conveyorBeltCanMove(BoardElementContainer<Tile> conveyorBelt) {
 | 
			
		||||
        if (!isConveyorBelt(conveyorBelt.getElement())) {
 | 
			
		||||
            throw new IllegalArgumentException("Input to function is of invalid tile type.");
 | 
			
		||||
        }
 | 
			
		||||
        Position conveyorBeltPosition = conveyorBelt.getPosition();
 | 
			
		||||
        Direction conveyorBeltDirection = conveyorBelt.getElement().getDirection();
 | 
			
		||||
        //Ignore conveyor belts without a robot
 | 
			
		||||
        if (!hasRobotOnPosition(conveyorBeltPosition)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        Position positionInFront = getNewPosition(conveyorBeltPosition, conveyorBeltDirection);
 | 
			
		||||
        Tile tileInFront = getTileOnPosition(positionInFront);
 | 
			
		||||
        //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;
 | 
			
		||||
        }
 | 
			
		||||
        //There is another robot trying to enter the same crossing
 | 
			
		||||
        if (hasCrossingConflict(positionInFront, conveyorBeltDirection)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        //The way forward seems clear
 | 
			
		||||
        if (!hasRobotOnPosition(positionInFront)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return conveyorBeltCanMove(new BoardElementContainer<>(tileInFront, positionInFront));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether a conveyor belt has anything in front of it preventing it from moving forward
 | 
			
		||||
     * @param conveyorBeltPosition The position of the conveyor belt
 | 
			
		||||
     * @param positionInFront The position in front of the conveyor belt
 | 
			
		||||
     * @param conveyorBeltDirection The direction of the conveyor belt
 | 
			
		||||
     * @return True if the conveyor belt cannot move forward
 | 
			
		||||
     */
 | 
			
		||||
    private boolean hasFrontConflict(Position conveyorBeltPosition, Position positionInFront,
 | 
			
		||||
                                     Direction conveyorBeltDirection) {
 | 
			
		||||
        //The robot cannot be moved because a wall is blocking it
 | 
			
		||||
        if (moveIsStoppedByWall(conveyorBeltPosition, positionInFront, conveyorBeltDirection)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        //The robot cannot move off the conveyor belt because another robot is blocking it
 | 
			
		||||
        if (hasRobotOnPosition(positionInFront)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        Position positionTwoForward = getNewPosition(positionInFront, conveyorBeltDirection);
 | 
			
		||||
        Tile tileTwoForward = getTileOnPosition(positionTwoForward);
 | 
			
		||||
        //If a robot standing on the opposite side of a tile and trying to get to the tile in the middle, none of
 | 
			
		||||
        //the robots should move
 | 
			
		||||
        return (isValidPosition(positionInFront) && isConveyorBelt(tileTwoForward) &&
 | 
			
		||||
                tileTwoForward.getDirection() == Direction.getReverseDirection(conveyorBeltDirection)
 | 
			
		||||
                && hasRobotOnPosition(positionTwoForward));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether a conveyor belt has a conflict in a crossing
 | 
			
		||||
     * @param crossingPosition The position of the crossing
 | 
			
		||||
     * @param conveyorBeltDirection The direction of the conveyor belt
 | 
			
		||||
     * @return True if there is a conflict. False otherwise
 | 
			
		||||
     */
 | 
			
		||||
    private boolean hasCrossingConflict(Position crossingPosition, Direction conveyorBeltDirection) {
 | 
			
		||||
        Position frontLeftPosition = getNewPosition(crossingPosition,
 | 
			
		||||
                Direction.getLeftRotatedDirection(conveyorBeltDirection));
 | 
			
		||||
        Tile frontLeftTile = getTileOnPosition(frontLeftPosition);
 | 
			
		||||
        Position frontRightPosition = getNewPosition(crossingPosition,
 | 
			
		||||
                Direction.getRightRotatedDirection(conveyorBeltDirection));
 | 
			
		||||
        Tile frontRightTile = getTileOnPosition(frontRightPosition);
 | 
			
		||||
        Position twoForwardPosition = getNewPosition(crossingPosition, conveyorBeltDirection);
 | 
			
		||||
        Tile twoForwardTile = getTileOnPosition(twoForwardPosition);
 | 
			
		||||
        //If another robot is standing on a conveyor belt pointing to the conveyor belt in front, a conflict happens
 | 
			
		||||
        return (isValidPosition(frontLeftPosition) && isConveyorBelt(frontLeftTile) && frontLeftTile.getDirection() ==
 | 
			
		||||
                Direction.getRightRotatedDirection(conveyorBeltDirection) && hasRobotOnPosition(frontLeftPosition)) ||
 | 
			
		||||
                (isValidPosition(frontRightPosition) && isConveyorBelt(frontRightTile)
 | 
			
		||||
                        && frontRightTile.getDirection() == Direction.getLeftRotatedDirection(conveyorBeltDirection)
 | 
			
		||||
                        && hasRobotOnPosition(frontRightPosition)) ||
 | 
			
		||||
                (isValidPosition(twoForwardPosition) && isConveyorBelt(twoForwardTile)
 | 
			
		||||
                        && twoForwardTile.getDirection() == Direction.getReverseDirection(conveyorBeltDirection)
 | 
			
		||||
                        && hasRobotOnPosition(twoForwardPosition));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Moves all dead robots to their backups and makes them part of the board again, and if a robot has no lives
 | 
			
		||||
     * it will be removed from the game.
 | 
			
		||||
@@ -316,7 +447,7 @@ public class Board {
 | 
			
		||||
     * @param direction The direction something is going
 | 
			
		||||
     * @return True if a wall would stop its path
 | 
			
		||||
     */
 | 
			
		||||
    boolean moveIsStoppedByWall(Position robotPosition, Position newPosition, Direction direction) {
 | 
			
		||||
    private boolean moveIsStoppedByWall(Position robotPosition, Position newPosition, Direction direction) {
 | 
			
		||||
            return hasWallFacing(robotPosition, direction) || (isValidPosition(newPosition) &&
 | 
			
		||||
                    hasWallFacing(newPosition, Direction.getReverseDirection(direction)));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,10 @@ import inf112.fiasko.roborally.utility.DeckLoaderUtil;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class represent a game which is drawable using libgdx
 | 
			
		||||
@@ -24,9 +25,11 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
    private List<BoardElementContainer<Tile>> conveyorBelts;
 | 
			
		||||
    private List<BoardElementContainer<Tile>> fastConveyorBelts;
 | 
			
		||||
    private List<Player> playerList;
 | 
			
		||||
    private List<BoardElementContainer<Tile>> blacklistedTiles = new ArrayList<>();
 | 
			
		||||
    private List<BoardElementContainer<Tile>> whitelistedTiles = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new robo rally game
 | 
			
		||||
     * @param debug Whether to start the game in debugging mode
 | 
			
		||||
     */
 | 
			
		||||
    public RoboRallyGame(boolean debug) {
 | 
			
		||||
        if (debug) {
 | 
			
		||||
            initializeDebugMode();
 | 
			
		||||
@@ -35,6 +38,9 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new robo rally game
 | 
			
		||||
     */
 | 
			
		||||
    public RoboRallyGame() {
 | 
			
		||||
        initializeGame();
 | 
			
		||||
    }
 | 
			
		||||
@@ -131,7 +137,7 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
                player.setInProgram(testProgram);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            gameBoard = BoardLoaderUtil.loadBoard("boards/Dizzy_Dash.txt", robots);
 | 
			
		||||
            gameBoard = BoardLoaderUtil.loadBoard("boards/Checkmate.txt", robots);
 | 
			
		||||
            cogwheels = gameBoard.getPositionsOfTileOnBoard(TileType.COGWHEEL_RIGHT,
 | 
			
		||||
                    TileType.COGWHEEL_LEFT);
 | 
			
		||||
            fastConveyorBelts = gameBoard.getPositionsOfTileOnBoard(TileType.CONVEYOR_BELT_FAST,
 | 
			
		||||
@@ -260,22 +266,6 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether a given list has at least one element as defined by the predicate
 | 
			
		||||
     * @param list The list to check
 | 
			
		||||
     * @param predicate The predicate to test
 | 
			
		||||
     * @param <T> The type of the list
 | 
			
		||||
     * @return True if the list has at least one element passing the test of the predicate
 | 
			
		||||
     */
 | 
			
		||||
    private static <T> boolean testPredicate(List<T> list, Predicate<T> predicate) {
 | 
			
		||||
        for (T object : list) {
 | 
			
		||||
            if (predicate.test(object)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Moves robots standing on conveyor belts in the direction of the conveyor belt
 | 
			
		||||
     *
 | 
			
		||||
@@ -291,191 +281,60 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Moves all conveyor belts in the input list
 | 
			
		||||
     * @param conveyorBelts A list of conveyor belts to move
 | 
			
		||||
     * Moves a list of conveyor belts
 | 
			
		||||
     * @param conveyorBelts A list of board element containers containing conveyor belts
 | 
			
		||||
     */
 | 
			
		||||
    private void moveConveyorBelts(List<BoardElementContainer<Tile>> conveyorBelts) {
 | 
			
		||||
        List<BoardElementContainer<Tile>> conveyorBeltsWithRobotsThatShouldMove =
 | 
			
		||||
                conveyorBeltsThatCanMoveWithoutConflict(conveyorBelts);
 | 
			
		||||
        for (BoardElementContainer<Tile> conveyorBelt : conveyorBeltsWithRobotsThatShouldMove) {
 | 
			
		||||
 | 
			
		||||
            Direction currentDirection = conveyorBelt.getElement().getDirection();
 | 
			
		||||
            RobotID robot = gameBoard.getRobotOnPosition(conveyorBelt.getPosition());
 | 
			
		||||
            Position newPosition = gameBoard.getNewPosition(conveyorBelt.getPosition(), currentDirection);
 | 
			
		||||
            Tile nextTile = gameBoard.getTileOnPosition(newPosition);
 | 
			
		||||
 | 
			
		||||
            doConveyorBeltMovement(robot, currentDirection, nextTile);
 | 
			
		||||
        Map<RobotID, Position> newPositions = new HashMap<>();
 | 
			
		||||
        Map<RobotID, Boolean> moveNormally = new HashMap<>();
 | 
			
		||||
        for (Robot robot : gameBoard.getAliveRobots()) {
 | 
			
		||||
            newPositions.put(robot.getRobotId(), robot.getPosition());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds conveyor belts that can move without conflict
 | 
			
		||||
     * @param conveyorBelts that should be checked
 | 
			
		||||
     * @return List of conveyor belts that can move robots without conflict
 | 
			
		||||
     */
 | 
			
		||||
    private List<BoardElementContainer<Tile>> conveyorBeltsThatCanMoveWithoutConflict(
 | 
			
		||||
            List<BoardElementContainer<Tile>> conveyorBelts) {
 | 
			
		||||
 | 
			
		||||
        List<BoardElementContainer<Tile>> conveyorBeltsWithRobotsOn = new ArrayList<>();
 | 
			
		||||
        whitelistedTiles.clear();
 | 
			
		||||
        blacklistedTiles.clear();
 | 
			
		||||
 | 
			
		||||
        //Updates hash maps containing robot move information
 | 
			
		||||
        for (BoardElementContainer<Tile> conveyorBelt : conveyorBelts) {
 | 
			
		||||
            if (gameBoard.hasRobotOnPosition(conveyorBelt.getPosition())) {
 | 
			
		||||
                conveyorBeltsWithRobotsOn.add(conveyorBelt);
 | 
			
		||||
            Position conveyorBeltPosition = conveyorBelt.getPosition();
 | 
			
		||||
            Direction conveyorBeltDirection = conveyorBelt.getElement().getDirection();
 | 
			
		||||
            if (gameBoard.conveyorBeltCanMove(conveyorBelt) &&
 | 
			
		||||
                    gameBoard.hasRobotOnPosition(conveyorBeltPosition)) {
 | 
			
		||||
                updateConveyorBeltMaps(conveyorBeltPosition, conveyorBeltDirection, newPositions, moveNormally);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<BoardElementContainer<Tile>> listOfRow = new ArrayList<>();
 | 
			
		||||
        for (BoardElementContainer<Tile> conveyorBeltWithRobot : conveyorBeltsWithRobotsOn) {
 | 
			
		||||
            if (blacklistedTiles.contains(conveyorBeltWithRobot) ||
 | 
			
		||||
                    whitelistedTiles.contains((conveyorBeltWithRobot))) {
 | 
			
		||||
        //Updates position for all robots affected by conveyor belts
 | 
			
		||||
        for (RobotID robotID : RobotID.values()) {
 | 
			
		||||
            if (newPositions.get(robotID) == null || moveNormally.get(robotID) == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            BoardElementContainer<Tile> lastInRow = findLastRobotInRow (conveyorBeltWithRobot, conveyorBeltsWithRobotsOn);
 | 
			
		||||
 | 
			
		||||
            List<BoardElementContainer<Tile>> results = findFirstRobotInRow(lastInRow, conveyorBeltsWithRobotsOn,
 | 
			
		||||
                    listOfRow);
 | 
			
		||||
 | 
			
		||||
            for (BoardElementContainer<Tile> result : results) {
 | 
			
		||||
                if (!whitelistedTiles.contains(result)) {
 | 
			
		||||
                    whitelistedTiles.add(0, result);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return whitelistedTiles;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recursive function to find all robots in a row that should move, and blacklists those that should not
 | 
			
		||||
     * @param currentConveyorBelt The current conveyor belt
 | 
			
		||||
     * @param conveyorBeltsWithRobotsOn List of conveyor belts that have robots on them
 | 
			
		||||
     * @param listOfRow List of conveyor belts in a row with robots on them
 | 
			
		||||
     * @return listOfRow
 | 
			
		||||
     */
 | 
			
		||||
    private List<BoardElementContainer<Tile>> findFirstRobotInRow(BoardElementContainer<Tile> currentConveyorBelt,
 | 
			
		||||
                                     List<BoardElementContainer<Tile>> conveyorBeltsWithRobotsOn,
 | 
			
		||||
                                     List<BoardElementContainer<Tile>> listOfRow) {
 | 
			
		||||
        Position nextPosition = gameBoard.getNewPosition(currentConveyorBelt.getPosition(),
 | 
			
		||||
                currentConveyorBelt.getElement().getDirection());
 | 
			
		||||
        Direction nextDirection = gameBoard.getTileOnPosition(nextPosition).getDirection();
 | 
			
		||||
        Tile nextTile = gameBoard.getTileOnPosition(nextPosition);
 | 
			
		||||
        BoardElementContainer<Tile> nextElementContainer = new BoardElementContainer<>(nextTile, nextPosition);
 | 
			
		||||
        List<BoardElementContainer<Tile>> pointingNeighbours = listOfConveyorBeltsWithRobotPointingAtTile(true,
 | 
			
		||||
                nextElementContainer, conveyorBeltsWithRobotsOn);
 | 
			
		||||
 | 
			
		||||
        listOfRow.add(currentConveyorBelt);
 | 
			
		||||
 | 
			
		||||
        if (blacklistedTiles.contains(nextElementContainer)) {
 | 
			
		||||
            blacklistedTiles.addAll(listOfRow);
 | 
			
		||||
            listOfRow.clear();
 | 
			
		||||
        } else if (currentConveyorBelt.getElement().getDirection() == Direction.getReverseDirection(nextDirection) &&
 | 
			
		||||
                conveyorBeltsWithRobotsOn.contains(nextElementContainer)) {
 | 
			
		||||
            blacklistedTiles.addAll(listOfRow);
 | 
			
		||||
            blacklistedTiles.add(nextElementContainer);
 | 
			
		||||
            listOfRow.clear();
 | 
			
		||||
        } else if ((!conveyorBelts.contains(nextElementContainer)) && gameBoard.hasRobotOnPosition(nextPosition)) {
 | 
			
		||||
            blacklistedTiles.addAll(listOfRow);
 | 
			
		||||
            listOfRow.clear();
 | 
			
		||||
        } else if (gameBoard.moveIsStoppedByWall(currentConveyorBelt.getPosition(), nextPosition,
 | 
			
		||||
                currentConveyorBelt.getElement().getDirection())) {
 | 
			
		||||
            blacklistedTiles.addAll(listOfRow);
 | 
			
		||||
            listOfRow.clear();
 | 
			
		||||
        } else if (pointingNeighbours.size() > 0) {
 | 
			
		||||
            blacklistedTiles.addAll(pointingNeighbours);
 | 
			
		||||
            blacklistedTiles.addAll(listOfRow);
 | 
			
		||||
            listOfRow.clear();
 | 
			
		||||
        } else if ((conveyorBeltsWithRobotsOn.contains(nextElementContainer))) {
 | 
			
		||||
            listOfRow = findFirstRobotInRow(nextElementContainer, conveyorBeltsWithRobotsOn, listOfRow);
 | 
			
		||||
        }
 | 
			
		||||
        return listOfRow;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Recursive function that finds the last robot in a row with conveyor belts without conflicts
 | 
			
		||||
     * @param currentConveyorBelt The current conveyor belt
 | 
			
		||||
     * @param conveyorBeltsWithRobotsOn List with conveyor belts that have robots on them
 | 
			
		||||
     * @return The last conveyor belt with a robot without conflict in a row
 | 
			
		||||
     */
 | 
			
		||||
    private BoardElementContainer<Tile> findLastRobotInRow(BoardElementContainer<Tile> currentConveyorBelt,
 | 
			
		||||
                                    List<BoardElementContainer<Tile>> conveyorBeltsWithRobotsOn) {
 | 
			
		||||
        List<BoardElementContainer<Tile>> listOfConveyorBeltsWithRobotPointingAtTile =
 | 
			
		||||
                listOfConveyorBeltsWithRobotPointingAtTile(false, currentConveyorBelt,
 | 
			
		||||
                        conveyorBeltsWithRobotsOn);
 | 
			
		||||
        int sizeOfPointingList = listOfConveyorBeltsWithRobotPointingAtTile.size();
 | 
			
		||||
        if (sizeOfPointingList == 0) {
 | 
			
		||||
            return currentConveyorBelt;
 | 
			
		||||
        } else if (sizeOfPointingList == 1) {
 | 
			
		||||
            return findLastRobotInRow(listOfConveyorBeltsWithRobotPointingAtTile.get(0), conveyorBeltsWithRobotsOn);
 | 
			
		||||
            if (moveNormally.get(robotID)) {
 | 
			
		||||
                gameBoard.moveRobot(robotID, gameBoard.getTileOnPosition(newPositions.get(robotID)).getDirection());
 | 
			
		||||
            } else {
 | 
			
		||||
            blacklistedTiles.addAll(listOfConveyorBeltsWithRobotPointingAtTile);
 | 
			
		||||
            return currentConveyorBelt;
 | 
			
		||||
                gameBoard.teleportRobot(robotID, newPositions.get(robotID));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds all neighbouring conveyor belt tiles with robots that are pointing on the current tile
 | 
			
		||||
     * @param forward True if looking forward, false otherwise
 | 
			
		||||
     * @param currentTile The current tile
 | 
			
		||||
     * @param conveyorBeltsWithRobots List with conveyor belts that have robots on them
 | 
			
		||||
     * @return A list of the neighbouring conveyor belt tiles with robots that are pointing on the current tile
 | 
			
		||||
     * Updates maps containing information about what a robot on a conveyor belt should do
 | 
			
		||||
     * @param conveyorBeltPosition The position of the conveyor belt the robot stands on
 | 
			
		||||
     * @param conveyorBeltDirection The direction of the conveyor belt the robot stands on
 | 
			
		||||
     * @param newPositions The map containing new positions for robots
 | 
			
		||||
     * @param moveNormally The map containing whether a robot should move normally following normal rules
 | 
			
		||||
     */
 | 
			
		||||
    private List<BoardElementContainer<Tile>> listOfConveyorBeltsWithRobotPointingAtTile(Boolean forward,
 | 
			
		||||
                                                                             BoardElementContainer<Tile> currentTile,
 | 
			
		||||
                                                            List<BoardElementContainer<Tile>> conveyorBeltsWithRobots) {
 | 
			
		||||
        List<BoardElementContainer<Tile>> possibleConflictConveyorBelts = new ArrayList<>();
 | 
			
		||||
        Tile conveyorBeltTile = currentTile.getElement();
 | 
			
		||||
        Position currentPosition = currentTile.getPosition();
 | 
			
		||||
        Direction currentDirection;
 | 
			
		||||
 | 
			
		||||
        if (forward) {
 | 
			
		||||
            currentDirection = conveyorBeltTile.getDirection();
 | 
			
		||||
        } else currentDirection = Direction.getReverseDirection(conveyorBeltTile.getDirection());
 | 
			
		||||
 | 
			
		||||
        Position nextPositionStraight = gameBoard.getNewPosition(currentPosition, currentDirection);
 | 
			
		||||
        Tile nextTileStraight = gameBoard.getTileOnPosition(nextPositionStraight);
 | 
			
		||||
        Position nextPositionLeft = gameBoard.getNewPosition(currentPosition,
 | 
			
		||||
                Direction.getLeftRotatedDirection(currentDirection));
 | 
			
		||||
        Tile nextTileLeft = gameBoard.getTileOnPosition(nextPositionLeft);
 | 
			
		||||
        Position nextPositionRight = gameBoard.getNewPosition(currentPosition,
 | 
			
		||||
                Direction.getRightRotatedDirection(currentDirection));
 | 
			
		||||
        Tile nextTileRight = gameBoard.getTileOnPosition(nextPositionRight);
 | 
			
		||||
 | 
			
		||||
        BoardElementContainer<Tile> rightOfCurrent = new BoardElementContainer<>(nextTileRight, nextPositionRight);
 | 
			
		||||
        BoardElementContainer<Tile> leftOfCurrent = new BoardElementContainer<>(nextTileLeft, nextPositionLeft);
 | 
			
		||||
        BoardElementContainer<Tile> inFrontOfCurrent = new BoardElementContainer<>(nextTileStraight, nextPositionStraight);
 | 
			
		||||
 | 
			
		||||
        if (currentDirection == Direction.getReverseDirection(
 | 
			
		||||
                nextTileStraight.getDirection()) && conveyorBeltsWithRobots.contains(inFrontOfCurrent)) {
 | 
			
		||||
            possibleConflictConveyorBelts.add(inFrontOfCurrent);
 | 
			
		||||
        }
 | 
			
		||||
        if (currentDirection == Direction.getLeftRotatedDirection(
 | 
			
		||||
                nextTileLeft.getDirection()) && conveyorBeltsWithRobots.contains(leftOfCurrent)) {
 | 
			
		||||
            possibleConflictConveyorBelts.add(leftOfCurrent);
 | 
			
		||||
        }
 | 
			
		||||
        if (currentDirection == Direction.getRightRotatedDirection(
 | 
			
		||||
                nextTileRight.getDirection()) && conveyorBeltsWithRobots.contains(rightOfCurrent)) {
 | 
			
		||||
            possibleConflictConveyorBelts.add(rightOfCurrent);
 | 
			
		||||
        }
 | 
			
		||||
        return possibleConflictConveyorBelts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Moves a robot standing on a conveyor belt
 | 
			
		||||
     * @param robot The id of the robot to move
 | 
			
		||||
     * @param currentDirection The direction of the conveyor belt the robot is standing on
 | 
			
		||||
     * @param nextTile The tile the robot is moving to
 | 
			
		||||
     */
 | 
			
		||||
    private void doConveyorBeltMovement(RobotID robot, Direction currentDirection, Tile nextTile) {
 | 
			
		||||
        Direction nextDirection = nextTile.getDirection();
 | 
			
		||||
        gameBoard.moveRobot(robot, currentDirection);
 | 
			
		||||
        if (testPredicate(conveyorBelts, (container) -> container.getElement() == nextTile)) {
 | 
			
		||||
            if (Direction.getRightRotatedDirection(nextDirection) == currentDirection) {
 | 
			
		||||
                gameBoard.rotateRobotLeft(robot);
 | 
			
		||||
            } else if (Direction.getLeftRotatedDirection(nextDirection) == currentDirection) {
 | 
			
		||||
                gameBoard.rotateRobotRight(robot);
 | 
			
		||||
    private void updateConveyorBeltMaps(Position conveyorBeltPosition, Direction conveyorBeltDirection,
 | 
			
		||||
                     Map<RobotID, Position> newPositions, Map<RobotID, Boolean> moveNormally) {
 | 
			
		||||
        RobotID robotAtConveyorBelt = gameBoard.getRobotOnPosition(conveyorBeltPosition);
 | 
			
		||||
        Position newPosition = gameBoard.getNewPosition(conveyorBeltPosition, conveyorBeltDirection);
 | 
			
		||||
        if (gameBoard.isConveyorBelt(gameBoard.getTileOnPosition(newPosition))) {
 | 
			
		||||
            newPositions.put(robotAtConveyorBelt, newPosition);
 | 
			
		||||
            moveNormally.put(robotAtConveyorBelt, false);
 | 
			
		||||
            Direction newDirection = gameBoard.getTileOnPosition(newPosition).getDirection();
 | 
			
		||||
            if (Direction.getRightRotatedDirection(newDirection) == conveyorBeltDirection) {
 | 
			
		||||
                gameBoard.rotateRobotLeft(robotAtConveyorBelt);
 | 
			
		||||
            } else if (Direction.getLeftRotatedDirection(newDirection) == conveyorBeltDirection) {
 | 
			
		||||
                gameBoard.rotateRobotRight(robotAtConveyorBelt);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            newPositions.put(robotAtConveyorBelt, conveyorBeltPosition);
 | 
			
		||||
            moveNormally.put(robotAtConveyorBelt, true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -515,7 +374,7 @@ public class RoboRallyGame implements IDrawableGame {
 | 
			
		||||
        for (Player player : playerList) {
 | 
			
		||||
            List<ProgrammingCard> playerProgram = player.getProgram();
 | 
			
		||||
            if (!playerProgram.isEmpty()) {
 | 
			
		||||
                ProgrammingCard programmingCard = playerProgram.get(phase);
 | 
			
		||||
                ProgrammingCard programmingCard = playerProgram.get(phase - 1);
 | 
			
		||||
                originalPriority.add(programmingCard.getPriority());
 | 
			
		||||
                robotsToDoAction.add(player.getRobotID());
 | 
			
		||||
                programToBeRun.add(programmingCard);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user