diff options
Diffstat (limited to 'src/ch')
-rw-r--r-- | src/ch/epfl/xblast/server/GameState.java | 81 |
1 files changed, 71 insertions, 10 deletions
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; | |||
8 | import java.util.stream.Collectors; | 8 | import java.util.stream.Collectors; |
9 | import java.util.stream.Stream; | 9 | import java.util.stream.Stream; |
10 | 10 | ||
11 | |||
11 | /** | 12 | /** |
12 | * GameState representing the current game state. | 13 | * GameState representing the current game state. |
13 | * | 14 | * |
@@ -126,9 +127,9 @@ public final class GameState { | |||
126 | for (Sq<Block> blockSq : blocks0) { | 127 | for (Sq<Block> blockSq : blocks0) { |
127 | int cellId = blocks0.get(i).hashCode(); | 128 | int cellId = blocks0.get(i).hashCode(); |
128 | Block block = blockSq.head(); | 129 | Block block = blockSq.head(); |
129 | if (( consumedBonuses).contains(cellId) && block.isBonus()) { | 130 | if (consumedBonuses.contains(cellId) && block.isBonus()) { |
130 | blocks1.add(Sq.constant(Block.FREE)); | 131 | blocks1.add(Sq.constant(Block.FREE)); |
131 | } else if ((blastedCells1).contains(cellId) && (block == Block.DESTRUCTIBLE_WALL || block.isBonus())) { | 132 | } else if (blastedCells1.contains(cellId) && (block == Block.DESTRUCTIBLE_WALL || block.isBonus())) { |
132 | if (block == Block.DESTRUCTIBLE_WALL) { | 133 | if (block == Block.DESTRUCTIBLE_WALL) { |
133 | Block bonus = randomBonus(); | 134 | Block bonus = randomBonus(); |
134 | blocks1.add(Sq.repeat(Ticks.WALL_CRUMBLING_TICKS, Block.CRUMBLING_WALL).concat(Sq.constant(bonus))); | 135 | blocks1.add(Sq.repeat(Ticks.WALL_CRUMBLING_TICKS, Block.CRUMBLING_WALL).concat(Sq.constant(bonus))); |
@@ -162,8 +163,68 @@ public final class GameState { | |||
162 | Board board1, | 163 | Board board1, |
163 | Set<Cell> blastedCells1, | 164 | Set<Cell> blastedCells1, |
164 | Map<PlayerID, Optional<Direction>> speedChangeEvents) { | 165 | Map<PlayerID, Optional<Direction>> speedChangeEvents) { |
165 | //ToDo | 166 | List<Player> players1 = new ArrayList<>(); |
166 | return players0; | 167 | |
168 | for (Player player0 : players0) { | ||
169 | Optional<Direction> event = speedChangeEvents.get(player0.id()); | ||
170 | Sq<Player.DirectedPosition> directedPositions1; | ||
171 | |||
172 | // Get the requested direction | ||
173 | Direction requestedDirection = null; | ||
174 | if (event != null) { | ||
175 | requestedDirection = event.orElse(null); | ||
176 | } | ||
177 | |||
178 | // Generate the new Sequence of Directed Positions (kinda ugly right now) | ||
179 | if (requestedDirection == null || !player0.lifeState().canMove()) { | ||
180 | // The player does not move | ||
181 | directedPositions1 = Player.DirectedPosition.stopped(player0.directedPositions().head()); | ||
182 | } else if (player0.direction() == requestedDirection.opposite() || player0.direction() == requestedDirection) { | ||
183 | // The player keep its actual position or go to the opposite direction | ||
184 | Player.DirectedPosition requestedDirectedPosition = new Player.DirectedPosition(player0.position(), requestedDirection); | ||
185 | directedPositions1 = Sq.constant(requestedDirectedPosition); | ||
186 | } else { | ||
187 | // The player go to a perpendicular position. | ||
188 | Player.DirectedPosition nextCentralSubCell = player0.directedPositions().findFirst(dp -> dp.position().isCentral()); | ||
189 | Sq<Player.DirectedPosition> toNextCentralSubCell = player0.directedPositions().takeWhile(dp -> !dp.position().isCentral()); | ||
190 | Sq<Player.DirectedPosition> pastNextCentralSubCell = Player.DirectedPosition.moving(new Player.DirectedPosition(nextCentralSubCell.position(), requestedDirection)); | ||
191 | directedPositions1 = toNextCentralSubCell.concat(pastNextCentralSubCell); | ||
192 | } | ||
193 | |||
194 | // Advance of one SubCell on the newly computed path | ||
195 | directedPositions1 = directedPositions1.tail(); | ||
196 | |||
197 | // Check possible collisions and update the Sequence if necessary (kinda ugly right now) | ||
198 | Cell possiblyWalledCell = directedPositions1.tail().findFirst(dp -> dp.position().isCentral()).position().containingCell(); | ||
199 | if (!board1.blockAt(possiblyWalledCell).canHostPlayer()) { // if block non-free | ||
200 | Sq<Player.DirectedPosition> actualDirectedPosition = Sq.repeat(1 , player0.directedPositions().head()); | ||
201 | directedPositions1 = actualDirectedPosition.concat(directedPositions1); // won't move for a tick | ||
202 | } | ||
203 | if (bombedCells1.contains(player0.position().containingCell()) && player0.position().distanceToCentral() <= 6) { // Magic number ! 10 lashes for Fnux. | ||
204 | Sq<Player.DirectedPosition> actualDirectedPosition = Sq.repeat(1 , player0.directedPositions().head()); | ||
205 | directedPositions1 = actualDirectedPosition.concat(directedPositions1); // won't move for a tick | ||
206 | } | ||
207 | |||
208 | // Apply damages and generate a new LifeState Sequence | ||
209 | Sq<Player.LifeState> lifeStates1; | ||
210 | if (player0.lifeState().state() == Player.LifeState.State.VULNERABLE && blastedCells1.contains(directedPositions1.head().position())) { | ||
211 | lifeStates1 = player0.statesForNextLife(); | ||
212 | } else { | ||
213 | lifeStates1 = player0.lifeStates().tail(); | ||
214 | } | ||
215 | |||
216 | // Create the new player given the new parameters | ||
217 | Player player1 = new Player(player0.id(), lifeStates1, directedPositions1, player0.maxBombs(), player0.bombRange()); | ||
218 | |||
219 | // Update the capacities of the player given the possible bonus | ||
220 | if (playerBonuses.containsKey(player0.id())) { | ||
221 | player1 = playerBonuses.get(player0.id()).applyTo(player1); | ||
222 | } | ||
223 | |||
224 | // Add the newly generated player to the returned list | ||
225 | players1.add(player1); | ||
226 | } | ||
227 | return players1; | ||
167 | } | 228 | } |
168 | 229 | ||
169 | /** | 230 | /** |
@@ -174,7 +235,7 @@ public final class GameState { | |||
174 | */ | 235 | */ |
175 | private static List<Sq<Sq<Cell>>> nextExplosions(List<Sq<Sq<Cell>>> explosions0) { | 236 | private static List<Sq<Sq<Cell>>> nextExplosions(List<Sq<Sq<Cell>>> explosions0) { |
176 | List<Sq<Sq<Cell>>> explosions1 = new ArrayList<>(); | 237 | List<Sq<Sq<Cell>>> explosions1 = new ArrayList<>(); |
177 | for (Sq<Sq<Cell>> explosion : explosions0) { | 238 | for (Sq<Sq<Cell>> explosion : explosions0) { |
178 | if (!explosion.tail().isEmpty()) { | 239 | if (!explosion.tail().isEmpty()) { |
179 | explosions1.add(explosion.tail()); | 240 | explosions1.add(explosion.tail()); |
180 | } | 241 | } |
@@ -203,9 +264,9 @@ public final class GameState { | |||
203 | 264 | ||
204 | for (Player player : players0) { | 265 | for (Player player : players0) { |
205 | if (bombDropEvents.contains(player.id()) && player.isAlive() && !containingBombCells.contains(player.position().containingCell())) { | 266 | if (bombDropEvents.contains(player.id()) && player.isAlive() && !containingBombCells.contains(player.position().containingCell())) { |
206 | Bomb newBomb = new Bomb(player.id(), player.position().containingCell(), Ticks.BOMB_FUSE_TICKS, player.bombRange()); | 267 | Bomb newBomb = new Bomb(player.id(), player.position().containingCell(), Ticks.BOMB_FUSE_TICKS, player.bombRange()); |
207 | containingBombCells.add(newBomb.position()); | 268 | containingBombCells.add(newBomb.position()); |
208 | bombs1.add(newBomb); | 269 | bombs1.add(newBomb); |
209 | } | 270 | } |
210 | } | 271 | } |
211 | return bombs1; | 272 | return bombs1; |
@@ -458,8 +519,8 @@ public final class GameState { | |||
458 | private Set<PlayerID> discardConflictingBombDropEvents(Set<PlayerID> bombDropEvents) { | 519 | private Set<PlayerID> discardConflictingBombDropEvents(Set<PlayerID> bombDropEvents) { |
459 | Map<Cell, PlayerID> bombDropMap = this.mapTopPriorityPlayerCells( | 520 | Map<Cell, PlayerID> bombDropMap = this.mapTopPriorityPlayerCells( |
460 | this.alivePlayers().stream() | 521 | this.alivePlayers().stream() |
461 | .filter(bombDropEvents::contains) | 522 | .filter(bombDropEvents::contains) |
462 | .collect(Collectors.toList()) | 523 | .collect(Collectors.toList()) |
463 | ); | 524 | ); |
464 | 525 | ||
465 | return bombDropMap.isEmpty() ? EnumSet.noneOf(PlayerID.class) : EnumSet.copyOf(bombDropMap.values()); | 526 | return bombDropMap.isEmpty() ? EnumSet.noneOf(PlayerID.class) : EnumSet.copyOf(bombDropMap.values()); |