aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam NAILI2018-02-03 23:20:03 +0100
committerAdam NAILI2018-02-03 23:20:03 +0100
commit78bfc15d36b94058b1f896ec7c8d753e2e487a1d (patch)
treef2c66df5838b11fad91a834b8b3c0cdc67d3369b
parentc4fa546ef067317bd5e22cdad40792cbd33035d7 (diff)
parent745b3c798de97785dd92e1a3db83cfdb2801ee87 (diff)
downloadwallj-78bfc15d36b94058b1f896ec7c8d753e2e487a1d.tar.gz
Merge branch 'master' of https://github.com/pacien/upem-java-wallj
-rw-r--r--src/main/java/fr/umlv/java/wallj/block/RobotBlock.java13
-rw-r--r--src/main/java/fr/umlv/java/wallj/board/PathFinder.java4
-rw-r--r--src/main/java/fr/umlv/java/wallj/context/Stage.java13
-rw-r--r--src/main/java/fr/umlv/java/wallj/event/SimulationStartOrder.java10
-rw-r--r--src/test/java/fr/umlv/java/wallj/board/PathFinderTest.java39
-rw-r--r--src/test/resources/maps/wall.txt7
6 files changed, 66 insertions, 20 deletions
diff --git a/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java b/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java
index da7f3cf..f81f423 100644
--- a/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java
+++ b/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java
@@ -27,6 +27,7 @@ public class RobotBlock extends Block {
27 private Vec2 pos; 27 private Vec2 pos;
28 private PathFinder pathFinder; 28 private PathFinder pathFinder;
29 private Deque<TileVec2> path = new LinkedList<>(); 29 private Deque<TileVec2> path = new LinkedList<>();
30 private int droppedBombCount = 0;
30 31
31 RobotBlock(Vec2 pos) { 32 RobotBlock(Vec2 pos) {
32 super(BlockType.ROBOT); 33 super(BlockType.ROBOT);
@@ -62,10 +63,17 @@ public class RobotBlock extends Block {
62 return Events.findFirst(events, BombSetupOrder.class) 63 return Events.findFirst(events, BombSetupOrder.class)
63 .map(event -> isOnBomb(stage) ? 64 .map(event -> isOnBomb(stage) ?
64 Collections.<Event>singletonList(new BombTimerIncrEvent(getTile())) : 65 Collections.<Event>singletonList(new BombTimerIncrEvent(getTile())) :
65 Collections.<Event>singletonList(new BlockCreateEvent(BlockType.BOMB, getTile()))) 66 dropBomb(event))
66 .orElse(Collections.emptyList()); 67 .orElse(Collections.emptyList());
67 } 68 }
68 69
70 private List<Event> dropBomb(BombSetupOrder order) {
71 if (droppedBombCount >= Stage.BOMB_PLACEMENTS) return Collections.emptyList();
72
73 droppedBombCount++;
74 return Collections.singletonList(new BlockCreateEvent(BlockType.BOMB, getTile()));
75 }
76
69 private void updatePath(Board board, TileVec2 target) { 77 private void updatePath(Board board, TileVec2 target) {
70 if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return; 78 if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return;
71 if (pathFinder == null) pathFinder = new PathFinder(board); 79 if (pathFinder == null) pathFinder = new PathFinder(board);
@@ -85,6 +93,9 @@ public class RobotBlock extends Block {
85 graphicsContext.paintCircle(Color.BLUE, getPos(), TileVec2.TILE_DIM / 2); 93 graphicsContext.paintCircle(Color.BLUE, getPos(), TileVec2.TILE_DIM / 2);
86 } 94 }
87 95
96 /**
97 * @implNote TODO: profile this and consider a mapping (pos: block) for faster lookup in Stage
98 */
88 private boolean isOnBomb(Stage stage) { 99 private boolean isOnBomb(Stage stage) {
89 return stage.getBlocks().stream() 100 return stage.getBlocks().stream()
90 .anyMatch(block -> Objects.equals(block.getType(), BlockType.BOMB) && 101 .anyMatch(block -> Objects.equals(block.getType(), BlockType.BOMB) &&
diff --git a/src/main/java/fr/umlv/java/wallj/board/PathFinder.java b/src/main/java/fr/umlv/java/wallj/board/PathFinder.java
index c530d83..dfd1fa6 100644
--- a/src/main/java/fr/umlv/java/wallj/board/PathFinder.java
+++ b/src/main/java/fr/umlv/java/wallj/board/PathFinder.java
@@ -57,7 +57,7 @@ public class PathFinder {
57 57
58 private static <T> List<T> findPath(Node<T> start, T target, BiFunction<T, T, Double> heuristic) { 58 private static <T> List<T> findPath(Node<T> start, T target, BiFunction<T, T, Double> heuristic) {
59 Map<Node<T>, NodeSearchData<T>> searchData = new HashMap<>(); 59 Map<Node<T>, NodeSearchData<T>> searchData = new HashMap<>();
60 TreeSet<Node<T>> discovered = new TreeSet<>(Comparator.comparingDouble(n -> searchData.get(n).estimatedCost)); 60 Queue<Node<T>> discovered = new PriorityQueue<>(Comparator.comparingDouble(n -> searchData.get(n).estimatedCost));
61 Set<Node<T>> visited = new HashSet<>(); 61 Set<Node<T>> visited = new HashSet<>();
62 62
63 searchData.put(start, new NodeSearchData<>(null, 0, heuristic.apply(start.val, target))); 63 searchData.put(start, new NodeSearchData<>(null, 0, heuristic.apply(start.val, target)));
@@ -65,7 +65,7 @@ public class PathFinder {
65 65
66 Node<T> current; 66 Node<T> current;
67 while (!discovered.isEmpty()) { 67 while (!discovered.isEmpty()) {
68 current = discovered.pollFirst(); 68 current = discovered.poll();
69 if (target.equals(current.val)) return buildPath(searchData, current); 69 if (target.equals(current.val)) return buildPath(searchData, current);
70 70
71 for (Map.Entry<Node<T>, Integer> neighborEntry : current.neighbors.entrySet()) { 71 for (Map.Entry<Node<T>, Integer> neighborEntry : current.neighbors.entrySet()) {
diff --git a/src/main/java/fr/umlv/java/wallj/context/Stage.java b/src/main/java/fr/umlv/java/wallj/context/Stage.java
index 49aa196..9737583 100644
--- a/src/main/java/fr/umlv/java/wallj/context/Stage.java
+++ b/src/main/java/fr/umlv/java/wallj/context/Stage.java
@@ -17,6 +17,7 @@ import java.util.*;
17 * @author Pacien TRAN-GIRARD 17 * @author Pacien TRAN-GIRARD
18 */ 18 */
19public class Stage implements Updateable { 19public class Stage implements Updateable {
20 public static final int BOMB_PLACEMENTS = 3;
20 private static final int VELOCITY_TICK_PER_MS = 6; 21 private static final int VELOCITY_TICK_PER_MS = 6;
21 private static final int POSITION_TICK_PER_MS = 2; 22 private static final int POSITION_TICK_PER_MS = 2;
22 23
@@ -60,7 +61,17 @@ public class Stage implements Updateable {
60 * @implNote TODO: profile this and consider a garbage block counter 61 * @implNote TODO: profile this and consider a garbage block counter
61 */ 62 */
62 public boolean isCleared() { 63 public boolean isCleared() {
63 return blocks.stream().noneMatch(block -> block.getType() == BlockType.GARBAGE); 64 return blocks.stream()
65 .noneMatch(block -> block.getType() == BlockType.GARBAGE);
66 }
67
68 /**
69 * @return T(the physics simulation can start, i.e. the player has placed all their bombs)
70 */
71 public boolean isReady() {
72 return blocks.stream()
73 .filter(block -> block.getType() == BlockType.BOMB)
74 .count() == BOMB_PLACEMENTS;
64 } 75 }
65 76
66 /** 77 /**
diff --git a/src/main/java/fr/umlv/java/wallj/event/SimulationStartOrder.java b/src/main/java/fr/umlv/java/wallj/event/SimulationStartOrder.java
new file mode 100644
index 0000000..a268ed0
--- /dev/null
+++ b/src/main/java/fr/umlv/java/wallj/event/SimulationStartOrder.java
@@ -0,0 +1,10 @@
1package fr.umlv.java.wallj.event;
2
3/**
4 * Signals the beginning of the physics simulation.
5 *
6 * @author Pacien TRAN-GIRARD
7 */
8public final class SimulationStartOrder implements InputEvent {
9 // void
10}
diff --git a/src/test/java/fr/umlv/java/wallj/board/PathFinderTest.java b/src/test/java/fr/umlv/java/wallj/board/PathFinderTest.java
index be615b7..ddacf71 100644
--- a/src/test/java/fr/umlv/java/wallj/board/PathFinderTest.java
+++ b/src/test/java/fr/umlv/java/wallj/board/PathFinderTest.java
@@ -14,7 +14,6 @@ import java.util.List;
14 * @author Pacien TRAN-GIRARD 14 * @author Pacien TRAN-GIRARD
15 */ 15 */
16final class PathFinderTest { 16final class PathFinderTest {
17
18 private Path getResourcePath(String str) throws URISyntaxException { 17 private Path getResourcePath(String str) throws URISyntaxException {
19 return Paths.get(getClass().getResource(str).toURI()); 18 return Paths.get(getClass().getResource(str).toURI());
20 } 19 }
@@ -35,29 +34,37 @@ final class PathFinderTest {
35 return true; 34 return true;
36 } 35 }
37 36
38 @Test 37 private void testValidPath(Board board, TileVec2 origin, TileVec2 target) {
39 void testFailImpossibleFindPath() throws URISyntaxException, IOException {
40 Board board = BoardParser.parse(getResourcePath("/maps/island.txt"));
41 PathFinder pathFinder = new PathFinder(board); 38 PathFinder pathFinder = new PathFinder(board);
39 List<TileVec2> path = pathFinder.findPath(origin, target);
42 40
43 Assertions.assertThrows(IllegalArgumentException.class, () -> { 41 Assertions.assertEquals(path.get(0), origin);
44 pathFinder.findPath(TileVec2.of(7, 3), TileVec2.of(16, 5)); // into a wall 42 Assertions.assertEquals(path.get(path.size() - 1), target);
45 }); 43 Assertions.assertTrue(isPathConnected(path));
44 Assertions.assertTrue(path.stream().allMatch(v -> board.getBlockTypeAt(v).isTraversable()));
46 } 45 }
47 46
48 @Test 47 @Test
49 void testFindPath() throws URISyntaxException, IOException { 48 void testFindPath() throws URISyntaxException, IOException {
49 testValidPath(
50 BoardParser.parse(getResourcePath("/maps/wall.txt")),
51 TileVec2.of(4, 3),
52 TileVec2.of(6, 3));
53
54 testValidPath(
55 BoardParser.parse(getResourcePath("/maps/island.txt")),
56 TileVec2.of(7, 3),
57 TileVec2.of(33, 4));
58 }
59
60
61 @Test
62 void testFailImpossibleFindPath() throws URISyntaxException, IOException {
50 Board board = BoardParser.parse(getResourcePath("/maps/island.txt")); 63 Board board = BoardParser.parse(getResourcePath("/maps/island.txt"));
51 PathFinder pathFinder = new PathFinder(board); 64 PathFinder pathFinder = new PathFinder(board);
52 65
53 TileVec2 origin = TileVec2.of(7, 3); 66 Assertions.assertThrows(IllegalArgumentException.class, () -> {
54 TileVec2 target = TileVec2.of(33, 4); 67 pathFinder.findPath(TileVec2.of(7, 3), TileVec2.of(16, 5)); // into a wall
55 List<TileVec2> path = pathFinder.findPath(origin, target); 68 });
56
57 Assertions.assertEquals(path.get(0), origin);
58 Assertions.assertEquals(path.get(path.size() - 1), target);
59 Assertions.assertTrue(isPathConnected(path));
60 Assertions.assertTrue(path.stream().allMatch(v -> board.getBlockTypeAt(v).isTraversable()));
61 } 69 }
62
63} 70}
diff --git a/src/test/resources/maps/wall.txt b/src/test/resources/maps/wall.txt
new file mode 100644
index 0000000..97a5874
--- /dev/null
+++ b/src/test/resources/maps/wall.txt
@@ -0,0 +1,7 @@
1WWWWWWWWWWW
2W W
3W W W
4W W W
5W W W
6W W
7WWWWWWWWWWW \ No newline at end of file