quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 17 Jan 2010 14:36:03 +0100
changeset 219 d836818f5554
parent 179 c5fbddc4c590
child 237 38db4aae19d9
permissions -rw-r--r--
Decoding of vertical walls on column A was broken
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * The contents of this file are subject to the terms of either the GNU
     5  * General Public License Version 2 only ("GPL") or the Common
     6  * Development and Distribution License("CDDL") (collectively, the
     7  * "License"). You may not use this file except in compliance with the
     8  * License. You can obtain a copy of the License at
     9  * http://www.netbeans.org/cddl-gplv2.html
    10  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    11  * specific language governing permissions and limitations under the
    12  * License.  When distributing the software, include this License Header
    13  * Notice in each file and include the License file at
    14  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    15  * particular file as subject to the "Classpath" exception as provided
    16  * by Sun in the GPL Version 2 section of the License file that
    17  * accompanied this code. If applicable, add the following below the
    18  * License Header, with the fields enclosed by brackets [] replaced by
    19  * your own identifying information:
    20  * "Portions Copyrighted [year] [name of copyright owner]"
    21  *
    22  * Contributor(s):
    23  *
    24  * Portions Copyrighted 2009 Jaroslav Tulach
    25  */
    26 package cz.xelfi.quoridor;
    27 
    28 import cz.xelfi.quoridor.Fence.Orientation;
    29 import cz.xelfi.quoridor.Player.Direction;
    30 import java.io.IOException;
    31 import java.io.StringReader;
    32 import java.io.StringWriter;
    33 import java.util.List;
    34 import junit.framework.TestCase;
    35 
    36 /**
    37  *
    38  * @author Jaroslav Tulach <jtulach@netbeans.org>
    39  */
    40 public abstract class BoardCase extends TestCase {
    41     protected Board board;
    42 
    43     protected BoardCase(String n) {
    44         super(n);
    45         board = Board.empty();
    46     }
    47 
    48     protected abstract Board move(Board b, int player, Player.Direction... where)
    49     throws IllegalPositionException;
    50 
    51     protected abstract Board fence(Board b, int player, char x, int y, Fence.Orientation orie)
    52     throws IllegalPositionException;
    53 
    54     protected abstract Board apply(Board b, Move move) throws IllegalPositionException;
    55 
    56 
    57     public void testResignWhite() throws IllegalPositionException {
    58         List<Player> list = board.getPlayers();
    59         assertEquals ("Two", 2, list.size ());
    60         Board b = board.apply(Move.RESIGN);
    61         assertEquals(b.getPlayers().get(1), b.getWinner());
    62         try {
    63             b.apply(Move.EAST);
    64             fail("No more moves allowed, the player resigned");
    65         } catch (IllegalPositionException ex) {
    66             // OK
    67         }
    68         assertNull("No player", b.getCurrentPlayer());
    69     }
    70     public void testResignBlack() throws IllegalPositionException {
    71         List<Player> list = board.getPlayers();
    72         assertEquals ("Two", 2, list.size ());
    73         Board b = board.apply(Move.NORTH).apply(Move.RESIGN);
    74         assertEquals(b.getPlayers().get(0), b.getWinner());
    75         try {
    76             b.apply(Move.EAST);
    77             fail("No more moves allowed, the player resigned");
    78         } catch (IllegalPositionException ex) {
    79             // OK
    80         }
    81         assertNull("No player", b.getCurrentPlayer());
    82     }
    83     public void testTwoPlayers () {
    84         List<Player> list = board.getPlayers();
    85         assertEquals ("Two", 2, list.size ());
    86         assertFalse ("Both are non-null", list.contains (null));
    87         try {
    88             list.add (null);
    89             fail ("Modifications are not allowed");
    90         } catch (UnsupportedOperationException ex) {
    91             // ok
    92         }
    93         try {
    94             list.remove (0);
    95             fail ("Modifications are not allowed");
    96         } catch (UnsupportedOperationException ex) {
    97             // ok
    98         }
    99         
   100         
   101         assertEquals (8, list.get (0).getXInternal());
   102         assertEquals (0, list.get (0).getYInternal());
   103         assertEquals (10, list.get (0).getFences ());
   104         assertEquals (8, list.get (1).getXInternal());
   105         assertEquals (16, list.get (1).getYInternal());
   106         assertEquals (10, list.get (1).getFences ());
   107     }
   108     
   109     public void testFences () throws IllegalPositionException {
   110         assertEquals ("No on board", 0, board.getFences ().size ());
   111         try {
   112             board.getFences ().add (null);
   113             fail ("Should be unmodifiable");
   114         } catch (java.lang.UnsupportedOperationException ex) {
   115             // ok
   116         }
   117 
   118         {
   119             Board b = board.apply(Move.fence('A', 1, Orientation.HORIZONTAL));
   120             assertEquals("One fence placed: ", 1, b.getFences().size());
   121             Fence f = b.getFences().iterator().next();
   122             assertEquals("Row", 1, f.getRow());
   123             assertEquals("Column", 'A', f.getColumn());
   124         }
   125 
   126         {
   127             Board b = board.apply(Move.fence('A', 1, Orientation.VERTICAL));
   128             assertEquals("One fence placed: ", 1, b.getFences().size());
   129             Fence f = b.getFences().iterator().next();
   130             assertEquals("Row", 1, f.getRow());
   131             assertEquals("Column", 'A', f.getColumn());
   132         }
   133 
   134         {
   135             Board b = board.apply(Move.fence('H', 8, Orientation.HORIZONTAL));
   136             assertEquals("One fence placed: ", 1, b.getFences().size());
   137             Fence f = b.getFences().iterator().next();
   138             assertEquals("Row", 8, f.getRow());
   139             assertEquals("Column", 'H', f.getColumn());
   140         }
   141 
   142         {
   143             Board b = board.apply(Move.fence('H', 8, Orientation.VERTICAL));
   144             assertEquals("One fence placed: ", 1, b.getFences().size());
   145             Fence f = b.getFences().iterator().next();
   146             assertEquals("Row", 8, f.getRow());
   147             assertEquals("Column", 'H', f.getColumn());
   148         }
   149     }
   150     public void testTwoFencesInTheSamePosition() throws IllegalPositionException {
   151         assertEquals ("No on board", 0, board.getFences ().size ());
   152         Board one = board.apply(Move.fence('A', 1, Orientation.HORIZONTAL));
   153         try {
   154             Board snd = one.apply(Move.fence('A', 1, Orientation.HORIZONTAL));
   155             fail("Cannot place fence twice to the same place");
   156         } catch (IllegalPositionException ex) {
   157             // OK
   158         }
   159     }
   160     
   161     public void testSelfDestructionForbidden() throws Exception {
   162         Board b = board;
   163 
   164         b = fence(b, 0, 'D', 1, Orientation.VERTICAL);
   165         b = move(b, 1, Player.Direction.SOUTH);
   166         b = fence(b, 0, 'E', 1, Orientation.VERTICAL);
   167         b = move(b, 1, Player.Direction.SOUTH);
   168         try {
   169             b = fence(b, 0, 'E', 2, Orientation.HORIZONTAL);
   170             fail ("Forbidden. Player 0 has no way to reach the end");
   171         } catch (IllegalPositionException ex) {
   172             // ok
   173         }
   174 
   175     }
   176     public void testRealSelfDestructionForbidden() throws Exception {
   177         String b = "" +
   178             "                         [N]    \n" +
   179             "\n" +
   180 "            A   B   C   D   E   F   G   H\n" +
   181 "            |   |   |   |   |   |   |   |\n" +
   182 "        +*----------------------------------+\n" +
   183 "        |                                   |\n" +
   184 "     8--|-------+-------+-------+-------+   |--8\n" +
   185 "        |               |           |       |\n" +
   186 "     7--|   +   +   +   |-------+   |   +   |--7\n" +
   187 "        |               |       |   |       |\n" +
   188 "     6--|   +   +   +   +   +   |   +   +   |--6\n" +
   189 "        |                   |   |           |\n" +
   190 "     5--|   +   +   +   +   |-------+   +   |--5\n" +
   191 "[W]     |                   |               |     [E]\n" +
   192 "     4--|   +   +   +   +   +-------+   +   |--4\n" +
   193 "        |                           |   |   |\n" +
   194 "     3--|   +   +   +   +   +   +   |   |   |--3\n" +
   195 "        |                         P | Q |   |\n" +
   196 "     2--|   +   +   +   +   +   +   +   +   |--2\n" +
   197 "        |                       |           |\n" +
   198 "     1--|   +   +   +   +   +   |   +-------|--1\n" +
   199 "        |                       |           |\n" +
   200 "        +||||-------------------------------+\n" +
   201 "            |   |   |   |   |   |   |   |\n" +
   202 "            A   B   C   D   E   F   G   H\n" +
   203 "\n" +
   204 "                         [S]                 \n";
   205 
   206         b = picture2board(b).toString();
   207         Board begin = Board.valueOf(b);
   208 
   209         try {
   210             Board bad = fence(begin, 0, 'G', 2, Orientation.HORIZONTAL);
   211             fail("Not allowed move:\n" + bad.toString());
   212         } catch (IllegalPositionException ex) {
   213             // OK
   214         }
   215     }
   216     public void testFourTimesInAgainstEachOtherResultsInInvalidPosition () throws Exception {
   217         Board b = board;
   218         
   219         for (int i = 0; i < 3; i++) {
   220             b = move(b, 0, Player.Direction.NORTH);
   221             b = move(b, 1, Player.Direction.SOUTH);
   222         }
   223         
   224         b = move(b, 0, Player.Direction.NORTH);
   225         try {
   226             b = move(b, 1, Player.Direction.SOUTH);
   227             fail ("Now the positions of two players are supposed to be the same, this results in exception");
   228         } catch (IllegalPositionException ex) {
   229             // ok
   230         }
   231         
   232     }
   233 
   234     public void testCrossFences () throws Exception {
   235         Board b1 = board.fence (board.getPlayers ().get(0), 'A', 1, Fence.Orientation.HORIZONTAL);
   236         
   237         try {
   238             b1.fence (b1.getPlayers ().get(1), 'A', 1, Fence.Orientation.VERTICAL);
   239             fail ("This must fail, as the fences overlap");
   240         } catch (IllegalPositionException ex) {
   241             // ok
   242         }
   243     }
   244     
   245     public void testPawnsCanJumpOverEachOther () throws Exception {
   246         Board b = board;
   247         
   248         for (int i = 0; i < 3; i++) {
   249             b = move(b, 0, Player.Direction.NORTH);
   250             b = move(b, 1, Player.Direction.SOUTH);
   251         }
   252         
   253         b = move(b, 0, Player.Direction.NORTH);
   254         
   255         // jump over
   256         b = move(b, 1, Player.Direction.SOUTH, Player.Direction.SOUTH);
   257     }
   258 
   259     public void testCannotJumpOverFence () throws Exception {
   260         Board b = fence (board, 0, 'D', 8, Fence.Orientation.HORIZONTAL);
   261         assertEquals("One fence is present", 1, b.getFences().size());
   262         final Fence f = b.getFences().iterator().next();
   263         assertEquals("Row is 8", 8, f.getRow());
   264         assertEquals("Column is D", 'D', f.getColumn());
   265         try {
   266             move(b, 1, Player.Direction.SOUTH);
   267             fail ("This shall not be allowed, as there is the fence");
   268         } catch (IllegalPositionException ex) {
   269             // ok
   270         }
   271     }
   272     
   273 
   274     public void testSideJumpsNotAllowedWhenThereIsNoFence () throws Exception {
   275         Board b = board;
   276         
   277         for (int i = 0; i < 3; i++) {
   278             b = move(b, 0, Player.Direction.NORTH);
   279             b = move(b, 1, Player.Direction.SOUTH);
   280         }
   281         
   282         b = move(b, 0, Player.Direction.NORTH);
   283         
   284         try {
   285             b = move(b, 1, Player.Direction.SOUTH, Player.Direction.WEST);
   286             fail ("Cannot just jump aside");
   287         } catch (IllegalPositionException ex) {
   288             // ok
   289         }
   290     }
   291     
   292     public void testSideJumpsAllowedWhenThereAFence () throws Exception {
   293         Board b = board;
   294         
   295         for (int i = 0; i < 3; i++) {
   296             b = move(b, 0, Player.Direction.NORTH);
   297             b = move(b, 1, Player.Direction.SOUTH);
   298         }
   299         
   300         b = move(b, 0, Player.Direction.NORTH);
   301         
   302         assertEquals (8, b.getPlayers ().get (0).getXInternal());
   303         assertEquals (8, b.getPlayers ().get (0).getYInternal());
   304         
   305         b = fence(b, 0, 'D', 4, Fence.Orientation.HORIZONTAL);
   306         
   307         // we can over jump to west
   308         move(b, 1, Player.Direction.SOUTH, Player.Direction.WEST);
   309         // as well as east
   310         move(b, 1, Player.Direction.SOUTH, Player.Direction.EAST);
   311     }
   312 
   313     public void testPlaceAllFences() throws Exception {
   314         doPlaceAllFences(0);
   315     }
   316     public void testPlaceAllFences2() throws Exception {
   317         doPlaceAllFences(1);
   318     }
   319 
   320     private void doPlaceAllFences(int player) throws Exception {
   321         Board b = board;
   322 
   323         int cnt = 10;
   324         for (int i = 1; i <= 5; i++) {
   325             b = fence(b, player, 'A', i, Fence.Orientation.HORIZONTAL);
   326             b = fence(b, player, 'D', i, Fence.Orientation.HORIZONTAL);
   327             cnt -= 2;
   328             assertEquals("Two less" + i, cnt, b.getPlayers().get(player).getFences());
   329         }
   330 
   331         try {
   332             fence(b, player, 'F', 7, Fence.Orientation.VERTICAL);
   333             fail("We shall run out of fences");
   334         } catch (IllegalPositionException ex) {
   335             // OK
   336         }
   337     }
   338     
   339     public void testAlwaysHasToHaveAccessToEndLine () throws Exception {
   340         Board b = board;
   341         
   342         b = b.fence (b.getPlayers ().get (0), 'E', 1, Fence.Orientation.HORIZONTAL);
   343         b = b.fence (b.getPlayers ().get (0), 'F', 1, Fence.Orientation.VERTICAL);
   344 
   345         try {
   346             b = b.fence (b.getPlayers ().get (0), 'D', 1, Fence.Orientation.VERTICAL);
   347             fail ("This is not allowed as player 0 cannot now reach the final line");
   348         } catch (IllegalPositionException ex) {
   349             // ok
   350         }
   351         
   352     }
   353     
   354     public void testEqualsOfPlayers () throws Exception {
   355         Player p1 = new Player (1, 1, 10, Player.Direction.EAST);
   356         Player p2 = new Player (1, 1, 10, Player.Direction.EAST);
   357         Player p3 = new Player (2, 1, 10, Player.Direction.EAST);
   358         Player p4 = new Player (1, 1, 10, Player.Direction.WEST);
   359         Player p5 = new Player (1, 2, 10, Player.Direction.EAST);
   360         Player p6 = new Player (1, 1, 5, Player.Direction.EAST);
   361         
   362         assertEquals ("p1 == p2", p1, p2);
   363         if (p2.equals (p3)) fail ();
   364         if (p2.equals (p4)) fail ();
   365         if (p2.equals (p5)) fail ();
   366         if (p2.equals (p6)) fail ();
   367         if (p3.equals (p6)) fail ();
   368         if (p4.equals (p3)) fail ();
   369         if (p6.equals (p3)) fail ();
   370         if (p5.equals (p3)) fail ();
   371         if (p5.equals (p3)) fail ();
   372         if (p4.equals (p3)) fail ();
   373         if (p3.equals (p4)) fail ();
   374         if (p3.equals (p5)) fail ();
   375         if (p4.equals (p5)) fail ();
   376         if (p5.equals (p4)) fail ();
   377     }
   378     
   379     public void testEqualsOfFences () throws Exception {
   380         Fence f1 = new Fence (1, 1, Fence.Orientation.HORIZONTAL);
   381         Fence f2 = new Fence (1, 1, Fence.Orientation.HORIZONTAL);
   382         Fence f3 = new Fence (3, 1, Fence.Orientation.HORIZONTAL);
   383         Fence f4 = new Fence (1, 3, Fence.Orientation.HORIZONTAL);
   384         Fence f5 = new Fence (1, 1, Fence.Orientation.VERTICAL);
   385         
   386         assertEquals ("f1 == f2", f1, f2);
   387         if (f1.equals (f3)) fail ();
   388         if (f3.equals (f1)) fail ();
   389         if (f5.equals (f1)) fail ();
   390         if (f1.equals (f5)) fail ();
   391         if (f4.equals (f1)) fail ();
   392         if (f1.equals (f4)) fail ();
   393     }
   394     
   395     public void testEqualsOfBoards1 () throws Exception {
   396         Board b1 = board.move (board.getPlayers ().get (0), Player.Direction.NORTH);
   397         Board b2 = board.move (board.getPlayers ().get (0), Player.Direction.NORTH);
   398         Board b3 = board.move (board.getPlayers ().get (0), Player.Direction.EAST);
   399         
   400         if (b1.equals (b3)) fail ();
   401         if (b3.equals (b1)) fail ();
   402         
   403         assertEquals ("b1 == b2", b1, b2);
   404     }
   405     public void testEqualsOfBoards2 () throws Exception {
   406         Board b1 = board.fence (board.getPlayers ().get (0), 'E', 3, Fence.Orientation.HORIZONTAL);
   407         Board b2 = board.fence (board.getPlayers ().get (0), 'E', 3, Fence.Orientation.HORIZONTAL);
   408         Board b3 = board.fence (board.getPlayers ().get (0), 'D', 3, Fence.Orientation.HORIZONTAL);
   409         Board b4 = board.fence (board.getPlayers ().get (0), 'E', 4, Fence.Orientation.HORIZONTAL);
   410         Board b5 = board.fence (board.getPlayers ().get (0), 'E', 3, Fence.Orientation.VERTICAL);
   411         
   412         if (b1.equals (b3)) fail ();
   413         if (b3.equals (b1)) fail ();
   414         if (b1.equals (b4)) fail ();
   415         if (b1.equals (b5)) fail ();
   416         if (b5.equals (b1)) fail ();
   417         if (b4.equals (b1)) fail ();
   418         
   419         assertEquals ("b1 == b2", b1, b2);
   420     }
   421     public void testEqualsOfBoardsWhenJumpOver () throws Exception {
   422         Board b = board;
   423         
   424         for (int i = 0; i < 3; i++) {
   425             b = move(b, 0, Player.Direction.NORTH);
   426             b = move(b, 1, Player.Direction.SOUTH);
   427         }
   428         
   429         Board b1 = move(b, 0, Player.Direction.NORTH);
   430         
   431         Board b2 = move(b, 1, Player.Direction.SOUTH);
   432         b2 = b2.move (b2.getPlayers ().get (0), Player.Direction.NORTH, Player.Direction.NORTH);
   433         
   434         if (b1.equals (b2)) fail ("Not the same, pawns are reverted");
   435         if (b2.equals (b1)) fail ("Not the same, pawns are reverted");
   436     }
   437 
   438     public void testMoveAltersCurrentPlayer() throws Exception {
   439         assertEquals("First player ready", board.getCurrentPlayer(), board.getPlayers().get(0));
   440         Board b = apply(board, Move.EAST);
   441 
   442         for (int i = 0; i < 7; i++) {
   443             assertEquals("Snd player ready", b.getCurrentPlayer(), b.getPlayers().get(1));
   444             b = apply(b, Move.SOUTH);
   445             assertEquals("First player ready", b.getCurrentPlayer(), b.getPlayers().get(0));
   446             b = apply(b, Move.NORTH);
   447         }
   448 
   449         Board fin = b.apply(Move.NORTH).apply(Move.NORTH);
   450         assertNotNull("There is a winner", fin.getWinner());
   451         assertEquals("And the winner is", fin.getPlayers().get(0), fin.getWinner());
   452 
   453         assertFalse("No next move can be applied", fin.isApplicable(Move.fence('D', 3, Fence.Orientation.HORIZONTAL)));
   454 
   455         try {
   456             fin.apply(Move.EAST);
   457             fail("No moves allow when we are in final position");
   458         } catch (IllegalPositionException ex) {
   459             // OK
   460         }
   461 
   462     }
   463 
   464     public void testDetectInvalidFence() {
   465         try {
   466             Move m = Move.fence('D', 9, Orientation.HORIZONTAL);
   467             fail("Move shall not be allowed: " + m);
   468         } catch (IllegalPositionException ex) {
   469             // OK
   470         }
   471     }
   472 
   473     public void testEqualityOfMoves() throws Exception {
   474 
   475         for (Direction m1 : Direction.values()) {
   476             for (Direction m2 : Direction.values()) {
   477                 Move both1 = Move.jump(m1, m2);
   478                 Move both2 = Move.jump(m1, m2);
   479                 Move opposite = Move.jump(m2, m1);
   480 
   481                 assertTrue("Both boths are equal", both1.equals(both2));
   482                 assertFalse("Not north", Move.NORTH.equals(both1));
   483                 assertFalse("Not east", Move.EAST.equals(both1));
   484                 assertFalse("Not west", Move.WEST.equals(both1));
   485                 assertFalse("Not south", Move.SOUTH.equals(both1));
   486                 if (m1 == m2) {
   487                     continue;
   488                 }
   489                 assertFalse("Not equal to opposite", both1.equals(opposite));
   490             }
   491         }
   492 
   493         Move f1 = Move.fence('D', 6, Orientation.HORIZONTAL);
   494         Move f2 = Move.fence('D', 6, Orientation.HORIZONTAL);
   495         Move f3 = Move.fence('D', 6, Orientation.VERTICAL);
   496         Move f4 = Move.fence('E', 6, Orientation.VERTICAL);
   497         Move f5 = Move.fence('E', 5, Orientation.VERTICAL);
   498 
   499         assertEquals(f1, f2);
   500         assertFalse(f1.equals(f3));
   501         assertFalse(f4.equals(f5));
   502         assertFalse(f3.equals(f5));
   503     }
   504 
   505     public void testBrokenWriteOfAGameDanVsJarda() throws Exception {
   506         Board b = board.apply(Move.NORTH).apply(Move.SOUTH).
   507             apply(Move.NORTH).apply(Move.SOUTH).
   508             apply(Move.NORTH).apply(Move.SOUTH).
   509             apply(Move.WEST).apply(Move.fence('C', 6, Orientation.HORIZONTAL)).
   510             apply(Move.EAST).apply(Move.SOUTH).
   511             apply(Move.fence('E', 2, Orientation.HORIZONTAL)).apply(Move.fence('E', 5, Orientation.HORIZONTAL)).
   512             apply(Move.fence('F', 3, Orientation.VERTICAL)).apply(Move.fence('D', 6, Orientation.VERTICAL)).
   513             apply(Move.jump(Direction.NORTH, Direction.EAST)).apply(Move.fence('F', 5, Orientation.VERTICAL)).
   514             apply(Move.fence('E', 1, Orientation.VERTICAL)).apply(Move.fence('E', 4, Orientation.VERTICAL)).
   515             apply(Move.fence('D', 8, Orientation.HORIZONTAL)).apply(Move.fence('D', 7, Orientation.HORIZONTAL)).
   516             apply(Move.fence('D', 4, Orientation.HORIZONTAL)).apply(Move.fence('E', 8, Orientation.VERTICAL)).
   517             apply(Move.fence('C', 3, Orientation.HORIZONTAL)).apply(Move.WEST).
   518             apply(Move.fence('D', 2, Orientation.VERTICAL)).apply(Move.fence('A', 4, Orientation.HORIZONTAL)).
   519             apply(Move.fence('B', 2, Orientation.HORIZONTAL)).apply(Move.WEST).
   520             apply(Move.SOUTH).apply(Move.SOUTH).
   521             apply(Move.SOUTH).apply(Move.WEST);
   522         Board m = move(b, 0, Direction.WEST);
   523         Board f = fence(m, 1, 'A', 1, Orientation.VERTICAL);
   524         Board l = fence(f, 0, 'A', 3, Orientation.VERTICAL);
   525     }
   526 
   527     static Board picture2board(String text) throws IOException, IllegalPositionException {
   528         StringReader sr = new StringReader(text);
   529         return Board.read(sr);
   530     }
   531 }