From 388ea0b54eb6e0d1ec1efe7146f92e3720df86eb Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Wed, 16 Mar 2016 17:36:02 +0100 Subject: Implement global game state evolution method --- src/ch/epfl/xblast/server/GameState.java | 112 ++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) (limited to 'src') 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 { * @return the next game state */ public GameState next(Map> speedChangeEvents, Set bombDropEvents) { - return null; // TODO + // 1. blasts evolution + List> blasts1 = GameState.nextBlasts(this.blasts, this.board, this.explosions); + + // 2. board evolution + Set blastedCells1 = GameState.blastedCells(blasts1); + Map consumedBonuses = this.consumedBonuses(); + Board board1 = GameState.nextBoard(this.board, consumedBonuses.keySet(), blastedCells1); + + // 3. existing explosions evolution + List>> explosions1 = GameState.nextExplosions(this.explosions); + + // 4.1. existing bombs evolution + Set blastedCells0 = this.blastedCells(); + List explodingBombs = this.filterExplodingBombs(this.bombs, blastedCells0); + List bombs = this.bombs.stream().filter(b -> !explodingBombs.contains(b)).collect(Collectors.toList()); + + // 4.2. subsequent explosions addition + explodingBombs.forEach(b -> explosions1.addAll(b.explosion())); + + // 4.3. newly dropped bombs addition + Set topPriorityBombDropEvents = discardConflictingBombDropEvents(bombDropEvents); + bombs.addAll(GameState.newlyDroppedBombs(this.players, topPriorityBombDropEvents, this.bombs)); + + // 5. players evolution + Map playerBonuses = mapPlayersToBonuses(consumedBonuses); + Set bombedCells1 = GameState.bombedCells(bombs).keySet(); + List players1 = GameState.nextPlayers( + this.players, playerBonuses, bombedCells1, board1, blastedCells1, speedChangeEvents); + + return new GameState(this.ticks, board1, players1, bombs, explosions1, blasts1); } /** @@ -324,4 +353,85 @@ public final class GameState { .get(); } + /** + * Returns a mapping of players from their location. + * + * @param players a list of players to map + * @return the location->player mapping + */ + private Map> mapPlayersCells(List players) { + return players.stream() + .collect( + Collectors.groupingBy(p -> p.position().containingCell(), + Collectors.mapping(Player::id, Collectors.toList()))); + } + + /** + * Returns a mapping of top-priority player from their location. + * Conflicts are resolved using the current turn's players priority order. + * + * @param players a list of players to map + * @return the location->top-priority player mapping + */ + private Map mapTopPriorityPlayerCells(List players) { + return this.mapPlayersCells(players).entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + e -> resolveConflict(e.getValue()))); + } + + /** + * Returns a mapping of location of consumed bonuses and their top-priority claimant. + * + * @return the bonus-location->player mapping + */ + private Map consumedBonuses() { + return this.mapTopPriorityPlayerCells( + this.alivePlayers().stream() + .filter(p -> p.position().isCentral()) + .filter(p -> this.board.blockAt(p.position().containingCell()).isBonus()) + .collect(Collectors.toList())); + } + + /** + * Returns a mapping of players and their newly acquired bonus. + * + * @param consumedBonuses a mapping of bonus location and their claimants + * @return the player->bonus mapping + */ + private Map mapPlayersToBonuses(Map consumedBonuses) { + return consumedBonuses.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getValue, + e -> this.board.blockAt(e.getKey()).associatedBonus())); + } + + /** + * Returns a conflict-free set a player bomb dropping events. + * + * @param bombDropEvents the bomb drop events to filter + * @return the conflict-free set of bomb drop events + */ + private Set discardConflictingBombDropEvents(Set bombDropEvents) { + return EnumSet.copyOf( + this.mapTopPriorityPlayerCells( + this.alivePlayers().stream() + .filter(bombDropEvents::contains) + .collect(Collectors.toList()) + ).values()); + } + + /** + * Returns a list of exploding bombs (reached by a blast or consumed fuse). + * + * @param bombs the list of bombs + * @param blastedCells the set of blasted cells + * @return the list of exploding bombs + */ + private List filterExplodingBombs(List bombs, Set blastedCells) { + return bombs.stream() + .filter(b -> blastedCells.contains(b.position()) || b.fuseLength() == 0) + .collect(Collectors.toList()); + } + } -- cgit v1.2.3