2020-03-02 18:46:45 +01:00
|
|
|
package inf112.fiasko.roborally.objects;
|
2020-02-04 17:52:17 +01:00
|
|
|
|
2020-03-24 12:03:17 +01:00
|
|
|
import inf112.fiasko.roborally.element_properties.Action;
|
|
|
|
import inf112.fiasko.roborally.element_properties.Direction;
|
|
|
|
import inf112.fiasko.roborally.element_properties.Position;
|
|
|
|
import inf112.fiasko.roborally.element_properties.RobotID;
|
|
|
|
import inf112.fiasko.roborally.element_properties.TileType;
|
2020-02-22 23:36:01 +01:00
|
|
|
import inf112.fiasko.roborally.utility.BoardLoaderUtil;
|
2020-03-24 15:26:20 +01:00
|
|
|
import inf112.fiasko.roborally.utility.DeckLoaderUtil;
|
2020-01-31 13:53:08 +01:00
|
|
|
|
2020-02-22 23:36:01 +01:00
|
|
|
import java.io.IOException;
|
2020-02-03 14:10:52 +01:00
|
|
|
import java.util.ArrayList;
|
2020-03-24 21:13:21 +01:00
|
|
|
import java.util.Collections;
|
2020-03-25 13:36:35 +01:00
|
|
|
import java.util.HashMap;
|
2020-01-31 13:53:08 +01:00
|
|
|
import java.util.List;
|
2020-03-25 13:36:35 +01:00
|
|
|
import java.util.Map;
|
2020-02-24 18:07:26 +01:00
|
|
|
import java.util.concurrent.TimeUnit;
|
2020-01-31 13:53:08 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This class represent a game which is drawable using libgdx
|
|
|
|
*/
|
2020-03-02 18:46:45 +01:00
|
|
|
public class RoboRallyGame implements IDrawableGame {
|
2020-02-22 23:36:01 +01:00
|
|
|
private Board gameBoard;
|
2020-03-16 17:55:38 +01:00
|
|
|
private List<BoardElementContainer<Tile>> cogwheels;
|
|
|
|
private List<BoardElementContainer<Tile>> conveyorBelts;
|
2020-03-16 19:37:21 +01:00
|
|
|
private List<BoardElementContainer<Tile>> fastConveyorBelts;
|
2020-03-24 14:02:03 +01:00
|
|
|
private List<Player> playerList;
|
2020-03-30 18:32:55 +02:00
|
|
|
private final boolean host;
|
2020-03-31 15:52:03 +02:00
|
|
|
private Deck<ProgrammingCard> mainDeck;
|
2020-03-25 09:58:42 +01:00
|
|
|
/**
|
|
|
|
* Instantiates a new robo rally game
|
|
|
|
* @param debug Whether to start the game in debugging mode
|
|
|
|
*/
|
2020-03-02 18:46:45 +01:00
|
|
|
public RoboRallyGame(boolean debug) {
|
2020-03-30 18:32:55 +02:00
|
|
|
this.host=false;
|
2020-02-27 16:44:06 +01:00
|
|
|
if (debug) {
|
|
|
|
initializeDebugMode();
|
|
|
|
} else {
|
|
|
|
initializeGame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-25 09:58:42 +01:00
|
|
|
/**
|
|
|
|
* Instantiates a new robo rally game
|
|
|
|
*/
|
2020-03-02 18:46:45 +01:00
|
|
|
public RoboRallyGame() {
|
2020-03-30 18:32:55 +02:00
|
|
|
this.host=false;
|
2020-02-27 16:44:06 +01:00
|
|
|
initializeGame();
|
|
|
|
}
|
|
|
|
|
2020-02-28 19:46:40 +01:00
|
|
|
@Override
|
|
|
|
public int getWidth() {
|
|
|
|
return gameBoard.getBoardWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int getHeight() {
|
|
|
|
return gameBoard.getBoardHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<Tile> getTilesToDraw() {
|
|
|
|
return gameBoard.getTiles();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<Wall> getWallsToDraw() {
|
|
|
|
return gameBoard.getWalls();
|
|
|
|
}
|
|
|
|
|
2020-03-23 13:42:48 +01:00
|
|
|
@Override
|
|
|
|
public List<Particle> getParticlesToDraw() {
|
|
|
|
return gameBoard.getParticles();
|
|
|
|
}
|
|
|
|
|
2020-02-28 19:46:40 +01:00
|
|
|
@Override
|
|
|
|
public List<Robot> getRobotsToDraw() {
|
|
|
|
return gameBoard.getAliveRobots();
|
|
|
|
}
|
|
|
|
|
2020-03-10 17:29:36 +01:00
|
|
|
/**
|
|
|
|
* Makes the game thread wait a given time amount before continuing.
|
|
|
|
* @throws InterruptedException If interrupted while trying to sleep.
|
|
|
|
*/
|
|
|
|
private void sleep() throws InterruptedException {
|
|
|
|
long cycleDelay = 600;
|
|
|
|
TimeUnit.MILLISECONDS.sleep(cycleDelay);
|
|
|
|
}
|
2020-02-28 19:46:40 +01:00
|
|
|
/**
|
|
|
|
* Initializes the game with a debugging board
|
|
|
|
*/
|
2020-02-27 16:44:06 +01:00
|
|
|
private void initializeDebugMode() {
|
|
|
|
List<Robot> robots = new ArrayList<>();
|
2020-03-19 13:46:45 +01:00
|
|
|
robots.add(new Robot(RobotID.ROBOT_1, new Position(0, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_2, new Position(1, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_3, new Position(2, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_4, new Position(3, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_5, new Position(4, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_6, new Position(5, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_7, new Position(6, 18)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_8, new Position(7, 18)));
|
2020-02-27 16:44:06 +01:00
|
|
|
try {
|
|
|
|
gameBoard = BoardLoaderUtil.loadBoard("boards/all_tiles_test_board.txt", robots);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-28 19:46:40 +01:00
|
|
|
/**
|
|
|
|
* Initializes the game with a playable board
|
|
|
|
*/
|
2020-02-27 16:44:06 +01:00
|
|
|
private void initializeGame() {
|
2020-02-22 23:36:01 +01:00
|
|
|
try {
|
|
|
|
List<Robot> robots = new ArrayList<>();
|
2020-02-24 18:07:26 +01:00
|
|
|
robots.add(new Robot(RobotID.ROBOT_1, new Position(1, 1)));
|
2020-02-24 23:35:58 +01:00
|
|
|
robots.add(new Robot(RobotID.ROBOT_2, new Position(1, 2)));
|
2020-02-26 19:45:39 +01:00
|
|
|
robots.add(new Robot(RobotID.ROBOT_3, new Position(1, 3)));
|
2020-03-17 22:00:56 +01:00
|
|
|
robots.add(new Robot(RobotID.ROBOT_4, new Position(4, 8)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_5, new Position(6, 6)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_6, new Position(7, 7)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_7, new Position(6, 7)));
|
|
|
|
robots.add(new Robot(RobotID.ROBOT_8, new Position(6, 8)));
|
2020-03-24 15:26:20 +01:00
|
|
|
|
2020-03-26 13:07:53 +01:00
|
|
|
initializePlayers();
|
2020-03-25 13:36:35 +01:00
|
|
|
gameBoard = BoardLoaderUtil.loadBoard("boards/Checkmate.txt", robots);
|
2020-03-26 13:07:53 +01:00
|
|
|
generateTileLists();
|
2020-03-31 15:52:03 +02:00
|
|
|
mainDeck = DeckLoaderUtil.loadProgrammingCardsDeck();
|
2020-03-16 17:31:54 +01:00
|
|
|
|
2020-02-24 18:07:26 +01:00
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
runGameLoop();
|
|
|
|
} catch (InterruptedException e) {
|
2020-02-26 08:10:46 +01:00
|
|
|
Thread.currentThread().interrupt();
|
2020-02-24 18:07:26 +01:00
|
|
|
}
|
|
|
|
}).start();
|
2020-02-22 23:36:01 +01:00
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2020-01-31 13:53:08 +01:00
|
|
|
|
2020-03-26 13:07:53 +01:00
|
|
|
/**
|
|
|
|
* Initializes all players
|
|
|
|
* @throws IOException If interrupted while trying to sleep
|
|
|
|
*/
|
|
|
|
private void initializePlayers() throws IOException {
|
|
|
|
playerList = new ArrayList<>();
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_1, "Player1"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_2, "Player2"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_3, "Player3"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_4, "Player4"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_5, "Player5"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_6, "Player6"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_7, "Player7"));
|
|
|
|
playerList.add(new Player(RobotID.ROBOT_8, "Player8"));
|
|
|
|
Deck<ProgrammingCard> cards = DeckLoaderUtil.loadProgrammingCardsDeck();
|
|
|
|
for (Player player : playerList) {
|
|
|
|
cards.shuffle();
|
|
|
|
List<ProgrammingCard> testProgram = new ArrayList<>();
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
cards.shuffle();
|
|
|
|
testProgram.add(cards.peekTop());
|
|
|
|
}
|
|
|
|
player.setInProgram(testProgram);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates lists containing board element containers with all tiles of certain types
|
|
|
|
*/
|
|
|
|
private void generateTileLists() {
|
|
|
|
cogwheels = gameBoard.getPositionsOfTileOnBoard(TileType.COGWHEEL_RIGHT,
|
|
|
|
TileType.COGWHEEL_LEFT);
|
|
|
|
fastConveyorBelts = gameBoard.getPositionsOfTileOnBoard(TileType.CONVEYOR_BELT_FAST,
|
|
|
|
TileType.CONVEYOR_BELT_FAST_RIGHT, TileType.CONVEYOR_BELT_FAST_LEFT,
|
|
|
|
TileType.CONVEYOR_BELT_FAST_SIDE_ENTRANCE_RIGHT,
|
|
|
|
TileType.CONVEYOR_BELT_FAST_SIDE_ENTRANCE_LEFT,
|
|
|
|
TileType.CONVEYOR_BELT_FAST_SIDE_ENTRANCES);
|
|
|
|
conveyorBelts = new ArrayList<>();
|
|
|
|
conveyorBelts.addAll(fastConveyorBelts);
|
|
|
|
conveyorBelts.addAll(gameBoard.getPositionsOfTileOnBoard(TileType.CONVEYOR_BELT_SLOW,
|
|
|
|
TileType.CONVEYOR_BELT_SLOW_RIGHT, TileType.CONVEYOR_BELT_SLOW_LEFT,
|
|
|
|
TileType.CONVEYOR_BELT_SLOW_SIDE_ENTRANCE_RIGHT,
|
|
|
|
TileType.CONVEYOR_BELT_SLOW_SIDE_ENTRANCE_LEFT,
|
|
|
|
TileType.CONVEYOR_BELT_SLOW_SIDE_ENTRANCES));
|
|
|
|
}
|
|
|
|
|
2020-02-24 22:27:19 +01:00
|
|
|
/**
|
|
|
|
* Does whatever the game wants to do
|
|
|
|
* @throws InterruptedException If interrupted while trying to sleep
|
|
|
|
*/
|
2020-02-24 18:07:26 +01:00
|
|
|
private void runGameLoop() throws InterruptedException {
|
2020-02-24 22:27:19 +01:00
|
|
|
TimeUnit.SECONDS.sleep(3);
|
2020-03-24 15:26:20 +01:00
|
|
|
runPhase(1);
|
|
|
|
runPhase(2);
|
|
|
|
runPhase(3);
|
|
|
|
runPhase(4);
|
2020-03-25 13:38:33 +01:00
|
|
|
runPhase(5);
|
2020-03-30 18:32:55 +02:00
|
|
|
respawnRobots();
|
2020-03-10 17:29:36 +01:00
|
|
|
}
|
|
|
|
|
2020-03-31 14:34:46 +02:00
|
|
|
/**
|
|
|
|
* Runs all the steps of one turn in the game
|
|
|
|
* @throws InterruptedException If interrupted while trying to sleep
|
|
|
|
*/
|
|
|
|
private void runTurn() throws InterruptedException {
|
|
|
|
// The method should follow this sequence:
|
|
|
|
/*
|
|
|
|
Tilegne programeringskort
|
|
|
|
|
|
|
|
Programmer roboten
|
|
|
|
|
|
|
|
Gå i power down
|
|
|
|
|
|
|
|
Kjør 5 faser
|
|
|
|
|
|
|
|
Flagg + reprasjonstiles reparerer
|
|
|
|
|
|
|
|
Fjerner ulåste programmeringskort
|
|
|
|
|
|
|
|
Spør om de i power down skal fortsette i power down
|
|
|
|
|
|
|
|
Respawn roboter
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Sets the power down status to true on robots that have players who planned one this turn.
|
|
|
|
// Resets players power down for next turn to false.
|
|
|
|
updateRobotPowerDown();
|
|
|
|
// Set damage of robots in power down to 0
|
|
|
|
gameBoard.executePowerdown();
|
|
|
|
if (host) {
|
|
|
|
// TODO: Distribute programming cards to players not in power down
|
2020-03-31 15:52:03 +02:00
|
|
|
distributeProgrammingCardsToPlayers();
|
2020-03-31 14:34:46 +02:00
|
|
|
}
|
|
|
|
// TODO: Make program for this player, if not in power down
|
|
|
|
// TODO: Ask player for new power down
|
|
|
|
// Run the phases of the game
|
|
|
|
runPhase(1);
|
|
|
|
runPhase(2);
|
|
|
|
runPhase(3);
|
|
|
|
runPhase(4);
|
|
|
|
runPhase(5);
|
|
|
|
|
|
|
|
// Repair robots on repair tiles
|
2020-03-31 14:36:38 +02:00
|
|
|
repairAllRobotsOnRepairTiles();
|
2020-03-31 15:52:03 +02:00
|
|
|
// TODO: Update locked cards deck
|
2020-03-31 14:34:46 +02:00
|
|
|
// TODO: Remove non-locked programming cards
|
|
|
|
// TODO: If this player is in power down, ask if it shall continue
|
|
|
|
// Respawn dead robots, as long as they have more lives left
|
|
|
|
respawnRobots();
|
|
|
|
}
|
|
|
|
|
2020-03-31 15:52:03 +02:00
|
|
|
private void distributeProgrammingCardsToPlayers() {
|
|
|
|
int robotDamage;
|
|
|
|
ProgrammingCardDeck playerDeck;
|
|
|
|
mainDeck.shuffle();
|
|
|
|
|
|
|
|
for (Player player : playerList) {
|
|
|
|
RobotID robot = player.getRobotID();
|
|
|
|
playerDeck = player.getPlayerDeck();
|
|
|
|
if (gameBoard.getPowerDown(robot)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
robotDamage = gameBoard.getRobotDamage(robot);
|
|
|
|
if (robotDamage >= 9) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (playerDeck.isEmpty()) {
|
|
|
|
playerDeck.draw(mainDeck,9-robotDamage);
|
|
|
|
} else throw new IllegalStateException("Player deck must be empty!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-24 12:24:25 +01:00
|
|
|
/**
|
|
|
|
* Runs one phase as defined in the Robo Rally rulebook
|
|
|
|
* @param phaseNumber The number of the phase to run
|
|
|
|
* @throws InterruptedException If interrupted wile trying to sleep
|
|
|
|
*/
|
|
|
|
private void runPhase(int phaseNumber) throws InterruptedException {
|
2020-03-24 14:05:39 +01:00
|
|
|
runProgramCards(phaseNumber);
|
2020-03-24 12:24:25 +01:00
|
|
|
|
|
|
|
moveAllConveyorBelts();
|
|
|
|
rotateCogwheels();
|
|
|
|
|
|
|
|
fireAllLasers();
|
|
|
|
checkAllFlags();
|
|
|
|
}
|
|
|
|
|
2020-03-10 17:29:36 +01:00
|
|
|
/**
|
|
|
|
* Makes the given robot move according to to the action input.
|
|
|
|
* @param robotID The ID of the robot to move.
|
|
|
|
* @param action The specific movement the robot is to take.
|
|
|
|
* @throws InterruptedException If interrupted wile trying to sleep.
|
|
|
|
*/
|
|
|
|
private void makeMove(RobotID robotID, Action action) throws InterruptedException {
|
|
|
|
if (!gameBoard.isRobotAlive(robotID)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sleep();
|
|
|
|
switch (action) {
|
|
|
|
case MOVE_1:
|
2020-03-11 08:02:30 +01:00
|
|
|
gameBoard.moveRobotForward(robotID);
|
2020-03-10 17:29:36 +01:00
|
|
|
break;
|
|
|
|
case MOVE_2:
|
2020-03-11 08:02:30 +01:00
|
|
|
gameBoard.moveRobotForward(robotID);
|
2020-03-10 17:29:36 +01:00
|
|
|
moveForward(robotID);
|
|
|
|
break;
|
|
|
|
case MOVE_3:
|
2020-03-11 08:02:30 +01:00
|
|
|
gameBoard.moveRobotForward(robotID);
|
2020-03-10 17:29:36 +01:00
|
|
|
moveForward(robotID);
|
|
|
|
moveForward(robotID);
|
|
|
|
break;
|
|
|
|
case ROTATE_RIGHT:
|
|
|
|
gameBoard.rotateRobotRight(robotID);
|
|
|
|
break;
|
|
|
|
case ROTATE_LEFT:
|
|
|
|
gameBoard.rotateRobotLeft(robotID);
|
|
|
|
break;
|
|
|
|
case U_TURN:
|
|
|
|
gameBoard.rotateRobotLeft(robotID);
|
|
|
|
gameBoard.rotateRobotLeft(robotID);
|
|
|
|
break;
|
|
|
|
case BACK_UP:
|
|
|
|
gameBoard.reverseRobot(robotID);
|
|
|
|
break;
|
2020-03-10 18:26:16 +01:00
|
|
|
default:
|
|
|
|
throw new IllegalArgumentException("Not a recognized action.");
|
2020-03-10 17:29:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper method for makeMove. Takes care of movement forward of given robot.
|
|
|
|
* @param robotID ID of the given robot.
|
|
|
|
* @throws InterruptedException If interrupted wile sleeping.
|
|
|
|
*/
|
|
|
|
private void moveForward(RobotID robotID) throws InterruptedException {
|
|
|
|
if (!gameBoard.isRobotAlive(robotID)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sleep();
|
|
|
|
gameBoard.moveRobotForward(robotID);
|
2020-02-24 18:07:26 +01:00
|
|
|
}
|
2020-03-12 11:49:14 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Rotates all robots that are standing on cogWheel tiles on the board.
|
|
|
|
* @throws InterruptedException If interrupted while sleeping.
|
|
|
|
*/
|
|
|
|
private void rotateCogwheels() throws InterruptedException {
|
2020-03-12 12:21:31 +01:00
|
|
|
for (BoardElementContainer<Tile> cogwheel : cogwheels) {
|
|
|
|
if (!gameBoard.hasRobotOnPosition(cogwheel.getPosition())) {
|
|
|
|
continue;
|
2020-03-12 11:49:14 +01:00
|
|
|
}
|
|
|
|
sleep();
|
2020-03-16 20:06:35 +01:00
|
|
|
if (cogwheel.getElement().getTileType() == TileType.COGWHEEL_RIGHT) {
|
2020-03-12 12:21:31 +01:00
|
|
|
gameBoard.rotateRobotRight(gameBoard.getRobotOnPosition(cogwheel.getPosition()));
|
|
|
|
} else {
|
|
|
|
gameBoard.rotateRobotLeft(gameBoard.getRobotOnPosition(cogwheel.getPosition()));
|
2020-03-12 11:49:14 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-16 17:31:54 +01:00
|
|
|
|
2020-03-16 19:37:21 +01:00
|
|
|
/**
|
|
|
|
* Moves robots standing on conveyor belts in the direction of the conveyor belt
|
|
|
|
*
|
|
|
|
* In addition, the function rotates appropriately when arriving at any non-straight conveyor belt
|
|
|
|
*
|
|
|
|
* @throws InterruptedException If disturbed during sleep
|
|
|
|
*/
|
|
|
|
private void moveAllConveyorBelts() throws InterruptedException {
|
2020-03-17 22:00:56 +01:00
|
|
|
sleep();
|
2020-03-16 19:37:21 +01:00
|
|
|
moveConveyorBelts(fastConveyorBelts);
|
2020-03-17 22:00:56 +01:00
|
|
|
sleep();
|
2020-03-16 19:37:21 +01:00
|
|
|
moveConveyorBelts(conveyorBelts);
|
2020-03-16 17:51:06 +01:00
|
|
|
}
|
|
|
|
|
2020-03-16 17:31:54 +01:00
|
|
|
/**
|
2020-03-25 13:36:35 +01:00
|
|
|
* Moves a list of conveyor belts
|
|
|
|
* @param conveyorBelts A list of board element containers containing conveyor belts
|
2020-03-16 17:31:54 +01:00
|
|
|
*/
|
2020-03-17 22:00:56 +01:00
|
|
|
private void moveConveyorBelts(List<BoardElementContainer<Tile>> conveyorBelts) {
|
2020-03-25 13:36:35 +01:00
|
|
|
Map<RobotID, Position> newPositions = new HashMap<>();
|
|
|
|
Map<RobotID, Boolean> moveNormally = new HashMap<>();
|
|
|
|
for (Robot robot : gameBoard.getAliveRobots()) {
|
|
|
|
newPositions.put(robot.getRobotId(), robot.getPosition());
|
2020-03-17 16:22:11 +01:00
|
|
|
}
|
2020-03-25 13:36:35 +01:00
|
|
|
//Updates hash maps containing robot move information
|
2020-03-16 17:31:54 +01:00
|
|
|
for (BoardElementContainer<Tile> conveyorBelt : conveyorBelts) {
|
2020-03-25 13:36:35 +01:00
|
|
|
Position conveyorBeltPosition = conveyorBelt.getPosition();
|
|
|
|
Direction conveyorBeltDirection = conveyorBelt.getElement().getDirection();
|
2020-03-28 15:34:47 +01:00
|
|
|
if (gameBoard.conveyorBeltCanMove(conveyorBelt, 0) &&
|
2020-03-25 13:36:35 +01:00
|
|
|
gameBoard.hasRobotOnPosition(conveyorBeltPosition)) {
|
2020-03-25 14:41:05 +01:00
|
|
|
updateConveyorBeltMaps(conveyorBeltPosition, conveyorBeltDirection, newPositions, moveNormally);
|
2020-03-16 17:31:54 +01:00
|
|
|
}
|
2020-03-17 16:22:11 +01:00
|
|
|
}
|
2020-03-25 13:36:35 +01:00
|
|
|
//Updates position for all robots affected by conveyor belts
|
|
|
|
for (RobotID robotID : RobotID.values()) {
|
|
|
|
if (newPositions.get(robotID) == null || moveNormally.get(robotID) == null) {
|
2020-03-24 21:13:21 +01:00
|
|
|
continue;
|
|
|
|
}
|
2020-03-25 13:36:35 +01:00
|
|
|
if (moveNormally.get(robotID)) {
|
|
|
|
gameBoard.moveRobot(robotID, gameBoard.getTileOnPosition(newPositions.get(robotID)).getDirection());
|
|
|
|
} else {
|
|
|
|
gameBoard.teleportRobot(robotID, newPositions.get(robotID));
|
2020-03-16 17:31:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-16 17:35:01 +01:00
|
|
|
|
2020-03-25 14:41:05 +01:00
|
|
|
/**
|
|
|
|
* 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 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-16 15:52:18 +01:00
|
|
|
/**
|
|
|
|
* Checks all flags for robots. Tries to update the flag of the robot.
|
|
|
|
*/
|
|
|
|
private void checkAllFlags() {
|
|
|
|
List<BoardElementContainer<Tile>> listOfFlags = gameBoard.getPositionsOfTileOnBoard(TileType.FLAG_1,
|
|
|
|
TileType.FLAG_2, TileType.FLAG_3, TileType.FLAG_4);
|
|
|
|
for (BoardElementContainer<Tile> flag:listOfFlags) {
|
|
|
|
Position flagPosition = flag.getPosition();
|
|
|
|
if (gameBoard.hasRobotOnPosition(flagPosition)) {
|
|
|
|
RobotID robot = gameBoard.getRobotOnPosition(flagPosition);
|
2020-03-16 20:06:35 +01:00
|
|
|
gameBoard.updateFlagOnRobot(robot, flag.getElement().getTileType());
|
2020-03-16 15:52:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-17 17:23:57 +01:00
|
|
|
|
2020-03-23 13:42:48 +01:00
|
|
|
/**
|
|
|
|
* Fires all lasers on the game board
|
|
|
|
*/
|
2020-03-23 13:47:34 +01:00
|
|
|
private void fireAllLasers() throws InterruptedException {
|
2020-03-17 17:23:57 +01:00
|
|
|
gameBoard.fireAllLasers();
|
2020-03-23 13:47:34 +01:00
|
|
|
sleep();
|
|
|
|
gameBoard.doLaserCleanup();
|
2020-03-17 17:23:57 +01:00
|
|
|
}
|
2020-03-24 14:02:03 +01:00
|
|
|
|
2020-03-24 14:28:42 +01:00
|
|
|
/**
|
2020-03-24 15:27:38 +01:00
|
|
|
* Runs all programming cards for a phase
|
|
|
|
* @param phase The number of the phase to run cards for
|
|
|
|
* @throws InterruptedException If it gets interrupted while trying to sleep
|
2020-03-24 14:28:42 +01:00
|
|
|
*/
|
2020-03-24 14:02:03 +01:00
|
|
|
private void runProgramCards(int phase) throws InterruptedException {
|
|
|
|
List<RobotID> robotsToDoAction = new ArrayList<>();
|
|
|
|
List<ProgrammingCard> programToBeRun = new ArrayList<>();
|
|
|
|
List<Integer> originalPriority = new ArrayList<>();
|
2020-03-24 15:26:20 +01:00
|
|
|
for (Player player : playerList) {
|
2020-03-24 14:02:03 +01:00
|
|
|
List<ProgrammingCard> playerProgram = player.getProgram();
|
|
|
|
if (!playerProgram.isEmpty()) {
|
2020-03-25 13:38:33 +01:00
|
|
|
ProgrammingCard programmingCard = playerProgram.get(phase - 1);
|
2020-03-24 15:26:20 +01:00
|
|
|
originalPriority.add(programmingCard.getPriority());
|
2020-03-24 14:02:03 +01:00
|
|
|
robotsToDoAction.add(player.getRobotID());
|
2020-03-24 15:26:20 +01:00
|
|
|
programToBeRun.add(programmingCard);
|
2020-03-24 14:02:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Collections.sort(programToBeRun);
|
2020-03-24 15:26:20 +01:00
|
|
|
for (ProgrammingCard card : programToBeRun) {
|
2020-03-24 14:02:03 +01:00
|
|
|
int i = originalPriority.indexOf(card.getPriority());
|
|
|
|
RobotID robot = robotsToDoAction.get(i);
|
|
|
|
makeMove(robot, card.getAction());
|
|
|
|
}
|
|
|
|
}
|
2020-03-30 18:32:55 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Respawn all the dead robots with more lives and places them on the game board
|
|
|
|
*/
|
|
|
|
private void respawnRobots(){
|
|
|
|
gameBoard.respawnRobots();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-03-31 13:45:35 +02:00
|
|
|
* repair all robots standing on a repair tile
|
2020-03-30 18:32:55 +02:00
|
|
|
*/
|
2020-03-31 13:45:35 +02:00
|
|
|
private void repairAllRobotsOnRepairTiles(){
|
2020-03-30 18:32:55 +02:00
|
|
|
List<BoardElementContainer<Tile>> listOfRepareTiles = gameBoard.getPositionsOfTileOnBoard(TileType.FLAG_1,
|
|
|
|
TileType.FLAG_2, TileType.FLAG_3, TileType.FLAG_4, TileType.WRENCH, TileType.WRENCH_AND_HAMMER);
|
|
|
|
for (BoardElementContainer<Tile> repareTile:listOfRepareTiles) {
|
|
|
|
Position robotOnTilePosition = repareTile.getPosition();
|
|
|
|
if (!gameBoard.hasRobotOnPosition(robotOnTilePosition)){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
gameBoard.repairRobotOnTile(gameBoard.getRobotOnPosition(robotOnTilePosition));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-30 18:53:10 +02:00
|
|
|
/**
|
|
|
|
* sets the robots powerdown status too the players powerdown next round status and sets the players status to false
|
|
|
|
*/
|
|
|
|
private void updateRobotPowerDown(){
|
|
|
|
for (Player player:playerList) {
|
|
|
|
gameBoard.setPowerDown(player.getRobotID(),player.getPowerDownNextRound());
|
|
|
|
player.setPowerDownNextRound(false);
|
|
|
|
}
|
|
|
|
}
|
2020-03-31 13:43:23 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* sets the powerdown status of a robots
|
|
|
|
* @param player the player that owns the robot
|
|
|
|
* @param powerdownStatus the powerdown status
|
|
|
|
*/
|
|
|
|
private void setRobotPowerDown(Player player,Boolean powerdownStatus){
|
|
|
|
gameBoard.setPowerDown(player.getRobotID(),powerdownStatus);
|
|
|
|
}
|
2020-03-12 11:49:14 +01:00
|
|
|
}
|