From 7733b7dffe5a70c578713c34bdbabafee060d80a Mon Sep 17 00:00:00 2001 From: pacien Date: Mon, 8 Jan 2018 17:49:05 +0100 Subject: Implement board parser and its tests Signed-off-by: pacien --- src/main/java/fr/umlv/java/wallj/board/Board.java | 4 +- .../java/fr/umlv/java/wallj/board/BoardParser.java | 59 ++++++++++++++++++++-- src/main/java/fr/umlv/java/wallj/utils/Matrix.java | 32 ++++++++++-- .../fr/umlv/java/wallj/board/BoardParserTest.java | 41 +++++++++++++++ src/test/resources/maps/nonRectangular.txt | 3 ++ src/test/resources/maps/smallValid.txt | 3 ++ 6 files changed, 134 insertions(+), 8 deletions(-) create mode 100644 src/test/java/fr/umlv/java/wallj/board/BoardParserTest.java create mode 100644 src/test/resources/maps/nonRectangular.txt create mode 100644 src/test/resources/maps/smallValid.txt diff --git a/src/main/java/fr/umlv/java/wallj/board/Board.java b/src/main/java/fr/umlv/java/wallj/board/Board.java index dfcec88..fbe6ad9 100644 --- a/src/main/java/fr/umlv/java/wallj/board/Board.java +++ b/src/main/java/fr/umlv/java/wallj/board/Board.java @@ -44,8 +44,8 @@ public final class Board { private Board(BlockType[][] map) { int w = Matrix.getWidth(map), h = Matrix.getHeight(map); - this.map = new BlockType[w][h]; - for (int row = 0; row < w; ++row) System.arraycopy(map[row], 0, this.map[row], 0, h); + this.map = new BlockType[h][w]; + for (int row = 0; row < h; ++row) System.arraycopy(map[row], 0, this.map[row], 0, w); } /** diff --git a/src/main/java/fr/umlv/java/wallj/board/BoardParser.java b/src/main/java/fr/umlv/java/wallj/board/BoardParser.java index 77d836f..b7db602 100644 --- a/src/main/java/fr/umlv/java/wallj/board/BoardParser.java +++ b/src/main/java/fr/umlv/java/wallj/board/BoardParser.java @@ -1,6 +1,59 @@ package fr.umlv.java.wallj.board; -public class BoardParser { - //TODO -} +import fr.umlv.java.wallj.model.BlockType; +import fr.umlv.java.wallj.utils.Matrix; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.ListIterator; +import java.util.stream.Collectors; + +public final class BoardParser { + + private static Board buildBoard(List> map) { + if (!Matrix.isShapeValid(map)) throw new IllegalArgumentException("Board must be rectangular."); + + Board.Builder b = new Board.Builder(Matrix.getWidth(map), Matrix.getHeight(map)); + for (ListIterator> line = map.listIterator(); line.hasNext(); ) + for (ListIterator block = line.next().listIterator(); block.hasNext(); ) + b.setBlockTypeAt(TileVec2.of(line.previousIndex(), block.nextIndex()), block.next()); + + return b.build(); + } + private static BlockType parseChar(int c) { + switch (c) { + case ' ': + return BlockType.FREE; + case 'W': + return BlockType.wALL; + case 'T': + return BlockType.TRASH; + case 'G': + return BlockType.GARBAGE; + default: + return null; + } + } + + private static List parseLine(String line) { + return line.chars() + .mapToObj(BoardParser::parseChar) + .collect(Collectors.toList()); + } + + public static Board parse(Path filePath) throws IOException { + return buildBoard(Files.lines(filePath) + .filter(s -> !s.isEmpty()) + .map(String::trim) + .map(BoardParser::parseLine) + .collect(Collectors.toList())); + } + + private BoardParser() { + // static class + } + +} diff --git a/src/main/java/fr/umlv/java/wallj/utils/Matrix.java b/src/main/java/fr/umlv/java/wallj/utils/Matrix.java index e23cb2a..e3702bf 100644 --- a/src/main/java/fr/umlv/java/wallj/utils/Matrix.java +++ b/src/main/java/fr/umlv/java/wallj/utils/Matrix.java @@ -1,12 +1,14 @@ package fr.umlv.java.wallj.utils; +import java.util.List; + /** - * Utility functions for two dimension arrays. + * Utility functions for two dimension arrays and lists. */ public final class Matrix { /** - * @param m the matrix + * @param m the matrix (2D array) * @return the width of the matrix (0 if null) */ public static int getWidth(Object[][] m) { @@ -14,13 +16,37 @@ public final class Matrix { } /** - * @param m the matrix + * @param m the matrix (2D array) * @return the height of the matrix (0 if null) */ public static int getHeight(Object[][] m) { return m != null ? m.length : 0; } + /** + * @param m the matrix (2D List) + * @return the width of the matrix (0 if null) + */ + public static int getWidth(List> m) { + return m != null && m.size() > 0 ? m.get(0).size() : 0; + } + + /** + * @param m the matrix (2D List) + * @return the height of the matrix (0 if null) + */ + public static int getHeight(List> m) { + return m != null ? m.size() : 0; + } + + /** + * @param l the 2D list to check + * @return T(l is a valid matrix, i.e. all sub - arrays are of the same size and l is not null) + */ + public static boolean isShapeValid(List> l) { + return l != null && l.stream().mapToInt(List::size).allMatch(s -> s == l.get(0).size()); + } + private Matrix() { // static class } diff --git a/src/test/java/fr/umlv/java/wallj/board/BoardParserTest.java b/src/test/java/fr/umlv/java/wallj/board/BoardParserTest.java new file mode 100644 index 0000000..fdeebbe --- /dev/null +++ b/src/test/java/fr/umlv/java/wallj/board/BoardParserTest.java @@ -0,0 +1,41 @@ +package fr.umlv.java.wallj.board; + +import fr.umlv.java.wallj.model.BlockType; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.nio.file.Paths; + +final class BoardParserTest { + + private Path getResourcePath(String str) throws URISyntaxException { + return Paths.get(getClass().getResource(str).toURI()); + } + + @Test + void testFailParseBadShape() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { + BoardParser.parse(getResourcePath("/maps/nonRectangular.txt")); + }); + } + + @Test + void testParse() throws IOException, URISyntaxException { + BlockType W = BlockType.wALL, F = BlockType.FREE, G = BlockType.GARBAGE, T = BlockType.TRASH; + BlockType[][] blocks = new BlockType[][]{ + {W, W, W, W, W, W}, + {W, F, G, F, T, W}, + {W, W, W, W, W, W}}; + + Board board = BoardParser.parse(getResourcePath("/maps/smallValid.txt")); + + Assertions.assertEquals(board.getDim(), TileVec2.of(blocks.length, blocks[0].length)); + for (int row = 0; row < blocks.length; ++row) + for (int col = 0; col < blocks[0].length; ++col) + Assertions.assertEquals(board.getBlockTypeAt(TileVec2.of(row, col)), blocks[row][col]); + } + +} diff --git a/src/test/resources/maps/nonRectangular.txt b/src/test/resources/maps/nonRectangular.txt new file mode 100644 index 0000000..8d834db --- /dev/null +++ b/src/test/resources/maps/nonRectangular.txt @@ -0,0 +1,3 @@ +WWWWWWWWWW +W W +WWWWWWWWWW diff --git a/src/test/resources/maps/smallValid.txt b/src/test/resources/maps/smallValid.txt new file mode 100644 index 0000000..fa3a3a9 --- /dev/null +++ b/src/test/resources/maps/smallValid.txt @@ -0,0 +1,3 @@ +WWWWWW +W G TW +WWWWWW \ No newline at end of file -- cgit v1.2.3