1
0
mirror of https://github.com/inf112-v20/Fiasko.git synced 2025-03-03 16:49:45 +01:00
This commit is contained in:
torlunjen 2020-03-23 16:07:59 +01:00
commit 6192d3fcf6
25 changed files with 573 additions and 120 deletions

@ -45,6 +45,17 @@ public enum Direction {
return null;
}
/**
* Checks whether two directions are perpendicular
* @param direction1 The first direction
* @param direction2 The second direction
* @return True if the directions are perpendicular
*/
public static boolean arePerpendicular(Direction direction1, Direction direction2) {
return direction1.equals(getLeftRotatedDirection(direction2)) ||
direction1.equals(getRightRotatedDirection(direction2));
}
/**
* Gets the reverse of a direction
* @param direction A direction

@ -0,0 +1,40 @@
package inf112.fiasko.roborally.element_properties;
public enum ParticleType {
LASER_BEAM_SINGLE (1),
LASER_BEAM_DOUBLE (2),
LASER_BEAM_SINGLE_CROSS (3),
LASER_BEAM_DOUBLE_CROSS (4);
private final int particleTypeID;
/**
* Constructor to let a particle type be represented by a numerical identifier
* @param particleTypeID <p>The numerical identifier assigned to the particle type</p>
*/
ParticleType(int particleTypeID) {
this.particleTypeID = particleTypeID;
}
/**
* Gets the numerical id used for alternate identification of a tile type
* @return <p>The numerical id of the tile type</p>
*/
public int getParticleTypeID() {
return this.particleTypeID;
}
/**
* Gets a particle type value from its numerical representation
* @param particleTypeID <p>The numerical representation of a particle type</p>
* @return <p>The enum value representing the particle type, or null if the id is invalid</p>
*/
public static ParticleType getParticleTypeFromID(int particleTypeID) {
for (ParticleType type : ParticleType.values()) {
if (type.particleTypeID == particleTypeID) {
return type;
}
}
return null;
}
}

