Using 17*17 bitfield. Using Direction.reached(...). Providing real world test that failed in my game with Martin Rexa.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Fri, 18 Sep 2009 07:16:47 +0200
changeset 92de3dd5710a5c
parent 90 63ec24914da9
child 93 af00332a19d9
Using 17*17 bitfield. Using Direction.reached(...). Providing real world test that failed in my game with Martin Rexa.
quoridor/src/main/java/cz/xelfi/quoridor/Board.java
quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java
     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