aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacien TRAN-GIRARD2016-03-16 17:36:02 +0100
committerPacien TRAN-GIRARD2016-03-16 17:36:02 +0100
commit388ea0b54eb6e0d1ec1efe7146f92e3720df86eb (patch)
tree3e5dbb2a978b494cfc552635c6094cf0d42ebae1
parent383079bb6082944391f1841fca38edd2e5af54fe (diff)
downloadxblast-388ea0b54eb6e0d1ec1efe7146f92e3720df86eb.tar.gz
Implement global game state evolution method
-rw-r--r--src/ch/epfl/xblast/server/GameState.java112
1 files changed, 111 insertions, 1 deletions
diff --git a/src/ch/epfl/xblast/server/GameState.java b/src/ch/epfl/xblast/server/GameState.java
index 5386311..522a367 100644
--- a/src/ch/epfl/xblast/server/GameState.java
+++ b/src/ch/epfl/xblast/server/GameState.java
@@ -295,7 +295,36 @@ public final class GameState {
295 * @return the next game state 295 * @return the next game state
296 */ 296 */
297 public GameState next(Map<PlayerID, Optional<Direction>> speedChangeEvents, Set<PlayerID> bombDropEvents) { 297 public GameState next(Map<PlayerID, Optional<Direction>> speedChangeEvents, Set<PlayerID> bombDropEvents) {
298 return null; // TODO 298 // 1. blasts evolution
299 List<Sq<Cell>> blasts1 = GameState.nextBlasts(this.blasts, this.board, this.explosions);
300
301 // 2. board evolution
302 Set<Cell> blastedCells1 = GameState.blastedCells(blasts1);
303 Map<Cell, PlayerID> consumedBonuses = this.consumedBonuses();
304 Board board1 = GameState.nextBoard(this.board, consumedBonuses.keySet(), blastedCells1);
305
306 // 3. existing explosions evolution
307 List<Sq<Sq<Cell>>> explosions1 = GameState.nextExplosions(this.explosions);
308
309 // 4.1. existing bombs evolution
310 Set<Cell> blastedCells0 = this.blastedCells();
311 List<Bomb> explodingBombs = this.filterExplodingBombs(this.bombs, blastedCells0);
312 List<Bomb> bombs = this.bombs.stream().filter(b -> !explodingBombs.contains(b)).collect(Collectors.toList());
313
314 // 4.2. subsequent explosions addition
315 explodingBombs.forEach(b -> explosions1.addAll(b.explosion()));
316
317 // 4.3. newly dropped bombs addition
318 Set<PlayerID> topPriorityBombDropEvents = discardConflictingBombDropEvents(bombDropEvents);
319 bombs.addAll(GameState.newlyDroppedBombs(this.players, topPriorityBombDropEvents, this.bombs));
320
321 // 5. players evolution
322 Map<PlayerID, Bonus> playerBonuses = mapPlayersToBonuses(consumedBonuses);
323 Set<Cell> bombedCells1 = GameState.bombedCells(bombs).keySet();
324 List<Player> players1 = GameState.nextPlayers(
325 this.players, playerBonuses, bombedCells1, board1, blastedCells1, speedChangeEvents);
326
327 return new GameState(this.ticks, board1, players1, bombs, explosions1, blasts1);
299 } 328 }
300 329
301 /** 330 /**
@@ -324,4 +353,85 @@ public final class GameState {
324 .get(); 353 .get();
325 } 354 }
326 355
356 /**
357 * Returns a mapping of players from their location.
358 *
359 * @param players a list of players to map
360 * @return the location->player mapping
361 */
362 private Map<Cell, List<PlayerID>> mapPlayersCells(List<Player> players) {
363 return players.stream()
364 .collect(
365 Collectors.groupingBy(p -> p.position().containingCell(),
366 Collectors.mapping(Player::id, Collectors.toList())));
367 }
368
369 /**
370 * Returns a mapping of top-priority player from their location.
371 * Conflicts are resolved using the current turn's players priority order.
372 *
373 * @param players a list of players to map
374 * @return the location->top-priority player mapping
375 */
376 private Map<Cell, PlayerID> mapTopPriorityPlayerCells(List<Player> players) {
377 return this.mapPlayersCells(players).entrySet().stream()
378 .collect(Collectors.toMap(
379 Map.Entry::getKey,
380 e -> resolveConflict(e.getValue())));
381 }
382
383 /**
384 * Returns a mapping of location of consumed bonuses and their top-priority claimant.
385 *
386 * @return the bonus-location->player mapping
387 */
388 private Map<Cell, PlayerID> consumedBonuses() {
389 return this.mapTopPriorityPlayerCells(
390 this.alivePlayers().stream()
391 .filter(p -> p.position().isCentral())
392 .filter(p -> this.board.blockAt(p.position().containingCell()).isBonus())
393 .collect(Collectors.toList()));
394 }
395
396 /**
397 * Returns a mapping of players and their newly acquired bonus.
398 *
399 * @param consumedBonuses a mapping of bonus location and their claimants
400 * @return the player->bonus mapping
401 */
402 private Map<PlayerID, Bonus> mapPlayersToBonuses(Map<Cell, PlayerID> consumedBonuses) {
403 return consumedBonuses.entrySet().stream()
404 .collect(Collectors.toMap(
405 Map.Entry::getValue,
406 e -> this.board.blockAt(e.getKey()).associatedBonus()));
407 }
408
409 /**
410 * Returns a conflict-free set a player bomb dropping events.
411 *
412 * @param bombDropEvents the bomb drop events to filter
413 * @return the conflict-free set of bomb drop events
414 */
415 private Set<PlayerID> discardConflictingBombDropEvents(Set<PlayerID> bombDropEvents) {
416 return EnumSet.copyOf(
417 this.mapTopPriorityPlayerCells(
418 this.alivePlayers().stream()
419 .filter(bombDropEvents::contains)
420 .collect(Collectors.toList())
421 ).values());
422 }
423
424 /**
425 * Returns a list of exploding bombs (reached by a blast or consumed fuse).
426 *
427 * @param bombs the list of bombs
428 * @param blastedCells the set of blasted cells
429 * @return the list of exploding bombs
430 */
431 private List<Bomb> filterExplodingBombs(List<Bomb> bombs, Set<Cell> blastedCells) {
432 return bombs.stream()
433 .filter(b -> blastedCells.contains(b.position()) || b.fuseLength() == 0)
434 .collect(Collectors.toList());
435 }
436
327} 437}