@ -26,15 +26,19 @@ public enum TileType {
FLAG_4 (20),
WRENCH (21),
WRENCH_AND_HAMMER (22),
DEATH_TILE (23),
ROBOT_SPAWN_1 (24),
ROBOT_SPAWN_2 (25),
ROBOT_SPAWN_3 (26),
ROBOT_SPAWN_4 (27),
ROBOT_SPAWN_5 (28),
ROBOT_SPAWN_6 (29),
ROBOT_SPAWN_7 (30),
ROBOT_SPAWN_8 (31);
ROBOT_SPAWN_1 (23),
ROBOT_SPAWN_2 (24),
ROBOT_SPAWN_3 (25),
ROBOT_SPAWN_4 (26),
ROBOT_SPAWN_5 (27),
ROBOT_SPAWN_6 (28),
ROBOT_SPAWN_7 (29),
ROBOT_SPAWN_8 (30),
PIT_EMPTY (31),
PIT_FULL (32),
PIT_NORMAL (33),
PIT_CORNER (34),
PIT_U (35);
private final int tileTypeID;

@ -30,7 +30,7 @@ public class CardChoiceScreen extends InputAdapter implements Screen {
private final List<CardRectangle> cardRectangles;
private final ShapeRenderer shapeRenderer;
private final Viewport viewport;
private List<CardRectangle> chosenCards;
private final List<CardRectangle> chosenCards;
private final int maxCards;
public CardChoiceScreen(final RoboRallyWrapper roboRallyWrapper) {

@ -33,9 +33,10 @@ public class MainMenuScreen implements Screen {
roboRallyWrapper.batch.setProjectionMatrix(camera.combined);
roboRallyWrapper.batch.begin();
roboRallyWrapper.font.draw(roboRallyWrapper.batch, "Robo Rally", 0, 250,
200, 0, false);
roboRallyWrapper.font.draw(roboRallyWrapper.batch, "Click anywhere to run the demo", 70, 200);
roboRallyWrapper.font.draw(roboRallyWrapper.batch, "Robo Rally", 10, 250,
380, 1, true);
roboRallyWrapper.font.draw(roboRallyWrapper.batch, "Click anywhere to run the demo", 10, 200,
380, 1, true);
roboRallyWrapper.batch.end();
if (Gdx.input.isTouched()) {

@ -17,7 +17,7 @@ public class RoboRallyWrapper extends Game {
batch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("assets/Montserrat-Regular.fnt"));
this.screenManager = new ScreenManager();
this.setScreen(screenManager.getBoardActiveScreen(this));
this.setScreen(screenManager.getMainMenuScreen(this));
}
public void dispose() {

@ -1,6 +1,7 @@
package inf112.fiasko.roborally.objects;
import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.ParticleType;
import inf112.fiasko.roborally.element_properties.Position;
import inf112.fiasko.roborally.element_properties.RobotID;
import inf112.fiasko.roborally.element_properties.TileType;
@ -19,6 +20,7 @@ public class Board {
private int boardWidth;
private IGrid<Wall> walls;
private IGrid<Tile> tiles;
private IGrid<Particle> particles;
private Map<RobotID, Robot> robots;
private List<Robot> deadRobots;
@ -43,24 +45,10 @@ public class Board {
this.boardHeight = tiles.getHeight();
this.walls = walls;
this.tiles = tiles;
this.particles = new Grid<>(tiles.getWidth(), tiles.getHeight());
this.deadRobots = new ArrayList<>();
}
/**
* Fires all lasers on the board and kills any robot that has taken to much damage after all lasers have fired.
*/
public void fireAllLasers(){
List<BoardElementContainer<Wall>> listOfWallLasers = getPositionsOfWallOnBoard(WallType.WALL_LASER_SINGLE,
WallType.WALL_LASER_DOUBLE);
for (Robot robot:robots.values()) {
fireOneRobotLaser(robot.getPosition(),robot.getFacingDirection());
}
for (BoardElementContainer<Wall> laser:listOfWallLasers) {
fireOneWallLaser(laser);
}
killAllDeadRobot();
}
/**
* Gets the height of the board
* @return The height of the board
@ -103,6 +91,14 @@ public class Board {
return getAllElementsFromGrid(walls);
}
/**
* Gets all the particles from the board
* @return A list of all the particles on the board
*/
public List<Particle> getParticles() {
return getAllElementsFromGrid(particles);
}
/**
* Rotates a robot to the right
* @param robotID The id of the robot to rotate
@ -244,6 +240,28 @@ public class Board {
}
}
/**
* Fires all lasers on the board and kills any robot that has taken to much damage after all lasers have fired.
*/
public void fireAllLasers() {
List<BoardElementContainer<Wall>> listOfWallLasers = getPositionsOfWallOnBoard(WallType.WALL_LASER_SINGLE,
WallType.WALL_LASER_DOUBLE);
for (Robot robot:robots.values()) {
fireRobotLaser(robot.getPosition(),robot.getFacingDirection());
}
for (BoardElementContainer<Wall> laser : listOfWallLasers) {
fireWallLaser(laser);
}
}
/**
* Does necessary cleanup after lasers have been fired
*/
public void doLaserCleanup() {
this.particles = new Grid<>(tiles.getWidth(), tiles.getHeight());
killAllHeavilyDamagedRobots();
}
/**
* Gets the tile on a specific position
* @param position The position to get a tile from
@ -282,6 +300,15 @@ public class Board {
return combinedList;
}
/**
* Checks whether there exists a robot on a specific position
* @param position The position to check
* @return True if there is a robot on the specified position
*/
public boolean hasRobotOnPosition(Position position) {
return getRobotOnPosition(position) != null;
}
/**
* Checks if a potential move would be blocked by a wall
* @param robotPosition The current position of whatever is trying to move
@ -289,7 +316,7 @@ public class Board {
* @param direction The direction something is going
* @return True if a wall would stop its path
*/
public 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)));
}
@ -331,7 +358,14 @@ public class Board {
throw new IllegalArgumentException("The game board is missing a tile. This should not happen.");
}
TileType tileTypeRobotStepsOn = tileRobotStepsOn.getTileType();
if (tileTypeRobotStepsOn == TileType.HOLE || tileTypeRobotStepsOn == TileType.DEATH_TILE) {
List<TileType> dangerousTiles = new ArrayList<>();
dangerousTiles.add(TileType.HOLE);
dangerousTiles.add(TileType.PIT_CORNER);
dangerousTiles.add(TileType.PIT_EMPTY);
dangerousTiles.add(TileType.PIT_FULL);
dangerousTiles.add(TileType.PIT_NORMAL);
dangerousTiles.add(TileType.PIT_U);
if (dangerousTiles.contains(tileTypeRobotStepsOn)) {
killRobot(robot);
}
}
@ -350,15 +384,6 @@ public class Board {
deadRobots.add(robot);
}
/**
* Checks whether there exists a robot on a specific position
* @param position The position to check
* @return True if there is a robot on the specified position
*/
public boolean hasRobotOnPosition(Position position) {
return getRobotOnPosition(position) != null;
}
/**
* Checks whether a position has a wall facing a specific direction
* @param position The position to check
@ -396,11 +421,11 @@ public class Board {
}
/**
* Finds all position of an obj and makes a list of BoardElementContainers
* @param type Type of obj
* @param grid Grid to search
* @param <K> Type of type
* @param <T> Type of grid
* Finds all tiles/walls with a certain type
* @param type The type of tile/wall to look for
* @param grid The grid to look through
* @param <K> Type of the type to look for
* @param <T> Type of the grid
* @return List of BoardElementContainers
*/
private <K,T> List<BoardElementContainer<T>> makeTileList(K type, IGrid<T> grid) {
@ -413,12 +438,12 @@ public class Board {
if (gridElement.getClass().isAssignableFrom(Tile.class)) {
Tile tile = (Tile) gridElement;
if (tile.getTileType() == type) {
objList.add(new BoardElementContainer<>(gridElement, new Position(x,y)));
objList.add(new BoardElementContainer<>(gridElement, new Position(x, y)));
}
} else if (gridElement.getClass().isAssignableFrom(Wall.class)) {
Wall wall = (Wall) gridElement;
if (wall.getWallType() == type) {
objList.add(new BoardElementContainer<>(gridElement, new Position(x,y)));
objList.add(new BoardElementContainer<>(gridElement, new Position(x, y)));
}
} else {
throw new IllegalArgumentException("Grid has unknown type.");
@ -430,11 +455,11 @@ public class Board {
}
/**
* Kills all robots that has taken too much damage
* Kills all robots that have taken too much damage
*/
private void killAllDeadRobot(){
private void killAllHeavilyDamagedRobots() {
for (Robot robot:robots.values()) {
if(robot.getDamageTaken()>=10){
if (robot.getDamageTaken() >= 10) {
killRobot(robot);
}
}
@ -442,62 +467,112 @@ public class Board {
/**
* Fires one wall laser
* @param laser the wall laser that is being fired
* @param wallLaser The wall laser being fired
*/
private void fireOneWallLaser(BoardElementContainer<Wall> laser){
Position hitPosition = lineForTheLaser(Direction.getReverseDirection(laser.getElement().getDirection()),
laser.getPosition());
if(getRobotOnPosition(hitPosition)!=null){
laserDamage(laser.getElement().getWallType(),robots.get(getRobotOnPosition(hitPosition)));
private void fireWallLaser(BoardElementContainer<Wall> wallLaser) {
Direction laserDirection = Direction.getReverseDirection(wallLaser.getElement().getDirection());
List<Position> laserTargets = new ArrayList<>();
getLaserTarget(laserDirection, wallLaser.getPosition(), laserTargets);
Position hitPosition = laserTargets.get(laserTargets.size()-1);
WallType laserType = wallLaser.getElement().getWallType();
updateLaserDisplay(laserTargets, laserDirection, laserType);
if (getRobotOnPosition(hitPosition) != null) {
applyLaserDamage(laserType, robots.get(getRobotOnPosition(hitPosition)));
}
}
/**
* fires on robot laser
* @param robotPosition the position of the robot firing the laser
* @param robotDirection the direction the robot is facing
* Fires one robot laser
* @param robotPosition The position of the robot firing the laser
* @param robotDirection The direction the robot is facing
*/
private void fireOneRobotLaser(Position robotPosition, Direction robotDirection){
private void fireRobotLaser(Position robotPosition, Direction robotDirection) {
Position positionInFront = getNewPosition(robotPosition,robotDirection);
if(!isValidPosition(positionInFront)||moveIsStoppedByWall(robotPosition,positionInFront,robotDirection)){
if (!isValidPosition(positionInFront) || moveIsStoppedByWall(robotPosition, positionInFront, robotDirection)) {
return;
}
Position hitPosition = lineForTheLaser(robotDirection,positionInFront);
if(getRobotOnPosition(hitPosition)!=null){
laserDamage(WallType.WALL_LASER_SINGLE,robots.get(getRobotOnPosition(hitPosition)));
List<Position> laserTargets = new ArrayList<>();
getLaserTarget(robotDirection, positionInFront, laserTargets);
Position hitPosition = laserTargets.get(laserTargets.size()-1);
WallType laserType = WallType.WALL_LASER_SINGLE;
updateLaserDisplay(laserTargets, robotDirection, laserType);
if (getRobotOnPosition(hitPosition) != null) {
applyLaserDamage(laserType, robots.get(getRobotOnPosition(hitPosition)));
}
}
/**
* Applies the damage form the laser to the robot the laser hit
* @param laserType the type of laser that hit the robot
* @param robot the robot getting hit by the robot
* @param laserType The type of laser that hit the robot
* @param robot The robot getting hit by the robot
*/
private void laserDamage(WallType laserType, Robot robot){
robot.setDamageTaken(robot.getDamageTaken()+laserType.getWallTypeID()-2);
private void applyLaserDamage(WallType laserType, Robot robot) {
robot.setDamageTaken(robot.getDamageTaken() + laserType.getWallTypeID() - 2);
}
/**
* Gets the Position of where the laser hits something
* @param direction the direction of the laser
* @param startPosition the start positon of the laser
* @return the position of the element that stopped the laser
* Gets all the positions the laser fires at
* @param direction The direction of the laser
* @param startPosition The start position of the laser
* @param targets The list to update with target positions
*/
private Position lineForTheLaser(Direction direction, Position startPosition){
Position newPosition = getNewPosition(startPosition,direction);
if(!isValidPosition(newPosition) || moveIsStoppedByWall(startPosition,newPosition,direction) ||
getRobotOnPosition(startPosition)!= null){
return startPosition;
private void getLaserTarget(Direction direction, Position startPosition, List<Position> targets) {
Position newPosition = getNewPosition(startPosition, direction);
targets.add(startPosition);
if (!isValidPosition(newPosition) || moveIsStoppedByWall(startPosition, newPosition, direction) ||
getRobotOnPosition(startPosition) != null) {
return;
}
else if(getRobotOnPosition(newPosition)!=null){
return newPosition;
}
else{
return lineForTheLaser(direction,newPosition);
if (getRobotOnPosition(newPosition) != null) {
targets.add(newPosition);
} else {
getLaserTarget(direction, newPosition, targets);
}
}
/**
* Adds any lasers in the targets list to the grid displaying lasers
* @param laserTargets The tiles the laser will hit
* @param laserDirection The direction of the laser
* @param laserType The type of the laser
*/
private void updateLaserDisplay(List<Position> laserTargets, Direction laserDirection, WallType laserType) {
for (Position laserTarget : laserTargets) {
System.out.println(laserTarget);
updateLaserBeamOnParticleGrid(laserTarget, laserDirection, laserType);
}
}
/**
* Updates a laser beam on the particle grid
* @param addPosition The position of the beam
* @param laserDirection The direction of the beam
* @param laserType The type of the laser shooting
*/
private void updateLaserBeamOnParticleGrid(Position addPosition, Direction laserDirection, WallType laserType) {
int positionX = addPosition.getXCoordinate();
int positionY = addPosition.getYCoordinate();
int numberOfLasers;
switch (laserType) {
case WALL_LASER_SINGLE:
numberOfLasers = 1;
break;
case WALL_LASER_DOUBLE:
numberOfLasers = 2;
break;
default:
throw new IllegalArgumentException("Laser type submitted is not a laser.");
}
ParticleType type;
Particle particleAtPosition = particles.getElement(positionX, positionY);
if (particleAtPosition != null && Direction.arePerpendicular(particleAtPosition.getDirection(),
laserDirection)) {
type = numberOfLasers == 1 ? ParticleType.LASER_BEAM_SINGLE_CROSS :
ParticleType.LASER_BEAM_DOUBLE_CROSS;
} else {
type = numberOfLasers == 1 ? ParticleType.LASER_BEAM_SINGLE : ParticleType.LASER_BEAM_DOUBLE;
}
particles.setElement(positionX, positionY, new Particle(type, laserDirection));
}
}

@ -39,6 +39,16 @@ public interface IDrawableGame {
*/
List<Wall> getWallsToDraw();
/**
* Gets a list of all the particles to be drawn
*
* Should return a list readable from top-left to top-right and so on. In other words, the first getWidth()
* particles should be drawn on the top row from left to right.
*
* @return A list of particles
*/
List<Particle> getParticlesToDraw();
/**
* Gets a list of all robots to draw
* @return A list of all robots to draw

@ -0,0 +1,42 @@
package inf112.fiasko.roborally.objects;
import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.ParticleType;
/**
* This class represents a particle
*/
public class Particle {
private ParticleType particleType;
private Direction direction;
/**
* Instantiates a new particle
* @param particleType The type of the particle
* @param direction The direction of the particle
*/
public Particle(ParticleType particleType, Direction direction) {
if (direction.getDirectionID() % 2 == 0) {
throw new IllegalArgumentException("Invalid direction for particle submitted");
}
this.particleType = particleType;
this.direction = direction;
}
/**
* Gets the particle type of the particle
* @return The particle's particle type
*/
public ParticleType getParticleType() {
return particleType;
}
/**
* Gets the direction of the particle
* @return The particle's direction
*/
public Direction getDirection() {
return direction;
}
}

@ -50,6 +50,11 @@ public class RoboRallyGame implements IDrawableGame {
return gameBoard.getWalls();
}
@Override
public List<Particle> getParticlesToDraw() {
return gameBoard.getParticles();
}
@Override
public List<Robot> getRobotsToDraw() {
return gameBoard.getAliveRobots();
@ -68,14 +73,14 @@ public class RoboRallyGame implements IDrawableGame {
*/
private void initializeDebugMode() {
List<Robot> robots = new ArrayList<>();
robots.add(new Robot(RobotID.ROBOT_1, new Position(0, 16)));
robots.add(new Robot(RobotID.ROBOT_2, new Position(1, 16)));
robots.add(new Robot(RobotID.ROBOT_3, new Position(2, 16)));
robots.add(new Robot(RobotID.ROBOT_4, new Position(3, 16)));
robots.add(new Robot(RobotID.ROBOT_5, new Position(4, 16)));
robots.add(new Robot(RobotID.ROBOT_6, new Position(5, 16)));
robots.add(new Robot(RobotID.ROBOT_7, new Position(6, 16)));
robots.add(new Robot(RobotID.ROBOT_8, new Position(7, 16)));
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)));
try {
gameBoard = BoardLoaderUtil.loadBoard("boards/all_tiles_test_board.txt", robots);
} catch (IOException e) {
@ -97,7 +102,7 @@ public class RoboRallyGame implements IDrawableGame {
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)));
gameBoard = BoardLoaderUtil.loadBoard("boards/Checkmate.txt", robots);
gameBoard = BoardLoaderUtil.loadBoard("boards/Dizzy_Dash.txt", robots);
cogwheels = gameBoard.getPositionsOfTileOnBoard(TileType.COGWHEEL_RIGHT,
TileType.COGWHEEL_LEFT);
fastConveyorBelts = gameBoard.getPositionsOfTileOnBoard(TileType.CONVEYOR_BELT_FAST,
@ -133,6 +138,7 @@ public class RoboRallyGame implements IDrawableGame {
TimeUnit.SECONDS.sleep(3);
makeMove(RobotID.ROBOT_1, Action.MOVE_1);
makeMove(RobotID.ROBOT_1, Action.MOVE_2);
fireAllLasers();
makeMove(RobotID.ROBOT_1, Action.BACK_UP);
makeMove(RobotID.ROBOT_1, Action.BACK_UP);
makeMove(RobotID.ROBOT_1, Action.MOVE_3);
@ -154,6 +160,8 @@ public class RoboRallyGame implements IDrawableGame {
makeMove(RobotID.ROBOT_2, Action.U_TURN);
makeMove(RobotID.ROBOT_2, Action.MOVE_1);
moveAllConveyorBelts();
checkAllFlags();
rotateCogwheels();
makeMove(RobotID.ROBOT_7, Action.MOVE_1);
}
@ -362,7 +370,12 @@ public class RoboRallyGame implements IDrawableGame {
}
}
private void fireAllLasers(){
/**
* Fires all lasers on the game board
*/
private void fireAllLasers() throws InterruptedException {
gameBoard.fireAllLasers();
sleep();
gameBoard.doLaserCleanup();
}
}

@ -6,6 +6,7 @@ import inf112.fiasko.roborally.element_properties.Position;
import inf112.fiasko.roborally.objects.IDrawableGame;
import inf112.fiasko.roborally.objects.DrawableObject;
import inf112.fiasko.roborally.objects.IDrawableObject;
import inf112.fiasko.roborally.objects.Particle;
import inf112.fiasko.roborally.objects.Robot;
import inf112.fiasko.roborally.objects.Tile;
import inf112.fiasko.roborally.objects.Wall;
@ -27,10 +28,12 @@ public final class IOUtil {
List<IDrawableObject> drawableObjects = new ArrayList<>();
List<Tile> tilesToDraw = game.getTilesToDraw();
List<Wall> wallsToDraw = game.getWallsToDraw();
List<Particle> particlesToDraw = game.getParticlesToDraw();
List<Robot> robotsToDraw = game.getRobotsToDraw();
int gameWidth = game.getWidth();
int gameHeight = game.getHeight();
drawableObjects.addAll(getDrawableObjectsFromElementList(tilesToDraw, gameWidth, tileWidth, tileHeight));
drawableObjects.addAll(getDrawableObjectsFromElementList(particlesToDraw, gameWidth, tileWidth, tileHeight));
drawableObjects.addAll(getDrawableObjectsFromElementList(wallsToDraw, gameWidth, tileWidth, tileHeight));
drawableObjects.addAll(getDrawableRobots(robotsToDraw, gameHeight, tileWidth, tileHeight));
return drawableObjects;
@ -86,6 +89,9 @@ public final class IOUtil {
} else if (currentElement.getClass().isAssignableFrom(Wall.class)) {
Wall wall = (Wall) currentElement;
region = TextureConverterUtil.convertElement(wall);
} else if (currentElement.getClass().isAssignableFrom(Particle.class)) {
Particle particle = (Particle) currentElement;
region = TextureConverterUtil.convertElement(particle);
} else {
throw new IllegalArgumentException("Unknown element type passed to function.");
}
@ -118,6 +124,10 @@ public final class IOUtil {
Wall wall = (Wall) element;
hasRotatedTexture = true;
direction = wall.getDirection();
} else if (element.getClass().isAssignableFrom(Particle.class)) {
Particle particle = (Particle) element;
hasRotatedTexture = true;
direction = particle.getDirection();
} else {
throw new IllegalArgumentException("Unknown element type passed to function.");
}

@ -5,9 +5,11 @@ import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Disposable;
import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.ParticleType;
import inf112.fiasko.roborally.element_properties.RobotID;
import inf112.fiasko.roborally.element_properties.TileType;
import inf112.fiasko.roborally.element_properties.WallType;
import inf112.fiasko.roborally.objects.Particle;
import inf112.fiasko.roborally.objects.Robot;
import inf112.fiasko.roborally.objects.Tile;
import inf112.fiasko.roborally.objects.Wall;
@ -29,6 +31,8 @@ public final class TextureConverterUtil {
private static final Texture robotsTexture = new Texture(Gdx.files.internal("assets/robots.png"));
private static Map<TileType, TextureConverterContainer> tileSheetTileTextureMappings;
private static Map<TileType, Boolean> tileSheetTileHasRotatedTextureMappings;
private static Map<ParticleType, TextureConverterContainer> tileSheetParticleTextureMappings;
private static Map<ParticleType, Boolean> tileSheetParticleHasRotatedTextureMappings;
private static Map<WallType, TextureConverterContainer> tileSheetWallTextureMappings;
private TextureConverterUtil() {}
@ -68,6 +72,30 @@ public final class TextureConverterUtil {
throw new IllegalArgumentException("Invalid or unimplemented tile type encountered");
}
/**
* Gets the texture representing the particle
* @param particle The particle to draw
* @return The texture to draw
*/
public static TextureRegion convertElement(Particle particle) {
if (tileSheetParticleTextureMappings == null) {
try {
loadParticleMappings();
} catch (IOException e) {
e.printStackTrace();
}
}
Direction direction = particle.getDirection();
TextureConverterContainer converterContainer = tileSheetParticleTextureMappings.get(particle.getParticleType());
if (converterContainer != null) {
return getDirectionalTextureRegion(direction, converterContainer.getXNorth(),
converterContainer.getYNorth(), converterContainer.getXEast(), converterContainer.getYEast(),
converterContainer.getXSouth(), converterContainer.getYSouth(), converterContainer.getXWest(),
converterContainer.getYWest());
}
throw new IllegalArgumentException("Invalid or unimplemented particle type encountered");
}
/**
* Gets the texture representing the tile
* @param wall The wall to draw
@ -95,8 +123,12 @@ public final class TextureConverterUtil {
throw new IllegalArgumentException("Invalid or unimplemented tile type encountered");
}
/**
* Gets the texture representing the robot
* @param robot The robot to draw
* @return The texture to draw
*/
public static TextureRegion convertElement(Robot robot) {
if (robot.getRobotId() == RobotID.ROBOT_1) {
return new TextureRegion(robotsTexture, 0, 0, 64, 64);
} else if (robot.getRobotId() == RobotID.ROBOT_2) {
@ -136,6 +168,25 @@ public final class TextureConverterUtil {
return tileSheetTileHasRotatedTextureMappings.get(tile.getTileType());
}
/**
* Checks whether a particle has textures for different rotations
*
* For a particle without a rotated texture, the texture needs to be rotated when rendering.
*
* @param particle The particle to check
* @return True if rotated versions of the texture exists. False otherwise
*/
public static boolean hasRotatedTexture(Particle particle) {
if (tileSheetTileTextureMappings == null) {
try {
loadParticleMappings();
} catch (IOException e) {
e.printStackTrace();
}
}
return tileSheetParticleHasRotatedTextureMappings.get(particle.getParticleType());
}
/**
* Loads mappings between a tile and texture
*
@ -158,6 +209,28 @@ public final class TextureConverterUtil {
}
}
/**
* Loads mappings between a particle and a texture
*
* Loads both information about mapping from a particle to a texture converter container and information about
* mapping from a particle to whether the particle has a rotated version of each texture
*
* @throws IOException If the mapping file can't be properly read
*/
private static synchronized void loadParticleMappings() throws IOException {
tileSheetParticleTextureMappings = new HashMap<>();
tileSheetParticleHasRotatedTextureMappings = new HashMap<>();
InputStream fileStream = ResourceUtil.getResourceAsInputStream("texture_sheet_particle_mapping.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream));
String line;
while ((line = reader.readLine()) != null) {
String[] parameters = line.split(" ");
ParticleType type = ParticleType.valueOf(parameters[0]);
storeTextMappingInMap(parameters, type, tileSheetParticleTextureMappings,
tileSheetParticleHasRotatedTextureMappings);
}
}
/**
* Loads mappings between a wall and texture
*

Binary file not shown.

Before

(image error) Size: 17 MiB

After

(image error) Size: 17 MiB

@ -13,7 +13,7 @@
21;7 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;1 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;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1
30;1 28;1 01;1 26;1 01;1 24;1 25;1 01;1 27;1 01;1 29;1 31;1
29;1 27;1 01;1 25;1 01;1 23;1 24;1 01;1 26;1 01;1 28;1 30;1
01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1
0 0 1;1 0 1;1 0 0 1;1 0 1;1 0 0
0 0 0 1;5 0 1;5 1;5 0 1;5 0 0 0

@ -0,0 +1,33 @@
12 16
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;1 12;3 11;3 11;3 12;5 01;1 01;1 12;3 11;3 11;3 12;5 01;1
01;1 11;1 03;1 01;1 11;1 04;7 01;1 11;1 03;1 01;1 11;5 01;1
01;1 11;1 21;1 03;1 11;1 01;1 01;1 11;1 22;1 03;1 11;5 01;1
01;1 12;1 11;7 11;7 12;7 17;1 04;7 12;1 11;7 11;7 12;7 01;1
01;1 01;1 01;1 01;1 04;5 01;1 01;1 01;1 01;1 04;1 01;1 01;1
01;1 19;1 04;5 01;1 01;1 01;1 01;1 04;1 01;1 01;1 01;1 01;1
01;1 12;3 11;3 11;3 12;5 04;3 01;1 12;3 11;3 11;3 12;5 01;1
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;1 11;1 01;1 03;1 11;5 01;1 04;3 11;1 01;1 03;1 11;5 01;1
01;1 12;1 11;7 11;7 12;7 01;1 01;1 12;1 11;7 11;7 12;7 01;1
01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 18;1 01;1
29;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 30;1
01;1 27;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 28;1 01;1
05;3 05;3 06;5 25;1 01;1 01;1 01;1 01;1 26;1 07;5 05;7 05;7
01;1 01;1 07;3 05;3 05;3 23;1 24;1 05;7 05;7 06;7 01;1 01;1
0 0 1;1 0 1;1 0 0 1;1 0 1;1 0 0
0 0 0 0 0 0 0 0 0 0 0 0
1;7 0 0 1;5 0 0 0 0 0 0 0 1;3
0 0 0 0 0 1;7 3;3 0 0 0 0 0
1;7 0 0 0 0 0 0 0 0 0 0 1;3
0 0 0 0 0 0 0 0 3;1 0 0 0
0 0 0 3;5 0 0 0 0 0 0 0 0
1;7 0 0 0 0 0 0 0 0 0 0 1;3
0 0 0 0 0 3;7 1;3 0 0 0 0 0
1;7 0 0 0 0 0 0 0 1;1 0 0 1;3
0 0 0 0 0 0 0 0 0 0 0 0
0 0 1;5 0 1;5 0 0 1;5 0 1;5 0 0
0 0 1;1 0 2;8 0 0 2;2 0 1;1 0 0
0 1;7 1;7 0 0 0 0 0 0 1;3 1;3 0
0 0 0 0 0 0 1;7 0 0 0 0 0
0 0 0 0 0 0 1;7 0 0 0 0 0

@ -11,10 +11,10 @@
01;1 01;1 01;1 05;1 01;1 11;5 05;1 01;1 05;5 01;1 01;1 01;1
02;7 01;1 01;1 05;1 01;1 11;5 05;1 01;1 05;5 01;1 03;5 05;3
01;1 01;1 01;1 05;1 01;1 11;5 01;1 01;1 05;5 01;1 05;1 21;5
30;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 31;1
01;1 28;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 29;1 01;1
05;3 05;3 06;5 26;1 01;1 01;1 01;1 01;1 27;1 07;5 05;7 05;7
01;1 01;1 07;3 05;3 05;3 24;1 25;1 05;7 05;7 06;7 01;1 01;1
29;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 30;1
01;1 27;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 01;1 28;1 01;1
05;3 05;3 06;5 25;1 01;1 01;1 01;1 01;1 26;1 07;5 05;7 05;7
01;1 01;1 07;3 05;3 05;3 23;1 24;1 05;7 05;7 06;7 01;1 01;1
0 0 1;1 0 1;1 0 0 1;1 0 1;1 0 0
0 0 0 0 0 0 0 0 0 0 0 0
1;7 0 0 0 0 0 0 0 0 1;7 0 3;3

@ -1,4 +1,4 @@
8 19
8 21
01;1 01;3 01;5 01;7 02;1 02;3 02;5 02;7
03;1 03;3 03;5 03;7 04;1 04;3 04;5 04;7
05;1 05;3 05;5 05;7 06;1 06;3 06;5 06;7
@ -14,7 +14,9 @@
25;1 25;3 25;5 25;7 26;1 26;3 26;5 26;7
27;1 27;3 27;5 27;7 28;1 28;3 28;5 28;7
29;1 29;3 29;5 29;7 30;1 30;3 30;5 30;7
31;1 31;3 31;5 31;7 01;1 01;1 01;1 01;1
31;1 31;3 31;5 31;7 32;1 32;3 32;5 32;7
33;1 33;3 33;5 33;7 34;1 34;3 34;5 34;7
35;1 35;3 35;5 35;7 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;1 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;1 01;1 01;1
@ -35,5 +37,7 @@
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
1;1 1;3 1;5 1;7 2;2 2;4 2;6 2;8
3;1 3;3 3;5 3;7 4;1 4;3 4;5 4;7

@ -0,0 +1,4 @@
LASER_BEAM_SINGLE 6 5 6 4 6 5 6 4
LASER_BEAM_DOUBLE 5 12 6 12 5 12 6 12
LASER_BEAM_SINGLE_CROSS 7 4
LASER_BEAM_DOUBLE_CROSS 4 12

@ -20,7 +20,6 @@ FLAG_3 6 8
FLAG_4 6 9
WRENCH 6 1
WRENCH_AND_HAMMER 6 0
DEATH_TILE 3 11
ROBOT_SPAWN_1 0 15
ROBOT_SPAWN_2 1 15
ROBOT_SPAWN_3 2 15
@ -28,4 +27,9 @@ ROBOT_SPAWN_4 3 15
ROBOT_SPAWN_5 0 16
ROBOT_SPAWN_6 1 16
ROBOT_SPAWN_7 2 16
ROBOT_SPAWN_8 3 16
ROBOT_SPAWN_8 3 16
PIT_EMPTY 3 11
PIT_FULL 2 11
PIT_NORMAL 1 13 3 13 1 14 3 14
PIT_CORNER 2 13 2 14 0 14 0 13
PIT_U 5 14 4 13 5 13 4 14

@ -8,7 +8,9 @@ import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class DirectionTest {
@ -176,4 +178,34 @@ public class DirectionTest {
public void getLeftRotatedDirectionFromSouthWest() {
assertEquals(Direction.SOUTH_EAST, Direction.getLeftRotatedDirection(Direction.SOUTH_WEST));
}
@Test
public void eastAndWestArePerpendicular() {
assertFalse(Direction.arePerpendicular(Direction.EAST, Direction.WEST));
}
@Test
public void eastAndNorthArePerpendicular() {
assertTrue(Direction.arePerpendicular(Direction.EAST, Direction.NORTH));
}
@Test
public void eastAndSouthArePerpendicular() {
assertTrue(Direction.arePerpendicular(Direction.EAST, Direction.SOUTH));
}
@Test
public void northAndSouthArePerpendicular() {
assertFalse(Direction.arePerpendicular(Direction.NORTH, Direction.SOUTH));
}
@Test
public void northAndWestArePerpendicular() {
assertTrue(Direction.arePerpendicular(Direction.NORTH, Direction.WEST));
}
@Test
public void southAndWestArePerpendicular() {
assertTrue(Direction.arePerpendicular(Direction.SOUTH, Direction.WEST));
}
}

@ -0,0 +1,52 @@
package inf112.fiasko.roborally.element_properties;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
public class ParticleTypeTest {
@Test
public void getTileTypeIDForLaserBeam() {
assertEquals(1, ParticleType.LASER_BEAM_SINGLE.getParticleTypeID());
}
@Test
public void getTileTypeFromLaserBeamID() {
assertEquals(ParticleType.LASER_BEAM_SINGLE, ParticleType.getParticleTypeFromID(1));
}
@Test
public void getTileTypeIDForLaserBeamDouble() {
assertEquals(2, ParticleType.LASER_BEAM_DOUBLE.getParticleTypeID());
}
@Test
public void getTileTypeFromLaserBeamDoubleID() {
assertEquals(ParticleType.LASER_BEAM_DOUBLE, ParticleType.getParticleTypeFromID(2));
}
@Test
public void allParticleTypesIDConversionToIDAndBack() {
for (ParticleType type : ParticleType.values()) {
assertEquals(type, ParticleType.getParticleTypeFromID(type.getParticleTypeID()));
}
}
@Test
public void allParticlesHaveUniqueId() {
/* This test is also done implicitly by the allTileTypesIDConversionToIDAndBack test, but that test may fail
even if this test passes, so this test is needed for clarity. */
Set<Integer> set = new HashSet<>();
List<Integer> list = new ArrayList<>();
for (ParticleType type : ParticleType.values()) {
set.add(type.getParticleTypeID());
list.add(type.getParticleTypeID());
}
assertEquals(list.size(), set.size());
}
}

@ -40,16 +40,6 @@ public class TileTypeTest {
}
}
@Test
public void invalidTileTypeIDReturnsNull() {
assertNull(TileType.getTileTypeFromID(-1));
}
@Test (expected = IllegalArgumentException.class)
public void invalidTileDirectionThrowsError() {
new Tile(TileType.TILE, Direction.NORTH_EAST);
}
@Test
public void allTilesHaveUniqueId() {
/* This test is also done implicitly by the allTileTypesIDConversionToIDAndBack test, but that test may fail

@ -5,7 +5,6 @@ import inf112.fiasko.roborally.element_properties.Position;
import inf112.fiasko.roborally.element_properties.RobotID;
import inf112.fiasko.roborally.element_properties.TileType;
import inf112.fiasko.roborally.element_properties.WallType;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@ -38,8 +37,6 @@ public class BoardTest {
private Board boardWithDifferentAmountOfAllTypes;
private final Map<WallType,Integer> wallTypeNumberMap = new HashMap<>();
private final Map<TileType,Integer> tileTypeNumberMap = new HashMap<>();
private Grid<Tile> tileGridforlaser;
private Grid<Wall> wallGridforlaser;
private List<Robot> robotListforlaser;
private Board boardforlaser;
@ -59,8 +56,8 @@ public class BoardTest {
@Before
public void setUp() {
tileGridforlaser = new Grid<>(8, 8, new Tile(TileType.TILE, Direction.NORTH));
wallGridforlaser = new Grid<>(8, 8);
Grid<Tile> tileGridforlaser = new Grid<>(8, 8, new Tile(TileType.TILE, Direction.NORTH));
Grid<Wall> wallGridforlaser = new Grid<>(8, 8);
robotListforlaser = new ArrayList<>();
robotListforlaser.add(new Robot(RobotID.ROBOT_1, new Position(2,1)));
robotListforlaser.add(new Robot(RobotID.ROBOT_2, new Position(4,0)));

@ -0,0 +1,52 @@
package inf112.fiasko.roborally.objects;
import inf112.fiasko.roborally.element_properties.Direction;
import inf112.fiasko.roborally.element_properties.ParticleType;
import inf112.fiasko.roborally.element_properties.TileType;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class ParticleTest {
private Particle particle;
private Particle particle2;
@Before
public void setUp() {
particle = new Particle(ParticleType.LASER_BEAM_SINGLE, Direction.NORTH);
particle2 = new Particle(ParticleType.LASER_BEAM_DOUBLE_CROSS, Direction.EAST);
}
@Test
public void getParticleTypeFromParticle() {
assertEquals(ParticleType.LASER_BEAM_SINGLE, particle.getParticleType());
}
@Test
public void getParticleTypeFromParticle2() {
assertEquals(ParticleType.LASER_BEAM_DOUBLE_CROSS, particle2.getParticleType());
}
@Test
public void getDirectionFromParticle() {
assertEquals(Direction.NORTH, particle.getDirection());
}
@Test
public void getDirectionFromParticle2() {
assertEquals(Direction.EAST, particle2.getDirection());
}
@Test
public void invalidParticleTypeIDReturnsNull() {
assertNull(ParticleType.getParticleTypeFromID(-1));
}
@Test (expected = IllegalArgumentException.class)
public void invalidParticleDirectionThrowsError() {
new Particle(ParticleType.LASER_BEAM_DOUBLE, Direction.NORTH_EAST);
}
}

@ -6,6 +6,7 @@ import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
public class TileTest {
private Tile tile;
@ -38,8 +39,13 @@ public class TileTest {
assertEquals(Direction.SOUTH, tile2.getDirection());
}
@Test
public void invalidTileTypeIDReturnsNull() {
assertNull(TileType.getTileTypeFromID(-1));
}
@Test (expected = IllegalArgumentException.class)
public void invalidTileThrowsException() {
new Tile(TileType.CONVEYOR_BELT_FAST, Direction.NORTH_EAST);
public void invalidTileDirectionThrowsError() {
new Tile(TileType.TILE, Direction.NORTH_EAST);
}
}