aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ch/epfl/xblast/RunLengthEncoder.java34
-rw-r--r--src/ch/epfl/xblast/server/GameStateSerializer.java90
-rw-r--r--src/ch/epfl/xblast/server/Level.java134
-rw-r--r--test/ch/epfl/xblast/GameStateSerializerTest.java39
4 files changed, 297 insertions, 0 deletions
diff --git a/src/ch/epfl/xblast/RunLengthEncoder.java b/src/ch/epfl/xblast/RunLengthEncoder.java
new file mode 100644
index 0000000..a3c8a88
--- /dev/null
+++ b/src/ch/epfl/xblast/RunLengthEncoder.java
@@ -0,0 +1,34 @@
1package ch.epfl.xblast;
2
3import java.util.ArrayList;
4import java.util.List;
5
6/**
7 * @author Timothée FLOURE (257420)
8 */
9public final class RunLengthEncoder {
10
11 /**
12 * Encode the given Byte sequence using the run length encoding.
13 *
14 * @param input the given byte sequence
15 * @return the encoded byte sequence
16 */
17 public static List<Byte> encode(List<Byte> input) {
18 List<Byte> output = new ArrayList<>();
19
20 return output;
21 }
22
23 /**
24 * Decode the given Byte sequence using the run length encoding.
25 *
26 * @param input the given encoded byte sequence
27 * @return the decoded byte sequence
28 */
29 public static List<Byte> decode(List<Byte> input) {
30 List<Byte> output = new ArrayList<>();
31
32 return output;
33 }
34}
diff --git a/src/ch/epfl/xblast/server/GameStateSerializer.java b/src/ch/epfl/xblast/server/GameStateSerializer.java
new file mode 100644
index 0000000..4a133e5
--- /dev/null
+++ b/src/ch/epfl/xblast/server/GameStateSerializer.java
@@ -0,0 +1,90 @@
1package ch.epfl.xblast.server;
2
3import ch.epfl.xblast.Cell;
4import ch.epfl.xblast.Direction;
5import ch.epfl.xblast.RunLengthEncoder;
6import ch.epfl.xblast.server.painter.*;
7
8import java.util.*;
9import java.util.stream.Collectors;
10
11/**
12 * @author Timothée FLOURE (257420)
13 */
14public final class GameStateSerializer {
15
16 /**
17 * @param painter
18 * @param board
19 * @return
20 */
21 private static List<Byte> serializeBoard(BoardPainter painter, Board board) {
22 return RunLengthEncoder.encode(Cell.SPIRAL_ORDER.stream()
23 .map(c -> painter.byteForCell(board, c))
24 .collect(Collectors.toList()));
25 }
26
27 private static byte serializeBlast(Set<Cell> blastedCells, Cell cell) {
28 return ExplosionPainter.byteForBlast(
29 blastedCells.contains(cell.neighbor(Direction.N)),
30 blastedCells.contains(cell.neighbor(Direction.E)),
31 blastedCells.contains(cell.neighbor(Direction.S)),
32 blastedCells.contains(cell.neighbor(Direction.W)));
33 }
34
35 private static byte serializeExplosion(Map<Cell, Bomb> bombedCells, Set<Cell> blastedCells, Cell cell) {
36 if (bombedCells.containsKey(cell))
37 return ExplosionPainter.byteForBomb(bombedCells.get(cell));
38 else
39 return serializeBlast(blastedCells, cell);
40 }
41
42 /**
43 * @param bombedCells
44 * @param blastedCells
45 * @return
46 */
47 private static List<Byte> serializeExplosions(Map<Cell, Bomb> bombedCells, Set<Cell> blastedCells) {
48 return RunLengthEncoder.encode(Cell.ROW_MAJOR_ORDER.stream()
49 .map(c -> serializeExplosion(bombedCells, blastedCells, c))
50 .collect(Collectors.toList()));
51 }
52
53 /**
54 * Serialize a whole game state.
55 *
56 * @param boardPainter board painter related to the actual level
57 * @param gameState GameState to be serialized
58 * @return the serialized game state
59 */
60 public static List<Byte> serialize(BoardPainter boardPainter, GameState gameState) {
61 List<Byte> output = new ArrayList<>();
62 List<Byte> data = new ArrayList<>();
63
64 // Board
65 data.addAll(serializeBoard(boardPainter, gameState.board()));
66
67 // Blasts and Bombs
68 data.addAll(serializeExplosions(gameState.bombedCells(), gameState.blastedCells()));
69
70 // Players
71 for (Player player : gameState.players()) {
72 List<Byte> serializedPlayer = new ArrayList<>();
73 serializedPlayer.add((byte) player.lives());
74 serializedPlayer.add((byte) player.position().x());
75 serializedPlayer.add((byte) player.position().y());
76 serializedPlayer.add(PlayerPainter.byteForPlayer(player, gameState.ticks()));
77
78 data.addAll(serializedPlayer);
79 }
80
81 // Ticks
82 data.add((byte) (gameState.remainingTime() / 2));
83
84 // Build output
85 output.add((byte) data.size());
86 output.addAll(data);
87
88 return output;
89 }
90}
diff --git a/src/ch/epfl/xblast/server/Level.java b/src/ch/epfl/xblast/server/Level.java
new file mode 100644
index 0000000..81bc85b
--- /dev/null
+++ b/src/ch/epfl/xblast/server/Level.java
@@ -0,0 +1,134 @@
1package ch.epfl.xblast.server;
2
3import ch.epfl.xblast.*;
4import ch.epfl.xblast.server.painter.*;
5
6import java.util.Arrays;
7import java.util.List;
8import java.util.HashMap;
9
10/**
11 * @author Timothée FLOURE (257420)
12 */
13public final class Level {
14
15 /** Players' initial parameters **/
16 private static final int PLAYER_INITIAL_LIVES = 5;
17 private static final int PLAYER_INITIAL_BOMB_MAXIMUM = 5;
18 private static final int PLAYER_INITIAL_BOMB_RANGE = 5;
19
20 /** Players' initial positions (Ugly!) **/
21 private static final Cell PLAYER_1_INITIAL_POSITION = new Cell(1,1);
22 private static final Cell PLAYER_2_INITIAL_POSITION = new Cell(16,1);
23 private static final Cell PLAYER_3_INITIAL_POSITION = new Cell(16,14);
24 private static final Cell PLAYER_4_INITIAL_POSITION = new Cell(1,14);
25
26 /** Level values **/
27 private final BoardPainter painter;
28 private final GameState initialState;
29
30 /**
31 * Build the default board of the game.
32 *
33 * @return the default board
34 */
35 private static BoardPainter buildDefaultBoardPainter() {
36 // Create the blocks map
37 HashMap<Block,BlockImage> blocksMap = new HashMap<>();
38
39 // Fill the blocks map
40 blocksMap.put(Block.FREE, BlockImage.IRON_FLOOR);
41 blocksMap.put(Block.DESTRUCTIBLE_WALL, BlockImage.EXTRA);
42 blocksMap.put(Block.CRUMBLING_WALL, BlockImage.EXTRA_O);
43 blocksMap.put(Block.INDESTRUCTIBLE_WALL, BlockImage.DARK_BLOCK);
44 blocksMap.put(Block.BONUS_BOMB, BlockImage.BONUS_BOMB);
45 blocksMap.put(Block.BONUS_RANGE, BlockImage.BONUS_RANGE);
46
47 // Create and return the board painter
48 return new BoardPainter(blocksMap, BlockImage.IRON_FLOOR_S);
49 }
50
51 /**
52 * Build the default game state of the game.
53 *
54 * @return the default game state
55 */
56 private static GameState buildDefaultGameState() {
57 return new GameState(buildDefaultBoard(), buildDefaultPlayers());
58 }
59
60 /**
61 * Build the default board of the game.
62 *
63 * @return the default board.
64 */
65 private static Board buildDefaultBoard() {
66
67 // Ugly!
68 Block __ = Block.FREE;
69 Block XX = Block.INDESTRUCTIBLE_WALL;
70 Block xx = Block.DESTRUCTIBLE_WALL;
71
72 return Board.ofQuadrantNWBlocksWalled(
73 Arrays.asList(
74 Arrays.asList(__, __, __, __, __, xx, __),
75 Arrays.asList(__, XX, xx, XX, xx, XX, xx),
76 Arrays.asList(__, xx, __, __, __, xx, __),
77 Arrays.asList(xx, XX, __, XX, XX, XX, XX),
78 Arrays.asList(__, xx, __, xx, __, __, __),
79 Arrays.asList(xx, XX, xx, XX, xx, XX, __)));
80 }
81
82 /**
83 * Build the default players of the games.
84 *
85 * @return a list of the 4 players built using the default parameters.
86 */
87 private static List<Player> buildDefaultPlayers() {
88 // Ugly!
89 return Arrays.asList(
90 new Player(PlayerID.PLAYER_1, PLAYER_INITIAL_LIVES, PLAYER_1_INITIAL_POSITION,
91 PLAYER_INITIAL_BOMB_MAXIMUM, PLAYER_INITIAL_BOMB_RANGE),
92 new Player(PlayerID.PLAYER_2, PLAYER_INITIAL_LIVES, PLAYER_2_INITIAL_POSITION,
93 PLAYER_INITIAL_BOMB_MAXIMUM, PLAYER_INITIAL_BOMB_RANGE),
94 new Player(PlayerID.PLAYER_3, PLAYER_INITIAL_LIVES, PLAYER_3_INITIAL_POSITION,
95 PLAYER_INITIAL_BOMB_MAXIMUM, PLAYER_INITIAL_BOMB_RANGE),
96 new Player(PlayerID.PLAYER_4, PLAYER_INITIAL_LIVES, PLAYER_4_INITIAL_POSITION,
97 PLAYER_INITIAL_BOMB_MAXIMUM, PLAYER_INITIAL_BOMB_RANGE)
98 );