diff options
-rw-r--r-- | src/ch/epfl/xblast/ArgumentChecker.java | 4 | ||||
-rw-r--r-- | src/ch/epfl/xblast/Lists.java | 15 | ||||
-rw-r--r-- | src/ch/epfl/xblast/PlayerID.java | 17 | ||||
-rw-r--r-- | src/ch/epfl/xblast/RunLengthEncoder.java | 10 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Block.java | 31 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Board.java | 48 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Bomb.java | 5 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/GameState.java | 480 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/GameStateSerializer.java | 134 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/GameStateTransitioner.java | 349 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Level.java | 104 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/Player.java | 121 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/PlayerPriorityManager.java | 82 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/debug/GameStatePrinter.java | 4 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/painter/BlockImage.java | 29 | ||||
-rw-r--r-- | src/ch/epfl/xblast/server/painter/BoardPainter.java | 5 | ||||
-rw-r--r-- | test/ch/epfl/xblast/server/GameStateSerializerTest.java | 49 |
17 files changed, 803 insertions, 684 deletions
diff --git a/src/ch/epfl/xblast/ArgumentChecker.java b/src/ch/epfl/xblast/ArgumentChecker.java index 8ba744e..7e77b61 100644 --- a/src/ch/epfl/xblast/ArgumentChecker.java +++ b/src/ch/epfl/xblast/ArgumentChecker.java | |||
@@ -13,6 +13,10 @@ import java.util.Objects; | |||
13 | */ | 13 | */ |
14 | public final class ArgumentChecker { | 14 | public final class ArgumentChecker { |
15 | 15 | ||
16 | private ArgumentChecker() { | ||
17 | // Static class | ||
18 | } | ||
19 | |||
16 | /** | 20 | /** |
17 | * Returns the given value if it is non-negative. | 21 | * Returns the given value if it is non-negative. |
18 | * | 22 | * |
diff --git a/src/ch/epfl/xblast/Lists.java b/src/ch/epfl/xblast/Lists.java index b943162..073e0cc 100644 --- a/src/ch/epfl/xblast/Lists.java +++ b/src/ch/epfl/xblast/Lists.java | |||
@@ -152,4 +152,19 @@ public final class Lists { | |||
152 | return new ArrayList<>(l.subList(n, l.size())); | 152 | return new ArrayList<>(l.subList(n, l.size())); |
153 | } | 153 | } |
154 | 154 | ||
155 | /** | ||
156 | * Returns an immutable copy of the given lists, concatenated. | ||
157 | * | ||
158 | * @param lists the lists to concatenate | ||
159 | * @param <T> the type of the list's elements | ||
160 | * @return the list result of the concatenation | ||
161 | */ | ||
162 | public static <T> List<T> concatenated(List<T>... lists) { | ||
163 | return Collections.unmodifiableList( | ||
164 | Stream.of(lists) | ||
165 | .map(List::stream) | ||
166 | .reduce(Stream::concat).orElse(Stream.empty()) | ||
167 | .collect(Collectors.toList())); | ||
168 | } | ||
169 | |||
155 | } | 170 | } |
diff --git a/src/ch/epfl/xblast/PlayerID.java b/src/ch/epfl/xblast/PlayerID.java index c2c5c58..9377fdf 100644 --- a/src/ch/epfl/xblast/PlayerID.java +++ b/src/ch/epfl/xblast/PlayerID.java | |||
@@ -11,6 +11,21 @@ public enum PlayerID { | |||
11 | PLAYER_1, | 11 | PLAYER_1, |
12 | PLAYER_2, | 12 | PLAYER_2, |
13 | PLAYER_3, | 13 | PLAYER_3, |
14 | PLAYER_4 | 14 | PLAYER_4; |
15 | |||
16 | public Cell initialPosition() { | ||
17 | switch (this) { | ||
18 | case PLAYER_1: | ||
19 | return new Cell(1, 1); | ||
20 | case PLAYER_2: | ||
21 | return new Cell(13, 1); | ||
22 | case PLAYER_3: | ||
23 | return new Cell(13, 11); | ||
24 | case PLAYER_4: | ||
25 | return new Cell(1, 11); | ||
26 | default: | ||
27 | return null; | ||
28 | } | ||
29 | } | ||
15 | 30 | ||
16 | } | 31 | } |
diff --git a/src/ch/epfl/xblast/RunLengthEncoder.java b/src/ch/epfl/xblast/RunLengthEncoder.java index d7ab106..3784e0d 100644 --- a/src/ch/epfl/xblast/RunLengthEncoder.java +++ b/src/ch/epfl/xblast/RunLengthEncoder.java | |||
@@ -171,10 +171,10 @@ public final class RunLengthEncoder { | |||
171 | public static List<Byte> encode(List<Byte> bl) { | 171 | public static List<Byte> encode(List<Byte> bl) { |
172 | List<RunLength> rll = bl.stream().map(RunLength::new).collect(Collectors.toList()); | 172 | List<RunLength> rll = bl.stream().map(RunLength::new).collect(Collectors.toList()); |
173 | 173 | ||
174 | return collapseRunLengths(rll).stream() | 174 | return Collections.unmodifiableList(collapseRunLengths(rll).stream() |
175 | .flatMap(rl -> rl.split().stream()) | 175 | .flatMap(rl -> rl.split().stream()) |
176 | .flatMap(rl -> rl.encode().stream()) | 176 | .flatMap(rl -> rl.encode().stream()) |
177 | .collect(Collectors.toList()); | 177 | .collect(Collectors.toList())); |
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
@@ -184,9 +184,9 @@ public final class RunLengthEncoder { | |||
184 | * @return the decoded byte sequence | 184 | * @return the decoded byte sequence |
185 | */ | 185 | */ |
186 | public static List<Byte> decode(List<Byte> el) { | 186 | public static List<Byte> decode(List<Byte> el) { |
187 | return decodeRunLengths(el).stream() | 187 | return Collections.unmodifiableList(decodeRunLengths(el).stream() |
188 | .flatMap(rl -> rl.expand().stream()) | 188 | .flatMap(rl -> rl.expand().stream()) |
189 | .collect(Collectors.toList()); | 189 | .collect(Collectors.toList())); |
190 | } | 190 | } |
191 | 191 | ||
192 | } \ No newline at end of file | 192 | } |
diff --git a/src/ch/epfl/xblast/server/Block.java b/src/ch/epfl/xblast/server/Block.java index 5ada099..4f3d033 100644 --- a/src/ch/epfl/xblast/server/Block.java +++ b/src/ch/epfl/xblast/server/Block.java | |||
@@ -1,6 +1,7 @@ | |||
1 | package ch.epfl.xblast.server; | 1 | package ch.epfl.xblast.server; |
2 | 2 | ||
3 | import java.util.NoSuchElementException; | 3 | import java.util.NoSuchElementException; |
4 | import java.util.Random; | ||
4 | 5 | ||
5 | /** | 6 | /** |
6 | * Blocks. | 7 | * Blocks. |
@@ -41,9 +42,25 @@ public enum Block { | |||
41 | BONUS_RANGE(Bonus.INC_RANGE); | 42 | BONUS_RANGE(Bonus.INC_RANGE); |
42 | 43 | ||
43 | /** | 44 | /** |
45 | * The list of bonuses to choose randomly from. | ||
46 | */ | ||
47 | private static final Block[] RANDOM_BONUSES = new Block[]{BONUS_BOMB, BONUS_RANGE, FREE}; | ||
48 | |||
49 | /** | ||
50 | * The seed used for random value generation. | ||
51 | * Constant between executions to make tests reproducible. | ||
52 | */ | ||
53 | private static final int RANDOM_SEED = 2016; | ||
54 | |||
55 | /** | ||
56 | * Pseudo-random source for randomized behaviours. | ||
57 | */ | ||
58 | private static final Random RANDOM_SOURCE = new Random(RANDOM_SEED); | ||
59 | |||
60 | /** | ||
44 | * Corresponding bonus, or null. | 61 | * Corresponding bonus, or null. |
45 | */ | 62 | */ |
46 | private Bonus maybeAssociatedBonus; | 63 | private final Bonus maybeAssociatedBonus; |
47 | 64 | ||
48 | /** | 65 | /** |
49 | * Main builder, used by the bonus blocks. | 66 | * Main builder, used by the bonus blocks. |
@@ -56,7 +73,17 @@ public enum Block { | |||
56 | * Default builder, used by the non-bonus blocks. | 73 | * Default builder, used by the non-bonus blocks. |
57 | */ | 74 | */ |
58 | Block() { | 75 | Block() { |
59 | this.maybeAssociatedBonus = null; | 76 | this(null); |
77 | } | ||
78 | |||
79 | /** | ||
80 | * Returns a randomly chosen bonus Block with an equal probability distribution. | ||
81 | * | ||
82 | * @return a random bonus block | ||
83 | */ | ||
84 | static Block getRandomBonusBlock() { | ||
85 | int randomIndex = RANDOM_SOURCE.nextInt(RANDOM_BONUSES.length); | ||
86 | return RANDOM_BONUSES[randomIndex]; | ||
60 | } | 87 | } |
61 | 88 | ||
62 | /** | 89 | /** |
diff --git a/src/ch/epfl/xblast/server/Board.java b/src/ch/epfl/xblast/server/Board.java index 4519781..4f5e045 100644 --- a/src/ch/epfl/xblast/server/Board.java +++ b/src/ch/epfl/xblast/server/Board.java | |||
@@ -4,6 +4,7 @@ import ch.epfl.cs108.Sq; | |||
4 | import ch.epfl.xblast.Cell; | 4 | import ch.epfl.xblast.Cell; |
5 | import ch.epfl.xblast.Lists; | 5 | import ch.epfl.xblast.Lists; |
6 | 6 | ||
7 | import java.util.Arrays; | ||
7 | import java.util.Collection; | 8 | import java.util.Collection; |
8 | import java.util.Collections; | 9 | import java.util.Collections; |
9 | import java.util.List; | 10 | import java.util.List; |
@@ -17,6 +18,8 @@ import java.util.stream.Collectors; | |||
17 | */ | 18 | */ |
18 | public final class Board { | 19 | public final class Board { |
19 | 20 | ||
21 | static final Board DEFAULT_BOARD = buildDefaultBoard(); | ||
22 | |||
20 | /** | 23 | /** |
21 | * Distance (in SubCells) from a bomb to block a player. | 24 | * Distance (in SubCells) from a bomb to block a player. |
22 | */ | 25 | */ |
@@ -38,21 +41,22 @@ public final class Board { | |||
38 | private static final int BLOCKS_LIST_SIZE = BOARD_ROWS * BOARD_COLUMNS; | 41 | private static final int BLOCKS_LIST_SIZE = BOARD_ROWS * BOARD_COLUMNS; |
39 | 42 | ||
40 | /** | 43 | /** |
41 | * List containing all the blocks of the board. | 44 | * Build the default board of the game. |
42 | */ | ||
43 | private final List<Sq<Block>> blocks; | ||
44 | |||
45 | /** | ||
46 | * Instantiates a new Board with the given sequence of blocks. | ||
47 | * | 45 | * |
48 | * @param blocks sequence containing all the blocks of the Boards | 46 | * @return the default board. |
49 | * @throws IllegalArgumentException if the blocks is not composed of BLOC_LIST_SIZE elements | ||
50 | */ | 47 | */ |
51 | public Board(List<Sq<Block>> blocks) { | 48 | private static Board buildDefaultBoard() { |
52 | if (blocks == null || blocks.size() != BLOCKS_LIST_SIZE) | 49 | Block __ = Block.FREE; |
53 | throw new IllegalArgumentException(); | 50 | Block XX = Block.INDESTRUCTIBLE_WALL; |
54 | 51 | Block xx = Block.DESTRUCTIBLE_WALL; | |
55 | this.blocks = Lists.immutableList(blocks); |