diff options
-rw-r--r-- | src/ch/epfl/xblast/client/GameState.java | 147 | ||||
-rw-r--r-- | src/ch/epfl/xblast/client/GameStateDeserializer.java | 193 | ||||
-rw-r--r-- | src/ch/epfl/xblast/client/ImageCollection.java | 158 | ||||
-rw-r--r-- | src/ch/epfl/xblast/client/painter/ScorePainter.java | 107 | ||||
-rw-r--r-- | src/ch/epfl/xblast/client/painter/TimeLinePainter.java | 39 | ||||
-rw-r--r-- | test/ch/epfl/xblast/GameStateSerializerTest.java | 71 | ||||
-rw-r--r-- | test/ch/epfl/xblast/client/GameStateDeserializerTest.java | 27 | ||||
-rw-r--r-- | test/ch/epfl/xblast/server/BlockTest.java | 2 |
8 files changed, 743 insertions, 1 deletions
diff --git a/src/ch/epfl/xblast/client/GameState.java b/src/ch/epfl/xblast/client/GameState.java new file mode 100644 index 0000000..7652cd5 --- /dev/null +++ b/src/ch/epfl/xblast/client/GameState.java | |||
@@ -0,0 +1,147 @@ | |||
1 | package ch.epfl.xblast.client; | ||
2 | |||
3 | import ch.epfl.xblast.ArgumentChecker; | ||
4 | import ch.epfl.xblast.Lists; | ||
5 | import ch.epfl.xblast.PlayerID; | ||
6 | import ch.epfl.xblast.SubCell; | ||
7 | import ch.epfl.xblast.client.painter.ScorePainter; | ||
8 | import ch.epfl.xblast.client.painter.TimeLinePainter; | ||
9 | |||
10 | import java.awt.*; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | |||
14 | /** | ||
15 | * The client representation of a game state. | ||
16 | * | ||
17 | * @author Timothée FLOURE (257420) | ||
18 | * @author Pacien TRAN-GIRARD (261948) | ||
19 | */ | ||
20 | public final class GameState { | ||
21 | |||
22 | /** | ||
23 | * A Player. | ||
24 | */ | ||
25 | public static final class Player { | ||
26 | |||
27 | private final PlayerID id; | ||
28 | private final int lives; | ||
29 | private final SubCell position; | ||
30 | private final Image image; | ||
31 | |||
32 | /** | ||
33 | * Instantiates a new Player. | ||
34 | * | ||
35 | * @param id id of the player | ||
36 | * @param lives number of lives of the player | ||
37 | * @param position position of the player | ||
38 | * @param image image related to the actual state of the player | ||
39 | */ | ||
40 | public Player(PlayerID id, int lives, SubCell position, Image image) { | ||
41 | this.id = id; | ||
42 | this.lives = lives; | ||
43 | this.position = Objects.requireNonNull(position); | ||
44 | this.image = Objects.requireNonNull(image); | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * @return the player ID | ||
49 | */ | ||
50 | public PlayerID id() { | ||
51 | return this.id; | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * @return the number of lives of the player | ||
56 | */ | ||
57 | public int lives() { | ||
58 | return this.lives; | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * @return the position of the player | ||
63 | */ | ||
64 | public SubCell position() { | ||
65 | return this.position; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * @return the image related to the actual state of the player | ||
70 | */ | ||
71 | public Image image() { | ||
72 | return this.image; | ||
73 | } | ||
74 | |||
75 | } | ||
76 | |||
77 | private final List<Player> players; | ||
78 | private final List<Image> board; | ||
79 | private final List<Image> explosions; | ||
80 | private final List<Image> scores; | ||
81 | private final List<Image> ticks; | ||
82 | |||
83 | /** | ||
84 | * Instantiates a new GameState. | ||
85 | * | ||
86 | * @param players list containing the players | ||
87 | * @param board list containing all the images composing the board | ||
88 | * @param explosions list containing all the images composing the blasts and the bombs | ||
89 | * @param scores list containing all the images composing the actual score | ||
90 | * @param ticks list containing all the images composing the time "line" | ||
91 | */ | ||
92 | public GameState(List<Player> players, List<Image> board, List<Image> explosions, List<Image> scores, List<Image> ticks) { | ||
93 | this.players = Lists.immutableList(ArgumentChecker.requireNonEmpty(players)); | ||
94 | this.board = Lists.immutableList(ArgumentChecker.requireNonEmpty(board)); | ||
95 | this.explosions = Lists.immutableList(Objects.requireNonNull(explosions)); | ||
96 | this.scores = Lists.immutableList(ArgumentChecker.requireNonEmpty(scores)); | ||
97 | this.ticks = Lists.immutableList(ArgumentChecker.requireNonEmpty(ticks)); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Instantiates a new GameState. | ||
102 | * | ||
103 | * @param players list containing the players | ||
104 | * @param board list containing all the images composing the board | ||
105 | * @param explosions list containing all the images composing the blasts and the bombs | ||
106 | * @param ticks the ticks | ||
107 | */ | ||
108 | public GameState(List<Player> players, List<Image> board, List<Image> explosions, int ticks) { | ||
109 | this(players, board, explosions, ScorePainter.buildScorePanel(players), TimeLinePainter.buildTimeLine(ticks)); | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * @return list containing the players | ||
114 | */ | ||
115 | public List<Player> players() { | ||
116 | return this.players; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * @return list containing all the images composing the board | ||
121 | */ | ||
122 | public List<Image> board() { | ||
123 | return this.board; | ||
124 | } | ||
125 | |||
126 | /** | ||
127 | * @return ist containing all the images composing the blasts and the bombs | ||
128 | */ | ||
129 | public List<Image> explosions() { | ||
130 | return this.explosions; | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * @return list containing all the images composing the actual score | ||
135 | */ | ||
136 | public List<Image> scores() { | ||
137 | return this.scores; | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * @return list containing all the images composing the time "line" | ||
142 | */ | ||
143 | public List<Image> ticks() { | ||
144 | return this.ticks; | ||
145 | } | ||
146 | |||
147 | } | ||
diff --git a/src/ch/epfl/xblast/client/GameStateDeserializer.java b/src/ch/epfl/xblast/client/GameStateDeserializer.java new file mode 100644 index 0000000..20b44f9 --- /dev/null +++ b/src/ch/epfl/xblast/client/GameStateDeserializer.java | |||
@@ -0,0 +1,193 @@ | |||
1 | package ch.epfl.xblast.client; | ||
2 | |||
3 | import ch.epfl.xblast.Lists; | ||
4 | import ch.epfl.xblast.PlayerID; | ||
5 | import ch.epfl.xblast.RunLengthEncoder; | ||
6 | import ch.epfl.xblast.SubCell; | ||
7 | import ch.epfl.xblast.client.GameState.Player; | ||
8 | |||
9 | import java.awt.*; | ||
10 | import java.util.*; | ||
11 | import java.util.List; | ||
12 | import java.util.stream.Collectors; | ||
13 | |||
14 | /** | ||
15 | * The client game state deserializer. | ||
16 | * | ||
17 | * @author Pacien TRAN-GIRARD (261948) | ||
18 | * @author Timothée FLOURE (257420) | ||
19 | */ | ||
20 | public final class GameStateDeserializer { | ||
21 | |||
22 | private static final int SERIALIZED_PLAYER_LENGTH = 4; | ||
23 | private static final int SERIALIZED_PLAYERS_LENGTH = PlayerID.values().length * SERIALIZED_PLAYER_LENGTH; | ||
24 | private static final int SERIALIZED_TICKS_LENGTH = 1; | ||
25 | |||
26 | /** | ||
27 | * Represents a length-prefixed chunk of byte-encoded data. | ||
28 | */ | ||
29 | private static class VariableLengthChunk { | ||
30 | |||
31 | private static final int PREFIX_SHIFT = 1; | ||
32 | |||
33 | private final List<Byte> bytes; | ||
34 | |||
35 | /** | ||
36 | * Instantiates a VariableLengthChunk from a byte sequence. | ||
37 | * | ||
38 | * @param l the byte sequence | ||
39 | */ | ||
40 | public VariableLengthChunk(List<Byte> l) { | ||
41 | this.bytes = Lists.immutableList(l); | ||
42 | } | ||
43 | |||
44 | /** | ||
45 | * Returns the length of the chunk given by its prefix. | ||
46 | * | ||
47 | * @return the length of the chunk | ||
48 | */ | ||
49 | public int length() { | ||
50 | if (this.bytes.isEmpty()) | ||
51 | return 0; | ||
52 | else | ||
53 | return Byte.toUnsignedInt(this.bytes.get(0)); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * Returns the head of the desired length of the chunk. | ||
58 | * | ||
59 | * @param takeFirst the desired length | ||
60 | * @return the head | ||
61 | */ | ||
62 | public List<Byte> head(int takeFirst) { | ||
63 | return this.bytes.subList(0, takeFirst); | ||
64 | } | ||
65 | |||
66 | /** | ||
67 | * Returns the head of the size-prefixed chunk. | ||
68 | * | ||
69 | * @return the head | ||
70 | */ | ||
71 | public List<Byte> head() { | ||
72< |