aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ch/epfl/xblast/Cell.java12
-rw-r--r--src/ch/epfl/xblast/SubCell.java21
-rw-r--r--src/ch/epfl/xblast/server/Board.java8
-rw-r--r--src/ch/epfl/xblast/server/GameState.java382
4 files changed, 397 insertions, 26 deletions
diff --git a/src/ch/epfl/xblast/Cell.java b/src/ch/epfl/xblast/Cell.java
index d31a889..06dfdbb 100644
--- a/src/ch/epfl/xblast/Cell.java
+++ b/src/ch/epfl/xblast/Cell.java
@@ -171,7 +171,17 @@ public final class Cell {
171 if (that == null) return false; 171 if (that == null) return false;
172 if (that == this) return true; 172 if (that == this) return true;
173 if (!(that instanceof Cell)) return false; 173 if (!(that instanceof Cell)) return false;
174 return (((Cell) that).x == this.x && ((Cell) that).y == this.y); 174 return (((Cell) that).rowMajorIndex() == this.rowMajorIndex());
175 }
176
177 /**
178 * Returns the hash code for this Cell, given by its row-major index.
179 *
180 * @return the hash code
181 */
182 @Override
183 public int hashCode() {
184 return this.rowMajorIndex();
175 } 185 }
176 186
177 /** 187 /**
diff --git a/src/ch/epfl/xblast/SubCell.java b/src/ch/epfl/xblast/SubCell.java
index a95e65e..27d5bcc 100644
--- a/src/ch/epfl/xblast/SubCell.java
+++ b/src/ch/epfl/xblast/SubCell.java
@@ -133,7 +133,17 @@ public final class SubCell {
133 if (that == null) return false; 133 if (that == null) return false;
134 if (that == this) return true; 134 if (that == this) return true;
135 if (!(that instanceof SubCell)) return false; 135 if (!(that instanceof SubCell)) return false;
136 return (((SubCell) that).x == this.x && ((SubCell) that).y == this.y); 136 return (((SubCell) that).rowMajorIndex() == this.rowMajorIndex());
137 }
138
139 /**
140 * Returns the hash code of this SubCell, given by its row-major index.
141 *
142 * @return the hash code
143 */
144 @Override
145 public int hashCode() {
146 return this.rowMajorIndex();
137 } 147 }
138 148
139 /** 149 /**
@@ -146,4 +156,13 @@ public final class SubCell {
146 return String.format("(%d,%d)", this.x, this.y); 156 return String.format("(%d,%d)", this.x, this.y);
147 } 157 }
148 158
159 /**
160 * Returns the index of the SubCell (major ordered).
161 *
162 * @return the index of the SubCell
163 */
164 private int rowMajorIndex() {
165 return this.y * SUB_COLUMNS + this.x;
166 }
167
149} 168}
diff --git a/src/ch/epfl/xblast/server/Board.java b/src/ch/epfl/xblast/server/Board.java
index 18ee532..f2a3c89 100644
--- a/src/ch/epfl/xblast/server/Board.java
+++ b/src/ch/epfl/xblast/server/Board.java
@@ -142,4 +142,12 @@ public final class Board {
142 return this.blocksAt(c).head(); 142 return this.blocksAt(c).head();
143 } 143 }
144 144
145 /**
146 * Return the blocks of the Board.
147 *
148 * @return a list of the Sequences of blocks of the board.
149 */
150 public List<Sq<Block>> getBlocks() {
151 return blocks;
152 }
145} 153}
diff --git a/src/ch/epfl/xblast/server/GameState.java b/src/ch/epfl/xblast/server/GameState.java
index ef792b6..1abe17a 100644
--- a/src/ch/epfl/xblast/server/GameState.java
+++ b/src/ch/epfl/xblast/server/GameState.java
@@ -1,14 +1,10 @@
1package ch.epfl.xblast.server; 1package ch.epfl.xblast.server;
2 2
3import ch.epfl.cs108.Sq; 3import ch.epfl.cs108.Sq;
4import ch.epfl.xblast.ArgumentChecker; 4import ch.epfl.xblast.*;
5import ch.epfl.xblast.Cell; 5
6import ch.epfl.xblast.PlayerID; 6import java.util.*;
7 7import java.util.function.Function;
8import java.util.ArrayList;
9import java.util.List;
10import java.util.Objects;
11import java.util.Optional;
12import java.util.stream.Collectors; 8import java.util.stream.Collectors;
13import java.util.stream.Stream; 9import java.util.stream.Stream;
14 10
@@ -20,33 +16,209 @@ import java.util.stream.Stream;
20 */ 16 */
21public final class GameState { 17public final class GameState {
22 18
23 private final int ticks; 19 /**
24 private final Board board; 20 * The list of player priority order permutations.
25 private final List<Player> players; 21 */
26 private final List<Bomb> bombs; 22 private static final List<List<PlayerID>> PLAYER_PRIORITY_ORDERS = GameState.buildPlayerPriorityOrderList();
27 private final List<Sq<Sq<Cell>>> explosions; 23
28 private final List<Sq<Cell>> blasts; 24 /**
25 * The list of bonuses to choose randomly from.
26 */
27 private static final Block[] RANDOM_BONUSES = new Block[]{Block.BONUS_BOMB, Block.BONUS_RANGE, Block.FREE};
28
29 /**
30 * The seed used for random value generation.
31 * Constant between executions to make tests reproducible.
32 */
33 private static final int RANDOM_SEED = 2016;
34
35 /**
36 * Pseudo-random source for randomized behaviours.
37 */
38 private static final Random RANDOM_SOURCE = new Random(GameState.RANDOM_SEED);
29 39
30 /** 40 /**
31 * Compute the next state of a blast. 41 * Builds and returns the player priority order permutations.
32 * 42 *
33 * @param blasts existing particles 43 * @return the list of player priority orders
34 * @param board the game's board 44 */
35 * @param explosions active explosions 45 private static List<List<PlayerID>> buildPlayerPriorityOrderList() {
46 return Lists.permutations(Arrays.asList(PlayerID.values()));
47 }
48
49 /**
50 * Returns a randomly chosen bonus Block with an equal probability distribution.
51 *
52 * @return a random bonus block
53 */
54 private static Block randomBonus() {
55 int randomIndex = RANDOM_SOURCE.nextInt(GameState.RANDOM_BONUSES.length);
56 return GameState.RANDOM_BONUSES[randomIndex];
57 }
58
59 /**
60 * Filters the given list of players and returns the lively ones.
61 *
62 * @param players a list of players
63 * @return the list of alive players
64 */
65 private static List<Player> alivePlayers(List<Player> players) {
66 return players.stream()
67 .filter(Player::isAlive)
68 .collect(Collectors.toList());
69 }
70
71 /**
72 * Maps the given bombs to their position.
73 *
74 * @param bombs a list of bombs
75 * @return a map of positions and their bombs
76 */
77 private static Map<Cell, Bomb> bombedCells(List<Bomb> bombs) {
78 return bombs.stream()
79 .collect(Collectors.toMap(Bomb::position, Function.identity()));
80 }
81
82 /**
83 * Returns a set of cells that contains at least one blast in the given blasts sequences.
84 *
85 * @param blasts the list of blast sequences
86 * @return the set of blasted cells
87 */
88 private static Set<Cell> blastedCells(List<Sq<Cell>> blasts) {
89 return blasts.stream()
90 .map(Sq::head)
91 .collect(Collectors.toSet());
92 }
93
94 /**
95 * Computes the next state of a blast.
96 *
97 * @param blasts0 existing particles
98 * @param board0 the game's board
99 * @param explosions0 active explosions
36 * @return the position of the explosion's particles for the next state. 100 * @return the position of the explosion's particles for the next state.
37 */ 101 */
38 private static List<Sq<Cell>> nextBlasts(List<Sq<Cell>> blasts, Board board, List<Sq<Sq<Cell>>> explosions) { 102 private static List<Sq<Cell>> nextBlasts(List<Sq<Cell>> blasts0, Board board0, List<Sq<Sq<Cell>>> explosions0) {
39 return Stream.concat( 103 return Stream.concat(
40 blasts.stream() 104 blasts0.stream()
41 .filter(blastSeq -> !blastSeq.tail().isEmpty()) 105 .filter(blastSeq -> !blastSeq.tail().isEmpty())
42 .filter(blastSeq -> board.blockAt(blastSeq.head()).isFree()) 106 .filter(blastSeq -> board0.blockAt(blastSeq.head()).isFree())
43 .map(Sq::tail), 107 .map(Sq::tail),
44 explosions.stream() 108 explosions0.stream()
45 .map(Sq::head) 109 .map(Sq::head)
46 ).collect(Collectors.toList()); 110 ).collect(Collectors.toList());
47 } 111 }
48 112
49 /** 113 /**
114 * Computes and returns the next board state of the given board according to the given events.
115 *
116 * @param board0 the previous board
117 * @param consumedBonuses the set of consumed bonuses
118 * @param blastedCells1 the set of newly blasted cells
119 * @return the next board
120 */
121 private static Board nextBoard(Board board0, Set<Cell> consumedBonuses, Set<Cell> blastedCells1) {
122 List<Sq<Block>> blocks0 = board0.getBlocks();
123 List<Sq<Block>> blocks1 = new ArrayList<>();
124
125 int i = 0;
126 for (Sq<Block> blockSq : blocks0) {
127 int cellId = blocks0.get(i).hashCode();<