aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacien TRAN-GIRARD2016-04-10 11:07:32 +0200
committerPacien TRAN-GIRARD2016-04-10 11:07:32 +0200
commita74846aced2635ebe7c51cc56b6d22eb4c33c69c (patch)
tree019435c66f889757b36330010c4f11a18a25142d
parentec69aef186d8f2d91dfd7d0e5ac792cd9c0ea1c6 (diff)
downloadxblast-a74846aced2635ebe7c51cc56b6d22eb4c33c69c.tar.gz
Fix and refactor player path evolution
-rw-r--r--src/ch/epfl/xblast/server/GameState.java140
1 files changed, 92 insertions, 48 deletions
diff --git a/src/ch/epfl/xblast/server/GameState.java b/src/ch/epfl/xblast/server/GameState.java
index f3547dc..df0cc24 100644
--- a/src/ch/epfl/xblast/server/GameState.java
+++ b/src/ch/epfl/xblast/server/GameState.java
@@ -188,57 +188,116 @@ public final class GameState {
188 .collect(Collectors.toList()); 188 .collect(Collectors.toList());
189 } 189 }
190 190
191 private static Player nextPlayer(Player players0, Bonus playerBonus, 191 /**
192 * Computes and returns the next State of a Player from the given events.
193 *
194 * @param player0 the Player
195 * @param playerBonus the optional Bonus to apply to the Player
196 * @param bombedCells1 the Set of bombed Cells
197 * @param board1 the updated Board
198 * @param blastedCells1 the Set of blasted Cells
199 * @param requestedDirection the Player's new requested Direction
200 * @return the next state of the Player
201 */
202 private static Player nextPlayer(Player player0, Bonus playerBonus,
192 Set<Cell> bombedCells1, Board board1, Set<Cell> blastedCells1, 203 Set<Cell> bombedCells1, Board board1, Set<Cell> blastedCells1,
193 Direction requestedDirection) { 204 Direction requestedDirection) {
194 205
195 Sq<Player.DirectedPosition> directedPositions1 = GameState.nextPath(players0, requestedDirection); 206 // 1. Compute the new path
207 Sq<Player.DirectedPosition> path1 = GameState.nextPath(player0, requestedDirection);
196 208
197 // Advance of one SubCell on the player's path 209 // 2. Check possible collisions and update the Sequence if necessary
198 directedPositions1 = directedPositions1.tail(); 210 Sq<Player.DirectedPosition> directedPos1 = GameState.handleCollisions(player0, path1, board1, bombedCells1);
199 211
200 //Check possible collisions and update the Sequence if necessary (kinda ugly right now) 212 // 3. Apply damages and generate a new LifeState Sequence
201 directedPositions1 = GameState.handleCollisions(players0, directedPositions1, board1, bombedCells1); 213 Sq<Player.LifeState> lifeStates1 = GameState.nextLifeState(player0, directedPos1, blastedCells1);
202 214
203 // Apply damages and generate a new LifeState Sequence 215 // 4. Create the new player given the new parameters
204 Sq<Player.LifeState> lifeStates1 = GameState.nextLifeState(players0, directedPositions1, blastedCells1); 216 Player p1 = new Player(player0.id(), lifeStates1, directedPos1, player0.maxBombs(), player0.bombRange());
205 217
206 // Create the new player given the new parameters 218 // 5. Update the capacities of the player given the possible bonus
207 Player p1 = new Player(players0.id(), lifeStates1, directedPositions1, players0.maxBombs(), players0.bombRange()); 219 if (!Objects.isNull(playerBonus))
208
209 // Update the capacities of the player given the possible bonus
210 if (playerBonus != null)
211 p1 = playerBonus.applyTo(p1); 220 p1 = playerBonus.applyTo(p1);
212 221
213 return p1; 222 return p1;
214 } 223 }
215 224
216 /** 225 /**
217 * Generate the new Sequence of Directed Positions. 226 * Returns the next Direction of the Player according to the constraints.
218 * 227 *
219 * @param player0 the Player 228 * @param p0 the Player
220 * @param requestedDirection the requested Direction 229 * @param requestedDir the requested new Direction
221 * @return the path 230 * @return the next Direction
222 */ 231 */
223 private static Sq<Player.DirectedPosition> nextPath(Player player0, Direction requestedDirection) { 232 private static Direction nextDirection(Player p0, Direction requestedDir) {
224 if (!player0.lifeState().canMove()) 233 return !Objects.isNull(requestedDir) ? requestedDir : p0.direction();
225 return Player.DirectedPosition.stopped(player0.directedPositions().head()); 234 }
226 235
227 if (requestedDirection == null) 236 /**
228 requestedDirection = player0.direction(); 237 * Generates the new Sequence of DirectedPositions.
238 *
239 * @param p0 the Player
240 * @param requestedDir the new requested Direction
241 * @return the next path
242 */
243 private static Sq<Player.DirectedPosition> nextPath(Player p0, Direction requestedDir) {
244 Sq<Player.DirectedPosition> path1 = GameState.newPath(
245 Player.DirectedPosition.moving(p0.directedPositions().head()),
246 GameState.nextDirection(p0, requestedDir));
229 247
230 if (player0.direction().isParallelTo(requestedDirection)) 248 return p0.lifeState().canMove() ? path1.tail() : path1;
231 return Player.DirectedPosition.moving(new Player.DirectedPosition(player0.position(), requestedDirection)); 249 }
232 250
233 if (player0.direction().isPerpendicularTo(requestedDirection)) { 251 /**
234 Player.DirectedPosition nextCentralSubCell = GameState.projectedDirectedPosition(player0, player0.directedPositions()); 252 * Computes the new path to follow according to the Player's wishes and the Board constraints.
235 Sq<Player.DirectedPosition> toNextCentralSubCell = player0.directedPositions().takeWhile(dp -> !dp.position().isCentral()); 253 *
236 Player.DirectedPosition centralSubCellDirectedPosition = new Player.DirectedPosition(nextCentralSubCell.position(), requestedDirection); 254 * @param p0 the current path
237 Sq<Player.DirectedPosition> pastNextCentralSubCell = Player.DirectedPosition.moving(centralSubCellDirectedPosition); 255 * @param newDir the new requested Direction
238 return toNextCentralSubCell.concat(pastNextCentralSubCell); 256 * @return the new path
239 } 257 */
258 private static Sq<Player.DirectedPosition> newPath(Sq<Player.DirectedPosition> p0, Direction newDir) {
259 if (p0.head().direction().isPerpendicularTo(newDir))
260 return GameState.pivotPath(p0, newDir);
261 else
262 return Player.DirectedPosition.moving(new Player.DirectedPosition(p0.head().position(), newDir));
263 }
240 264
241 return player0.directedPositions(); 265 /**
266 * Builds and returns a pivot path reaching the next pivot SubCell and then rotating to the given Direction.
267 *
268 * @param p0 the initial path
269 * @param newDir the new Direction to follow when possible
270 * @return the pivot path
271 */
272 private static Sq<Player.DirectedPosition> pivotPath(Sq<Player.DirectedPosition> p0, Direction newDir) {
273 SubCell nextCentral = GameState.nextCentralPosition(p0);
274
275 return GameState
276 .pathToNextCentralPosition(p0)
277 .concat(Player.DirectedPosition.moving(new Player.DirectedPosition(nextCentral, newDir)));
278 }
279
280 /**
281 * Returns the path to the next central SubCell.
282 *
283 * @param p the path to follow
284 * @return the truncated path
285 */
286 private static Sq<Player.DirectedPosition> pathToNextCentralPosition(Sq<Player.DirectedPosition> p) {
287 return p.tail()
288 .takeWhile(dp -> dp.position().isCentral());
289 }
290
291 /**
292 * Searches for and returns the next central SubCell reachable following the given path.
293 *
294 * @param p the path to follow
295 * @return the next central SubCell
296 */
297 private static SubCell nextCentralPosition(Sq<Player.DirectedPosition> p) {
298 return p.tail()
299 .findFirst(dp -> dp.position().isCentral())
300 .position();
242 } 301 }
243 302
244 /** 303 /**
@@ -254,7 +313,7 @@ public final class GameState {
254 Sq<Player.DirectedPosition> projectedPath, 313 Sq<Player.DirectedPosition> projectedPath,
255 Board board1, Set<Cell> bombedCells1) { 314 Board board1, Set<Cell> bombedCells1) {
256 315
257 Cell projectedCell = GameState.projectedDirectedPosition(player0, projectedPath).position().containingCell(); 316 Cell projectedCell = GameState.nextCentralPosition(projectedPath).containingCell();
258 if (GameState.isColliding(player0, projectedCell, board1, bombedCells1)) 317 if (GameState.isColliding(player0, projectedCell, board1, bombedCells1))
259 return Sq.repeat(1, player0.directedPositions().head()) 318 return Sq.repeat(1, player0.directedPositions().head())
260 .concat(projectedPath); 319 .concat(projectedPath);
@@ -263,21 +322,6 @@ public final class GameState {
263 } 322 }
264 323
265 /** 324 /**
266 * Computes a projection of the next DirectedPosition.
267 *
268 * @param player0 the Player
269 * @param projectedPath the projected path
270 * @return the projected next DirectedPosition
271 */
272 private static Player.DirectedPosition projectedDirectedPosition(Player player0, Sq<Player.DirectedPosition> projectedPath) {
273 if (!player0.lifeState().canMove())
274 return new Player.DirectedPosition(player0.position(), player0.direction());
275
276 return projectedPath.tail()
277 .findFirst(directedPos -> directedPos.position().isCentral());
278 }
279
280 /**
281 * Returns T(the player is colliding with an object). 325 * Returns T(the player is colliding with an object).
282 * 326 *
283 * @param player0 the Player 327 * @param player0 the Player