From d60cd3c353b4132e3d37122a274ecc3cbe43b78e Mon Sep 17 00:00:00 2001 From: Timothée Floure Date: Sat, 30 Apr 2016 17:33:41 +0200 Subject: Fix the GameStateSerializer (comply with the subject) --- src/ch/epfl/xblast/RunLengthEncoder.java | 2 +- src/ch/epfl/xblast/server/GameStateSerializer.java | 50 +++++++++++++++++----- src/ch/epfl/xblast/server/Level.java | 8 ++-- .../xblast/server/painter/ExplosionPainter.java | 5 +++ test/ch/epfl/xblast/GameStateSerializerTest.java | 44 ++++++++++++++----- 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/src/ch/epfl/xblast/RunLengthEncoder.java b/src/ch/epfl/xblast/RunLengthEncoder.java index ecb9f4e..d7ab106 100644 --- a/src/ch/epfl/xblast/RunLengthEncoder.java +++ b/src/ch/epfl/xblast/RunLengthEncoder.java @@ -189,4 +189,4 @@ public final class RunLengthEncoder { .collect(Collectors.toList()); } -} +} \ No newline at end of file diff --git a/src/ch/epfl/xblast/server/GameStateSerializer.java b/src/ch/epfl/xblast/server/GameStateSerializer.java index 998ff21..049e993 100644 --- a/src/ch/epfl/xblast/server/GameStateSerializer.java +++ b/src/ch/epfl/xblast/server/GameStateSerializer.java @@ -47,13 +47,17 @@ public final class GameStateSerializer { * @param bombedCells cells containing a bomb * @param blastedCells cells containing a blast * @param cell cell hosting the explosion + * @param board actual Board * @return the serialized explosion */ - private static byte serializeExplosion(Map bombedCells, Set blastedCells, Cell cell) { + private static byte serializeExplosion(Map bombedCells, Set blastedCells, Cell cell, Board board) { if (bombedCells.containsKey(cell)) return ExplosionPainter.byteForBomb(bombedCells.get(cell)); - else + + if (blastedCells.contains(cell) && board.blockAt(cell).isFree()) return serializeBlast(blastedCells, cell); + + return ExplosionPainter.INVALID_EXPLOSION_IMAGE_ID; } /** @@ -61,14 +65,28 @@ public final class GameStateSerializer { * * @param bombedCells cells containing a bomb * @param blastedCells cells containing a blast + * @param board actual Board * @return the serialized explosions */ - private static List serializeExplosions(Map bombedCells, Set blastedCells) { + private static List serializeExplosions(Map bombedCells, Set blastedCells, Board board) { return RunLengthEncoder.encode(Cell.ROW_MAJOR_ORDER.stream() - .map(c -> serializeExplosion(bombedCells, blastedCells, c)) + .map(c -> serializeExplosion(bombedCells, blastedCells, c, board)) .collect(Collectors.toList())); } + /** + * Prepend its size to a Byte List. + * + * @param list Byte List to be prefixed + * @return the Byte List prefixed with its size + */ + private static List prefixByteListWithSize(List list) { + List prefixedList = new ArrayList<>(); + prefixedList.add((byte) list.size()); + prefixedList.addAll(list); + return prefixedList; + } + /** * Serialize a Player. * @@ -96,17 +114,27 @@ public final class GameStateSerializer { */ public static List serialize(BoardPainter boardPainter, GameState gameState) { List output = new ArrayList<>(); - List data = new ArrayList<>(); - data.addAll(serializeBoard(boardPainter, gameState.board())); // Serialize the Board - data.addAll(serializeExplosions(gameState.bombedCells(), gameState.blastedCells())); // Serialize Explosions + // Add the serialized Board to the output + output.addAll( + prefixByteListWithSize( + serializeBoard(boardPainter, gameState.board()) + ) + ); + + // Add the serialized Explosions to the output + output.addAll( + prefixByteListWithSize( + serializeExplosions(gameState.bombedCells(), gameState.blastedCells(), gameState.board()) + ) + ); + + // Add the serialized Players to the output for (Player player : gameState.players()) { - data.addAll(serializePlayer(player, gameState.ticks())); // Serialize each Player + output.addAll(serializePlayer(player, gameState.ticks())); // Serialize each Player } - data.add((byte) (gameState.remainingTime() / 2)); // Add the state Tick to the data - output.add((byte) data.size()); // Get the size of the whole data chunk and add it as first element of the output - output.addAll(data); // Add all the data to the output + output.add((byte) (gameState.remainingTime() / 2)); // Add the state Tick to the output return output; } diff --git a/src/ch/epfl/xblast/server/Level.java b/src/ch/epfl/xblast/server/Level.java index 81bc85b..155b99a 100644 --- a/src/ch/epfl/xblast/server/Level.java +++ b/src/ch/epfl/xblast/server/Level.java @@ -13,15 +13,15 @@ import java.util.HashMap; public final class Level { /** Players' initial parameters **/ - private static final int PLAYER_INITIAL_LIVES = 5; + private static final int PLAYER_INITIAL_LIVES = 3; private static final int PLAYER_INITIAL_BOMB_MAXIMUM = 5; private static final int PLAYER_INITIAL_BOMB_RANGE = 5; /** Players' initial positions (Ugly!) **/ private static final Cell PLAYER_1_INITIAL_POSITION = new Cell(1,1); - private static final Cell PLAYER_2_INITIAL_POSITION = new Cell(16,1); - private static final Cell PLAYER_3_INITIAL_POSITION = new Cell(16,14); - private static final Cell PLAYER_4_INITIAL_POSITION = new Cell(1,14); + private static final Cell PLAYER_2_INITIAL_POSITION = new Cell(13,1); + private static final Cell PLAYER_3_INITIAL_POSITION = new Cell(13,11); + private static final Cell PLAYER_4_INITIAL_POSITION = new Cell(1,11); /** Level values **/ private final BoardPainter painter; diff --git a/src/ch/epfl/xblast/server/painter/ExplosionPainter.java b/src/ch/epfl/xblast/server/painter/ExplosionPainter.java index 63181e9..83c6176 100644 --- a/src/ch/epfl/xblast/server/painter/ExplosionPainter.java +++ b/src/ch/epfl/xblast/server/painter/ExplosionPainter.java @@ -14,6 +14,11 @@ public final class ExplosionPainter { private static final byte SOUTH_EXPLOSION = 0b0010; private static final byte WEST_EXPLOSION = 0b0001; + /** + * Image ID corresponding to an explosion-free (and bomb-free) cell. + */ + public static final byte INVALID_EXPLOSION_IMAGE_ID = (byte) 16; + /** * Return the image corresponding to a bomb depending on its fuse length. * diff --git a/test/ch/epfl/xblast/GameStateSerializerTest.java b/test/ch/epfl/xblast/GameStateSerializerTest.java index a701d2b..881b1ec 100644 --- a/test/ch/epfl/xblast/GameStateSerializerTest.java +++ b/test/ch/epfl/xblast/GameStateSerializerTest.java @@ -5,9 +5,11 @@ import ch.epfl.xblast.server.Level; import org.junit.Assert; import org.junit.Test; +import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * @author Timothée FLOURE (257420) @@ -15,25 +17,45 @@ import java.util.List; public class GameStateSerializerTest { @Test - public void GameStateSerializerTest() { - List integerExpectedValues = Arrays.asList(121, -50, 2, 1, -2, 0, 3, 1, 3, 1, -2, 0, 1, 1, 3, 1, 3, + public void IntialGameStateSerializationTest() { + List sourceValues = Arrays.asList( + // Serialized Board + 121, -50, 2, 1, -2, 0, 3, 1, 3, 1, -2, 0, 1, 1, 3, 1, 3, 1, 3, 1, 1, -2, 0, 1, 3, 1, 3, -2, 0, -1, 1, 3, 1, 3, 1, 3, 1, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 1, 0, 0, 3, 1, 3, 1, 0, 0, 1, 1, 3, 1, 1, 0, 0, 1, 3, 1, 3, 0, 0, -1, 1, 3, 1, 1, -5, 2, 3, 2, 3, -5, 2, 3, 2, - 3, 1, -2, 0, 3, -2, 0, 1, 3, 2, 1, 2, 4, -128, 16, -63, - 16, 3, 24, 24, 6, 3, -40, 24, 26, 3, -40, -72, 46, 3, 24, - -72, 66, 60); - List expectedValues = new ArrayList<>(); + 3, 1, -2, 0, 3, -2, 0, 1, 3, 2, 1, 2, + // Explosions (blasts & bombs) + 4, -128, 16, -63, 16, + // Players + 3, 24, 24, 6, + 3, -40, 24, 26, + 3, -40, -72, 46, + 3, 24, -72, 66, + // Ticks + 60); - for (Integer i : integerExpectedValues) { - expectedValues.add((byte) i.intValue()); - } + // Build a List of Bytes from the Expected Values + List expectedValues = sourceValues.stream().map(i -> (byte) i.intValue()).collect(Collectors.toList()); + // Get the actual values + List actualValues = GameStateSerializer.serialize( + Level.DEFAULT_LEVEL.painter(), + Level.DEFAULT_LEVEL.initialState() + ); + + // Check the first element (number of elements) + Assert.assertEquals( + Byte.toUnsignedInt(expectedValues.get(0)), + Byte.toUnsignedInt(actualValues.get(0)) + ); + + // Check the rest of the data chunk Assert.assertEquals( - expectedValues, - GameStateSerializer.serialize(Level.DEFAULT_LEVEL.painter(), Level.DEFAULT_LEVEL.initialState()) + expectedValues.subList(1,expectedValues.size()), + actualValues.subList(1,expectedValues.size()) ); } } -- cgit v1.2.3