From 4d75a239dbffb6bd73d261c2cd5804d6e77834b4 Mon Sep 17 00:00:00 2001 From: Timothée Floure Date: Tue, 5 Apr 2016 01:04:06 +0200 Subject: Implement nextPlayer() for GameState --- src/ch/epfl/xblast/server/GameState.java | 81 ++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 10 deletions(-) (limited to 'src/ch') diff --git a/src/ch/epfl/xblast/server/GameState.java b/src/ch/epfl/xblast/server/GameState.java index f4d021c..035493d 100644 --- a/src/ch/epfl/xblast/server/GameState.java +++ b/src/ch/epfl/xblast/server/GameState.java @@ -8,6 +8,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; + /** * GameState representing the current game state. * @@ -126,9 +127,9 @@ public final class GameState { for (Sq blockSq : blocks0) { int cellId = blocks0.get(i).hashCode(); Block block = blockSq.head(); - if (( consumedBonuses).contains(cellId) && block.isBonus()) { + if (consumedBonuses.contains(cellId) && block.isBonus()) { blocks1.add(Sq.constant(Block.FREE)); - } else if ((blastedCells1).contains(cellId) && (block == Block.DESTRUCTIBLE_WALL || block.isBonus())) { + } else if (blastedCells1.contains(cellId) && (block == Block.DESTRUCTIBLE_WALL || block.isBonus())) { if (block == Block.DESTRUCTIBLE_WALL) { Block bonus = randomBonus(); blocks1.add(Sq.repeat(Ticks.WALL_CRUMBLING_TICKS, Block.CRUMBLING_WALL).concat(Sq.constant(bonus))); @@ -162,8 +163,68 @@ public final class GameState { Board board1, Set blastedCells1, Map> speedChangeEvents) { - //ToDo - return players0; + List players1 = new ArrayList<>(); + + for (Player player0 : players0) { + Optional event = speedChangeEvents.get(player0.id()); + Sq directedPositions1; + + // Get the requested direction + Direction requestedDirection = null; + if (event != null) { + requestedDirection = event.orElse(null); + } + + // Generate the new Sequence of Directed Positions (kinda ugly right now) + if (requestedDirection == null || !player0.lifeState().canMove()) { + // The player does not move + directedPositions1 = Player.DirectedPosition.stopped(player0.directedPositions().head()); + } else if (player0.direction() == requestedDirection.opposite() || player0.direction() == requestedDirection) { + // The player keep its actual position or go to the opposite direction + Player.DirectedPosition requestedDirectedPosition = new Player.DirectedPosition(player0.position(), requestedDirection); + directedPositions1 = Sq.constant(requestedDirectedPosition); + } else { + // The player go to a perpendicular position. + Player.DirectedPosition nextCentralSubCell = player0.directedPositions().findFirst(dp -> dp.position().isCentral()); + Sq toNextCentralSubCell = player0.directedPositions().takeWhile(dp -> !dp.position().isCentral()); + Sq pastNextCentralSubCell = Player.DirectedPosition.moving(new Player.DirectedPosition(nextCentralSubCell.position(), requestedDirection)); + directedPositions1 = toNextCentralSubCell.concat(pastNextCentralSubCell); + } + + // Advance of one SubCell on the newly computed path + directedPositions1 = directedPositions1.tail(); + + // Check possible collisions and update the Sequence if necessary (kinda ugly right now) + Cell possiblyWalledCell = directedPositions1.tail().findFirst(dp -> dp.position().isCentral()).position().containingCell(); + if (!board1.blockAt(possiblyWalledCell).canHostPlayer()) { // if block non-free + Sq actualDirectedPosition = Sq.repeat(1 , player0.directedPositions().head()); + directedPositions1 = actualDirectedPosition.concat(directedPositions1); // won't move for a tick + } + if (bombedCells1.contains(player0.position().containingCell()) && player0.position().distanceToCentral() <= 6) { // Magic number ! 10 lashes for Fnux. + Sq actualDirectedPosition = Sq.repeat(1 , player0.directedPositions().head()); + directedPositions1 = actualDirectedPosition.concat(directedPositions1); // won't move for a tick + } + + // Apply damages and generate a new LifeState Sequence + Sq lifeStates1; + if (player0.lifeState().state() == Player.LifeState.State.VULNERABLE && blastedCells1.contains(directedPositions1.head().position())) { + lifeStates1 = player0.statesForNextLife(); + } else { + lifeStates1 = player0.lifeStates().tail(); + } + + // Create the new player given the new parameters + Player player1 = new Player(player0.id(), lifeStates1, directedPositions1, player0.maxBombs(), player0.bombRange()); + + // Update the capacities of the player given the possible bonus + if (playerBonuses.containsKey(player0.id())) { + player1 = playerBonuses.get(player0.id()).applyTo(player1); + } + + // Add the newly generated player to the returned list + players1.add(player1); + } + return players1; } /** @@ -174,7 +235,7 @@ public final class GameState { */ private static List>> nextExplosions(List>> explosions0) { List>> explosions1 = new ArrayList<>(); - for (Sq> explosion : explosions0) { + for (Sq> explosion : explosions0) { if (!explosion.tail().isEmpty()) { explosions1.add(explosion.tail()); } @@ -203,9 +264,9 @@ public final class GameState { for (Player player : players0) { if (bombDropEvents.contains(player.id()) && player.isAlive() && !containingBombCells.contains(player.position().containingCell())) { - Bomb newBomb = new Bomb(player.id(), player.position().containingCell(), Ticks.BOMB_FUSE_TICKS, player.bombRange()); - containingBombCells.add(newBomb.position()); - bombs1.add(newBomb); + Bomb newBomb = new Bomb(player.id(), player.position().containingCell(), Ticks.BOMB_FUSE_TICKS, player.bombRange()); + containingBombCells.add(newBomb.position()); + bombs1.add(newBomb); } } return bombs1; @@ -458,8 +519,8 @@ public final class GameState { private Set discardConflictingBombDropEvents(Set bombDropEvents) { Map bombDropMap = this.mapTopPriorityPlayerCells( this.alivePlayers().stream() - .filter(bombDropEvents::contains) - .collect(Collectors.toList()) + .filter(bombDropEvents::contains) + .collect(Collectors.toList()) ); return bombDropMap.isEmpty() ? EnumSet.noneOf(PlayerID.class) : EnumSet.copyOf(bombDropMap.values()); -- cgit v1.2.3