Using 17*17 bitfield. Using Direction.reached(...). Providing real world test that failed in my game with Martin Rexa.
1.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Tue Sep 15 21:46:30 2009 +0200
1.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Fri Sep 18 07:16:47 2009 +0200
1.3 @@ -129,9 +129,10 @@
1.4 this.players = Collections.unmodifiableList (players);
1.5 this.fences = Collections.unmodifiableSet (fences);
1.6 this.occupied = computeOccupied (players, fences);
1.7 -
1.8 +
1.9 for (Player p : players) {
1.10 - if (!accessibleFinalLine (p, p.endDirection, occupied, new BitSet ())) {
1.11 + BitSet bs = new BitSet(17 * 17);
1.12 + if (!accessibleFinalLine (p, p.endDirection, occupied, bs)) {
1.13 throw new IllegalPositionException ("Player " + p + " cannot reach " + p.endDirection + " side"); // NOI18N
1.14 }
1.15 }
1.16 @@ -765,22 +766,9 @@
1.17 // already visited without success
1.18 return false;
1.19 }
1.20 -
1.21 - switch (endDir) {
1.22 - case NORTH:
1.23 - if (position.getYInternal() == 8) return true;
1.24 - break;
1.25 - case SOUTH:
1.26 - if (position.getYInternal() == 0) return true;
1.27 - break;
1.28 - case EAST:
1.29 - if (position.getXInternal() == 0) return true;
1.30 - break;
1.31 - case WEST:
1.32 - if (position.getXInternal() == 8) return true;
1.33 - break;
1.34 - default:
1.35 - throw new IllegalStateException ("Wrong direction: " + endDir); // NOI18N
1.36 +
1.37 + if (endDir.reached(position)) {
1.38 + return true;
1.39 }
1.40
1.41 reached.set (index);
1.42 @@ -803,7 +791,7 @@
1.43 private static BitSet computeOccupied (
1.44 Collection<Player> players, Collection<Fence> fences
1.45 ) throws IllegalPositionException {
1.46 - BitSet occupied = new BitSet (20 * 30); // TBD this is just an upper guess
1.47 + BitSet occupied = new BitSet (17 * 17);
1.48
1.49 for (Player p : players) {
1.50 if (p.getXInternal() % 2 == 1) throw new IllegalPositionException ("Wrong player position: " + p); // NOI18N
1.51 @@ -868,9 +856,9 @@
1.52 * </pre>
1.53 */
1.54 private static int toIndex (int x, int y) {
1.55 - int max = x + y;
1.56 - int baseOnY0 = max * (max + 1) / 2;
1.57 - return baseOnY0 + y;
1.58 + assert x >= 0 && x < 17;
1.59 + assert y >= 0 && y < 17;
1.60 + return 17 * y + x;
1.61 }
1.62
1.63 }
2.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Tue Sep 15 21:46:30 2009 +0200
2.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Fri Sep 18 07:16:47 2009 +0200
2.3 @@ -145,6 +145,60 @@
2.4 }
2.5 }
2.6
2.7 + public void testSelfDestructionForbidden() throws Exception {
2.8 + Board b = board;
2.9 +
2.10 + b = fence(b, 0, 'D', 1, Orientation.VERTICAL);
2.11 + b = move(b, 1, Player.Direction.SOUTH);
2.12 + b = fence(b, 0, 'E', 1, Orientation.VERTICAL);
2.13 + b = move(b, 1, Player.Direction.SOUTH);
2.14 + try {
2.15 + b = fence(b, 0, 'E', 2, Orientation.HORIZONTAL);
2.16 + fail ("Forbidden. Player 0 has no way to reach the end");
2.17 + } catch (IllegalPositionException ex) {
2.18 + // ok
2.19 + }
2.20 +
2.21 + }
2.22 + public void testRealSelfDestructionForbidden() throws Exception {
2.23 + String b = "" +
2.24 + " [N] \n" +
2.25 + "\n" +
2.26 +" A B C D E F G H\n" +
2.27 +" | | | | | | | |\n" +
2.28 +" +*----------------------------------+\n" +
2.29 +" | |\n" +
2.30 +" 8--|-------+-------+-------+-------+ |--8\n" +
2.31 +" | | | |\n" +
2.32 +" 7--| + + + |-------+ | + |--7\n" +
2.33 +" | | | | |\n" +
2.34 +" 6--| + + + + + | + + |--6\n" +
2.35 +" | | | |\n" +
2.36 +" 5--| + + + + |-------+ + |--5\n" +
2.37 +"[W] | | | [E]\n" +
2.38 +" 4--| + + + + +-------+ + |--4\n" +
2.39 +" | | | |\n" +
2.40 +" 3--| + + + + + + | | |--3\n" +
2.41 +" | P | Q | |\n" +
2.42 +" 2--| + + + + + + + + |--2\n" +
2.43 +" | | |\n" +
2.44 +" 1--| + + + + + | +-------|--1\n" +
2.45 +" | | |\n" +
2.46 +" +||||-------------------------------+\n" +
2.47 +" | | | | | | | |\n" +
2.48 +" A B C D E F G H\n" +
2.49 +"\n" +
2.50 +" [S] \n";
2.51 +
2.52 + Board begin = Board.valueOf(b);
2.53 +
2.54 + try {
2.55 + Board bad = fence(begin, 0, 'G', 2, Orientation.HORIZONTAL);
2.56 + fail("Not allowed move:\n" + bad.toString());
2.57 + } catch (IllegalPositionException ex) {
2.58 + // OK
2.59 + }
2.60 + }
2.61 public void testFourTimesInAgainstEachOtherResultsInInvalidPosition () throws Exception {
2.62 Board b = board;
2.63