chess/src/test/java/org/apidesign/html/demo/chess/BoardModelTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 22 Nov 2021 15:58:31 +0100
changeset 244 cea2063fd0f9
parent 53 bc0094a5f88c
permissions -rw-r--r--
Rochade shall move the rock as well
     1 /**
     2  * The MIT License (MIT)
     3  *
     4  * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5  *
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
     7  * of this software and associated documentation files (the "Software"), to deal
     8  * in the Software without restriction, including without limitation the rights
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    10  * copies of the Software, and to permit persons to whom the Software is
    11  * furnished to do so, subject to the following conditions:
    12  *
    13  * The above copyright notice and this permission notice shall be included in
    14  * all copies or substantial portions of the Software.
    15  *
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    22  * THE SOFTWARE.
    23  */
    24 package org.apidesign.html.demo.chess;
    25 
    26 import org.apidesign.html.demo.chess.Color;
    27 import org.apidesign.html.demo.chess.Rules;
    28 import org.apidesign.html.demo.chess.BoardModel;
    29 import org.apidesign.html.demo.chess.BoardModel.PieceType;
    30 import java.util.Arrays;
    31 import java.util.Collections;
    32 import java.util.List;
    33 import static org.testng.Assert.*;
    34 import org.testng.annotations.Test;
    35 
    36 /**
    37  *
    38  * @author Jaroslav Tulach <jtulach@netbeans.org>
    39  */
    40 public class BoardModelTest {
    41     
    42     public BoardModelTest() {
    43     }
    44     
    45     @Test public void whiteRockLeftBottom() {
    46         Board b = Rules.createBoard();
    47         Row bottom = b.getRows().get(7);
    48         Square left = bottom.getColumns().get(0);
    49         assertEquals(left.getPiece(), PieceType.ROCK, "Rock is on bottom left square");
    50         assertEquals(left.getPieceColor(), Color.W, "It is white");
    51         assertEquals(left.getColor(), Color.B, "Square is black");
    52     }
    53 
    54     @Test public void e2e4e7e6() {
    55         Board b = Rules.createBoard();
    56         b.setGameId("myId");
    57         setPlayer(b, Color.W);
    58         assertEquals(b.getTurn(), Color.W);
    59         
    60         Square e2 = BoardModel.findSquare(b, 'E', 2);
    61         assertNotNull(e2);
    62         BoardModel.selected(b, e2);
    63         assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
    64         
    65         Square e4 = BoardModel.findSquare(b, 'E', 4);
    66         assertNotNull(e4);
    67         
    68         BoardModel.selected(b, e4);
    69         
    70         assertNull(e2.getPiece(), "No pawn at e2");
    71         assertEquals(e4.getPiece(), BoardModel.PieceType.PAWN, "Pawn moved successfully");
    72         assertNull(BoardModel.findSelectedSquare(b), "No square selected");
    73         
    74         BoardModel.selected(b, e4);
    75         assertNull(BoardModel.findSelectedSquare(b), "No square selected, it is blacks turn");
    76 
    77         List<Move> mvs1 = b.getMoves();
    78         assertEquals(1, mvs1.size(), "First move was made: " + mvs1);
    79         Move firstMove = mvs1.get(0);
    80         assertEquals(firstMove.getPiece(), PieceType.PAWN, "Moving with pawn");
    81         assertEquals(firstMove.getRound(), 1, "First round of moves");
    82         assertEquals(firstMove.getTurn(), Color.W, "Moved by white");
    83         assertTrue(firstMove.isWhiteMove(), "Really moved by white");
    84         
    85         assertTrue(b.isBlackTurn(), "black's turn");
    86         
    87         
    88         Square e7 = BoardModel.findSquare(b, 'E', 7);
    89         
    90         Move blackMv = BoardModel.MoveImpl.valueOf("E7E6");
    91         BoardModel.moveUpdate(b, blackMv, 
    92             Collections.singletonList("PE4"), 
    93             Collections.singletonList("PE6"), 
    94             Color.W, null
    95         );
    96         
    97         assertNull(e7.getPiece(), "Piece has been moved");
    98         
    99         List<Move> mvs = b.getMoves();
   100         assertEquals(2, mvs.size(), "There are two moves now: " + mvs);
   101         Move secondMove = mvs.get(1);
   102         assertEquals(secondMove.getPiece(), PieceType.PAWN, "Moving with pawn");
   103         assertEquals(secondMove.getRound(), 1, "Still 1st round of moves");
   104         assertEquals(secondMove.getTurn(), Color.B, "Moved by black");
   105         assertFalse(secondMove.isWhiteMove(), "Really moved by black");
   106     }
   107 
   108     @Test public void unselect() {
   109         Board b = Rules.createBoard();
   110         b.setGameId("myId");
   111         setPlayer(b, Color.W);
   112         assertEquals(b.getTurn(), Color.W);
   113         
   114         Square e2 = BoardModel.findSquare(b, 'E', 2);
   115         assertNotNull(e2);
   116         BoardModel.selected(b, e2);
   117         assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
   118         
   119         BoardModel.selected(b, e2);
   120         assertNull(BoardModel.findSelectedSquare(b), "E2 is unselected");
   121         
   122         for (Row row : b.getRows()) {
   123             for (Square s : row.getColumns()) {
   124                 assertFalse(s.isAccessible(), "No square is accessible anymore: " + s);
   125             }
   126         }
   127     }
   128     
   129     @Test public void discaredMove() {
   130         Board b = Rules.createBoard();
   131         b.setGameId("myId");
   132         setPlayer(b, Color.W);
   133         assertEquals(b.getTurn(), Color.W);
   134         
   135         Square e2 = BoardModel.findSquare(b, 'E', 2);
   136         assertNotNull(e2);
   137         BoardModel.selected(b, e2);
   138         assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
   139         
   140         Square e4 = BoardModel.findSquare(b, 'E', 4);
   141         assertNotNull(e4);
   142         
   143         BoardModel.selected(b, e4);
   144         
   145         assertNull(e2.getPiece(), "No pawn at e2");
   146         
   147         assertEquals(b.getMoves().size(), 1, "One move recorded");
   148         assertEquals(b.getMoves().get(0), b.getPendingMove(), "Pending move is waiting");
   149     }
   150     
   151     @Test public void cantSelectEmptySquare() {
   152         Board b = Rules.createBoard();
   153         Square e3 = BoardModel.findSquare(b, 'E', 3);
   154         assertNotNull(e3);
   155         BoardModel.selected(b, e3);
   156         assertNull(BoardModel.findSelectedSquare(b), "No square is selected");
   157     }
   158 
   159     @Test public void cantTakeOwnPiece() {
   160         Board b = Rules.createBoard();
   161         setPlayer(b, Color.W);
   162         Square e1 = BoardModel.findSquare(b, 'E', 1);
   163         assertNotNull(e1);
   164         BoardModel.selected(b, e1);
   165         assertEquals(BoardModel.findSelectedSquare(b), e1, "E1 is selected");
   166         
   167         Square e2 = BoardModel.findSquare(b, 'E', 2);
   168         assertNotNull(e2);
   169         
   170         BoardModel.selected(b, e2);
   171         
   172         assertNotNull(e1.getPiece(), "King remains at e1");
   173         assertEquals(e2.getPiece(), BoardModel.PieceType.PAWN, "Pawn remains");
   174         assertEquals(BoardModel.findSelectedSquare(b), e2, "e2 now selected");
   175         
   176     }
   177     
   178     @Test public void knightMustMoveToF3() {
   179         Board b = Rules.createBoard();
   180         setPlayer(b, Color.W);
   181         Square g1 = BoardModel.findSquare(b, 'G', 1);
   182         BoardModel.selected(b, g1);
   183         
   184         Square f3 = BoardModel.findSquare(b, 'F', 3);
   185         assertTrue(f3.isAccessible(), "This is a field where knight can move");
   186 
   187         Square g3 = BoardModel.findSquare(b, 'G', 3);
   188         assertFalse(g3.isAccessible(), "Not a place for knight");
   189 
   190         Square e2 = BoardModel.findSquare(b, 'E', 2);
   191         assertFalse(e2.isAccessible(), "Not a place either, occupied");
   192 
   193         BoardModel.selected(b, g3);
   194         
   195         assertNull(g3.getPiece(), "No figure was moved");
   196         assertTrue(g1.isSelected(), "Original square still selected");
   197         
   198         BoardModel.selected(b, f3);
   199         
   200         assertEquals(f3.getPiece(), PieceType.KNIGHT, "Moved");
   201         assertFalse(g3.isSelected(), "No longer selected");
   202     }
   203     
   204     @Test public void pawnCanTakeToSide() {
   205         Board b = Rules.createBoard();
   206         Square e2 = BoardModel.findSquare(b, 'E', 2);
   207         Square e4 = BoardModel.findSquare(b, 'E', 4);
   208         Square d7 = BoardModel.findSquare(b, 'D', 7);
   209         Square d5 = BoardModel.findSquare(b, 'D', 5);
   210         
   211         BoardModel.selected(b, e2);
   212         BoardModel.selected(b, e4);
   213         
   214         setPlayer(b, Color.B);
   215         
   216         BoardModel.selected(b, d7);
   217         BoardModel.selected(b, d5);
   218         
   219         setPlayer(b, Color.W);
   220         
   221         BoardModel.selected(b, e4);
   222         assertTrue(d5.isAccessible(), "Can take on d5");
   223         BoardModel.selected(b, d5);
   224         assertNull(e4.getPiece(), "No pawn on e4");
   225         assertEquals(d5.getPieceColor(), Color.W, "White Pawn on d5");
   226     }
   227     
   228     @Test public void pawnCanJumpOnAnother() {
   229         Board b = Rules.createBoard();
   230         Square e2 = BoardModel.findSquare(b, 'E', 2);
   231         Square e4 = BoardModel.findSquare(b, 'E', 4);
   232         Square d7 = BoardModel.findSquare(b, 'D', 7);
   233         Square d5 = BoardModel.findSquare(b, 'D', 5);
   234         Square e7 = BoardModel.findSquare(b, 'E', 7);
   235         Square e6 = BoardModel.findSquare(b, 'E', 6);
   236         Square e5 = BoardModel.findSquare(b, 'E', 5);
   237         
   238         BoardModel.selected(b, e2);
   239         BoardModel.selected(b, e4);
   240         
   241         setPlayer(b, Color.B);
   242         
   243         BoardModel.selected(b, d7);
   244         BoardModel.selected(b, d5);
   245         
   246         setPlayer(b, Color.W);
   247         
   248         BoardModel.selected(b, e4);
   249         BoardModel.selected(b, e5);
   250         
   251         setPlayer(b, Color.B);
   252         
   253         BoardModel.selected(b, e7);
   254         assertTrue(e6.isAccessible(), "Can move by one piece");
   255         assertFalse(e5.isAccessible(), "Can't move where other pawn is");
   256     }
   257     
   258     @Test public void showFirstMove() {
   259         Board b = Rules.createBoard();
   260         setPlayer(b, Color.W);
   261         Square e2 = BoardModel.findSquare(b, 'E', 2);
   262         Square e4 = BoardModel.findSquare(b, 'E', 4);
   263         Square d7 = BoardModel.findSquare(b, 'D', 7);
   264         Square d5 = BoardModel.findSquare(b, 'D', 5);
   265         
   266         BoardModel.selected(b, e2);
   267         BoardModel.selected(b, e4);
   268         
   269         Move blackMv = BoardModel.MoveImpl.valueOf("D7D5");
   270         BoardModel.moveUpdate(b, blackMv, 
   271             Collections.singletonList("PE4"), 
   272             Collections.singletonList("PD5"), 
   273             Color.W, null
   274         );
   275         
   276 
   277         assertEquals(b.getMoves().size(), 2, "Two moves");
   278         BoardModel.showPosition(b, b.getMoves().get(0));
   279         
   280         assertEquals(b.getRows().size(), 8, "Still eight rows");
   281         assertEquals(b.getRows().get(0).getColumns().size(), 8, "Eight columns");
   282         
   283         assertNull(e2.getPiece(), "e2 is empty");
   284         assertEquals(e4.getPiece(), PieceType.PAWN, "e4 has pawn");
   285         assertEquals(d7.getPiece(), PieceType.PAWN, "d7 has pawn");
   286         assertNull(d5.getPiece(), "Second move is not made");
   287         assertNull(b.getTurn(), "Nobody to make a move");
   288     }
   289     
   290     @Test public void initialPositionReadFromAServer() {
   291         List<String> blacks = Arrays.asList(
   292             "Pa7",
   293             "Pb7",
   294             "Pc7",
   295             "Pd7",
   296             "Pe7",
   297             "Pf7",
   298             "Pg7",
   299             "Ph7",
   300             "Ra8",
   301             "Nb8",
   302             "Bc8",
   303             "Qd8",
   304             "Ke8",
   305             "Bf8",
   306             "Ng8",
   307             "Rh8"
   308         );
   309         List<String> whites = Arrays.asList(
   310             "Ra1",
   311             "Nb1",
   312             "Bc1",
   313             "Qd1",
   314             "Ke1",
   315             "Bf1",
   316             "Ng1",
   317             "Rh1",
   318             "Pa2",
   319             "Pb2",
   320             "Pc2",
   321             "Pd2",
   322             "Pe2",
   323             "Pf2",
   324             "Pg2",
   325             "Ph2"
   326         );
   327         
   328         Board b = Rules.createBoard();
   329         Rules.initBoard(b, whites, blacks, Color.W);
   330         
   331         Board b2 = Rules.createBoard();
   332         Rules.initBoard(b2);
   333         
   334         for (int i = 0; i < 7; i++) {
   335             for (int j = 0; j < 7; j++) {
   336                 Square s = b.getRows().get(i).getColumns().get(j);
   337                 Square s2 = b2.getRows().get(i).getColumns().get(j);
   338                 
   339                 assertEquals(s.getPiece(), s2.getPiece(), "Same piece at " + i + "/" + j);
   340                 assertEquals(s.getPieceColor(), s2.getPieceColor(), "Same piece color at " + i + "/" + j);
   341             }
   342         }
   343     }
   344     
   345     @Test public void allowSmallRochade() {
   346         Board b = Rules.createBoard();
   347         setPlayer(b, Color.W);
   348         Square f1 = BoardModel.findSquare(b, 'F', 1);
   349         f1.setPiece(null);
   350         f1.setPieceColor(null);
   351         Square g1 = BoardModel.findSquare(b, 'G', 1);
   352         g1.setPiece(null);
   353         g1.setPieceColor(null);
   354         Square e1 = BoardModel.findSquare(b, 'E', 1);
   355         
   356         BoardModel.selected(b, e1);
   357         assertTrue(g1.isAccessible(), "Can do 0-0");
   358 
   359         BoardModel.selected(b, g1);
   360 
   361         assertNull(e1.getPiece());
   362         assertEquals(g1.getPiece(), PieceType.KING);
   363         assertEquals(f1.getPiece(), PieceType.ROCK);
   364     }
   365     
   366     @Test public void allowSmallRochadeForBlack() {
   367         Board b = Rules.createBoard();
   368         setPlayer(b, Color.B);
   369         b.setTurn(Color.B);
   370         Square f8 = BoardModel.findSquare(b, 'F', 8);
   371         f8.setPiece(null);
   372         f8.setPieceColor(null);
   373         Square g8 = BoardModel.findSquare(b, 'G', 8);
   374         g8.setPiece(null);
   375         g8.setPieceColor(null);
   376         Square e8 = BoardModel.findSquare(b, 'E', 8);
   377         
   378         BoardModel.selected(b, e8);
   379         assertTrue(g8.isAccessible(), "Can do 0-0");
   380     }
   381     
   382     @Test public void disallowSmallRochadeWhenNoRock() {
   383         Board b = Rules.createBoard();
   384         setPlayer(b, Color.W);
   385         Square f1 = BoardModel.findSquare(b, 'F', 1);
   386         f1.setPiece(null);
   387         f1.setPieceColor(null);
   388         Square g1 = BoardModel.findSquare(b, 'G', 1);
   389         g1.setPiece(null);
   390         g1.setPieceColor(null);
   391         Square h1 = BoardModel.findSquare(b, 'H', 1);
   392         h1.setPiece(null);
   393         h1.setPieceColor(null);
   394         Square e1 = BoardModel.findSquare(b, 'E', 1);
   395         
   396         BoardModel.selected(b, e1);
   397         assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is no rock");
   398     }
   399     
   400     @Test public void disallowSmallRochadeWhenBishop() {
   401         Board b = Rules.createBoard();
   402         setPlayer(b, Color.W);
   403         Square g1 = BoardModel.findSquare(b, 'G', 1);
   404         g1.setPiece(null);
   405         Square e1 = BoardModel.findSquare(b, 'E', 1);
   406         
   407         BoardModel.selected(b, e1);
   408         assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is bishop");
   409     }
   410 
   411     @Test public void disallowSmallRochadeWhenKnight() {
   412         Board b = Rules.createBoard();
   413         setPlayer(b, Color.W);
   414         Square f1 = BoardModel.findSquare(b, 'F', 1);
   415         f1.setPiece(null);
   416         Square e1 = BoardModel.findSquare(b, 'E', 1);
   417         
   418         BoardModel.selected(b, e1);
   419         assertFalse(f1.isAccessible(), "Cannot do 0-0 when there is knight");
   420     }
   421     
   422     @Test public void allowBigRochadeForBlack() {
   423         Board b = Rules.createBoard();
   424         setPlayer(b, Color.B);
   425         b.setTurn(Color.B);
   426         Square b8 = BoardModel.findSquare(b, 'B', 8);
   427         b8.setPiece(null);
   428         b8.setPieceColor(null);
   429         Square c8 = BoardModel.findSquare(b, 'C', 8);
   430         c8.setPiece(null);
   431         c8.setPieceColor(null);
   432         Square d8 = BoardModel.findSquare(b, 'D', 8);
   433         d8.setPiece(null);
   434         d8.setPieceColor(null);
   435         Square e8 = BoardModel.findSquare(b, 'E', 8);
   436         
   437         BoardModel.selected(b, e8);
   438         assertTrue(c8.isAccessible(), "Can do 0-0-0");
   439     }
   440     
   441     @Test public void enPassant() {
   442         Board b = Rules.createBoard();
   443         setPlayer(b, Color.B);
   444         b.setTurn(Color.B);
   445 
   446         Square e7 = BoardModel.findSquare(b, 'E', 7);
   447         Square e4 = BoardModel.findSquare(b, 'E', 4);
   448         movePiece(e7, e4);
   449         
   450         Move move = new Move();
   451         move.setFrom(position('D', 2));
   452         move.setTo(position('D', 4));
   453         move.setPiece(PieceType.PAWN);
   454         b.getMoves().add(move);
   455         
   456         Square d2 = BoardModel.findSquare(b, 'D', 2);
   457         Square d4 = BoardModel.findSquare(b, 'D', 4);
   458         movePiece(d2, d4);
   459         
   460         BoardModel.selected(b, e4);
   461         
   462         Square e3 = BoardModel.findSquare(b, 'E', 3);
   463         assertTrue(e3.isAccessible(), "Obviously can move to e3");
   464         
   465         Square d3 = BoardModel.findSquare(b, 'D', 3);
   466         assertTrue(d3.isAccessible(), "Can also take on d3");
   467     }
   468 
   469     private void movePiece(Square from, Square to) {
   470         to.setPiece(from.getPiece());
   471         to.setPieceColor(from.getPieceColor());
   472         from.setPiece(null);
   473         from.setPieceColor(null);
   474     }
   475 
   476     private Position position(char c, int i) {
   477         Position p = new Position();
   478         p.setX(c);
   479         p.setY(i);
   480         return p;
   481     }
   482     
   483     private static void setPlayer(Board b, Color c) {
   484         b.setWhitePlayer("x");
   485         b.setBlackPlayer("y");
   486         if (c == Color.B) {
   487             b.setPlayer("y");
   488         } else {
   489             b.setPlayer("x");
   490         }
   491     }
   492 }