2 * The MIT License (MIT)
4 * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 package org.apidesign.html.demo.chess;
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;
38 * @author Jaroslav Tulach <jtulach@netbeans.org>
40 public class BoardModelTest {
42 public BoardModelTest() {
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");
54 @Test public void e2e4e7e6() {
55 Board b = Rules.createBoard();
57 setPlayer(b, Color.W);
58 assertEquals(b.getTurn(), Color.W);
60 Square e2 = BoardModel.findSquare(b, 'E', 2);
62 BoardModel.selected(b, e2);
63 assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
65 Square e4 = BoardModel.findSquare(b, 'E', 4);
68 BoardModel.selected(b, e4);
70 assertTrue(e4.isPending(), "e4 marked as pending move");
71 assertNull(e2.getPiece(), "No pawn at e2");
73 // ignore all other figures than the two pawns
74 BoardModel.moveResponse(b, null, Collections.singletonList("Pe4"),
75 Collections.singletonList("Pe7"), Color.B, null
78 assertFalse(e4.isPending(), "e4 now the move is real");
79 assertNull(e2.getPiece(), "No pawn at e2");
80 assertEquals(e4.getPiece(), BoardModel.PieceType.PAWN, "Pawn moved successfully");
81 assertNull(BoardModel.findSelectedSquare(b), "No square selected");
83 BoardModel.selected(b, e4);
84 assertNull(BoardModel.findSelectedSquare(b), "No square selected, it is blacks turn");
86 List<Move> mvs1 = b.getMoves();
87 assertEquals(1, mvs1.size(), "First move was made: " + mvs1);
88 Move firstMove = mvs1.get(0);
89 assertEquals(firstMove.getPiece(), PieceType.PAWN, "Moving with pawn");
90 assertEquals(firstMove.getRound(), 1, "First round of moves");
91 assertEquals(firstMove.getTurn(), Color.W, "Moved by white");
92 assertTrue(firstMove.isWhiteMove(), "Really moved by white");
94 assertTrue(b.isBlackTurn(), "black's turn");
97 Square e7 = BoardModel.findSquare(b, 'E', 7);
98 BoardModel.selected(b, e7);
99 assertNull(BoardModel.findSelectedSquare(b), "Can't select anything when I am white player");
101 Move blackMv = BoardModel.MoveImpl.valueOf("E7E6");
102 BoardModel.moveUpdate(b, blackMv,
103 Collections.singletonList("PE4"),
104 Collections.singletonList("PE6"),
108 assertNull(e7.getPiece(), "Piece has been moved");
110 List<Move> mvs = b.getMoves();
111 assertEquals(2, mvs.size(), "There are two moves now: " + mvs);
112 Move secondMove = mvs.get(1);
113 assertEquals(secondMove.getPiece(), PieceType.PAWN, "Moving with pawn");
114 assertEquals(secondMove.getRound(), 1, "Still 1st round of moves");
115 assertEquals(secondMove.getTurn(), Color.B, "Moved by black");
116 assertFalse(secondMove.isWhiteMove(), "Really moved by black");
119 @Test public void unselect() {
120 Board b = Rules.createBoard();
122 setPlayer(b, Color.W);
123 assertEquals(b.getTurn(), Color.W);
125 Square e2 = BoardModel.findSquare(b, 'E', 2);
127 BoardModel.selected(b, e2);
128 assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
130 BoardModel.selected(b, e2);
131 assertNull(BoardModel.findSelectedSquare(b), "E2 is unselected");
133 for (Row row : b.getRows()) {
134 for (Square s : row.getColumns()) {
135 assertFalse(s.isAccessible(), "No square is accessible anymore: " + s);
140 @Test public void discaredMove() {
141 Board b = Rules.createBoard();
143 setPlayer(b, Color.W);
144 assertEquals(b.getTurn(), Color.W);
146 Square e2 = BoardModel.findSquare(b, 'E', 2);
148 BoardModel.selected(b, e2);
149 assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
151 Square e4 = BoardModel.findSquare(b, 'E', 4);
154 BoardModel.selected(b, e4);
156 assertTrue(e4.isPending(), "e4 marked as pending move");
157 assertNull(e2.getPiece(), "No pawn at e2");
159 assertEquals(b.getMoves().size(), 1, "One move recorded");
160 assertEquals(b.getMoves().get(0), b.getPendingMove(), "Pending move is waiting");
162 // ignore all other figures than the two pawns
163 BoardModel.moveResponse(b, "No way, can't play like this", Collections.singletonList("PE2"),
164 Collections.singletonList("Pe7"), Color.W, null
167 assertEquals(b.getAlertMessage(), "No way, can't play like this");
168 assertNull(e4.getPiece(), "No piece on e4");
169 assertEquals(e2.getPiece(), PieceType.PAWN, "Pawn is back");
171 assertEquals(b.getMoves().size(), 0, "Move was discarded");
172 assertNull(b.getPendingMove(), "No pending moves");
175 @Test public void cantSelectEmptySquare() {
176 Board b = Rules.createBoard();
177 Square e3 = BoardModel.findSquare(b, 'E', 3);
179 BoardModel.selected(b, e3);
180 assertNull(BoardModel.findSelectedSquare(b), "No square is selected");
183 @Test public void cantTakeOwnPiece() {
184 Board b = Rules.createBoard();
185 setPlayer(b, Color.W);
186 Square e1 = BoardModel.findSquare(b, 'E', 1);
188 BoardModel.selected(b, e1);
189 assertEquals(BoardModel.findSelectedSquare(b), e1, "E1 is selected");
191 Square e2 = BoardModel.findSquare(b, 'E', 2);
194 BoardModel.selected(b, e2);
196 assertNotNull(e1.getPiece(), "King remains at e1");
197 assertEquals(e2.getPiece(), BoardModel.PieceType.PAWN, "Pawn remains");
198 assertEquals(BoardModel.findSelectedSquare(b), e2, "e2 now selected");
202 @Test public void knightMustMoveToF3() {
203 Board b = Rules.createBoard();
204 setPlayer(b, Color.W);
205 Square g1 = BoardModel.findSquare(b, 'G', 1);
206 BoardModel.selected(b, g1);
208 Square f3 = BoardModel.findSquare(b, 'F', 3);
209 assertTrue(f3.isAccessible(), "This is a field where knight can move");
211 Square g3 = BoardModel.findSquare(b, 'G', 3);
212 assertFalse(g3.isAccessible(), "Not a place for knight");
214 Square e2 = BoardModel.findSquare(b, 'E', 2);
215 assertFalse(e2.isAccessible(), "Not a place either, occupied");
217 BoardModel.selected(b, g3);
219 assertNull(g3.getPiece(), "No figure was moved");
220 assertTrue(g1.isSelected(), "Original square still selected");
222 BoardModel.selected(b, f3);
224 assertEquals(f3.getPiece(), PieceType.KNIGHT, "Moved");
225 assertFalse(g3.isSelected(), "No longer selected");
228 @Test public void pawnCanTakeToSide() {
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);
235 BoardModel.selected(b, e2);
236 BoardModel.selected(b, e4);
238 // ignore all other figures than the two pawns
239 BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
240 Collections.singletonList("PD7"), Color.B, null
243 setPlayer(b, Color.B);
245 BoardModel.selected(b, d7);
246 BoardModel.selected(b, d5);
248 // ignore all other figures than the two pawns
249 BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
250 Collections.singletonList("PD5"), Color.W, null
253 setPlayer(b, Color.W);
255 BoardModel.selected(b, e4);
256 assertTrue(d5.isAccessible(), "Can take on d5");
257 BoardModel.selected(b, d5);
258 assertNull(e4.getPiece(), "No pawn on e4");
259 assertEquals(d5.getPieceColor(), Color.W, "White Pawn on d5");
262 @Test public void pawnCanJumpOnAnother() {
263 Board b = Rules.createBoard();
264 Square e2 = BoardModel.findSquare(b, 'E', 2);
265 Square e4 = BoardModel.findSquare(b, 'E', 4);
266 Square d7 = BoardModel.findSquare(b, 'D', 7);
267 Square d5 = BoardModel.findSquare(b, 'D', 5);
268 Square e7 = BoardModel.findSquare(b, 'E', 7);
269 Square e6 = BoardModel.findSquare(b, 'E', 6);
270 Square e5 = BoardModel.findSquare(b, 'E', 5);
272 BoardModel.selected(b, e2);
273 BoardModel.selected(b, e4);
275 // ignore all other figures than the three pawns
276 BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
277 Arrays.asList("PD7", "PE7"), Color.B, null
280 setPlayer(b, Color.B);
282 BoardModel.selected(b, d7);
283 BoardModel.selected(b, d5);
285 // ignore all other figures than the three pawns
286 BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
287 Arrays.asList("PD5", "PE7"), Color.W, null
290 setPlayer(b, Color.W);
292 BoardModel.selected(b, e4);
293 BoardModel.selected(b, e5);
295 // ignore all other figures than the three pawns
296 BoardModel.moveResponse(b, null, Collections.singletonList("PE5"),
297 Arrays.asList("PD5", "PE7"), Color.B, null
300 setPlayer(b, Color.B);
302 BoardModel.selected(b, e7);
303 assertTrue(e6.isAccessible(), "Can move by one piece");
304 assertFalse(e5.isAccessible(), "Can't move where other pawn is");
307 @Test public void showFirstMove() {
308 Board b = Rules.createBoard();
309 setPlayer(b, Color.W);
310 Square e2 = BoardModel.findSquare(b, 'E', 2);
311 Square e4 = BoardModel.findSquare(b, 'E', 4);
312 Square d7 = BoardModel.findSquare(b, 'D', 7);
313 Square d5 = BoardModel.findSquare(b, 'D', 5);
315 BoardModel.selected(b, e2);
316 BoardModel.selected(b, e4);
318 // ignore all other figures than the two pawns
319 BoardModel.moveResponse(b, null, Collections.singletonList("Pe4"),
320 Collections.singletonList("PD7"), Color.B, null
323 Move blackMv = BoardModel.MoveImpl.valueOf("D7D5");
324 BoardModel.moveUpdate(b, blackMv,
325 Collections.singletonList("PE4"),
326 Collections.singletonList("PD5"),
331 assertEquals(b.getMoves().size(), 2, "Two moves");
332 BoardModel.showPosition(b, b.getMoves().get(0));
334 assertEquals(b.getRows().size(), 8, "Still eight rows");
335 assertEquals(b.getRows().get(0).getColumns().size(), 8, "Eight columns");
337 assertNull(e2.getPiece(), "e2 is empty");
338 assertEquals(e4.getPiece(), PieceType.PAWN, "e4 has pawn");
339 assertEquals(d7.getPiece(), PieceType.PAWN, "d7 has pawn");
340 assertNull(d5.getPiece(), "Second move is not made");
341 assertNull(b.getTurn(), "Nobody to make a move");
344 @Test public void initialPositionReadFromAServer() {
345 List<String> blacks = Arrays.asList(
363 List<String> whites = Arrays.asList(
382 Board b = Rules.createBoard();
383 Rules.initBoard(b, whites, blacks, Color.W);
385 Board b2 = Rules.createBoard();
388 for (int i = 0; i < 7; i++) {
389 for (int j = 0; j < 7; j++) {
390 Square s = b.getRows().get(i).getColumns().get(j);
391 Square s2 = b2.getRows().get(i).getColumns().get(j);
393 assertEquals(s.getPiece(), s2.getPiece(), "Same piece at " + i + "/" + j);
394 assertEquals(s.getPieceColor(), s2.getPieceColor(), "Same piece color at " + i + "/" + j);
399 @Test public void allowSmallRochade() {
400 Board b = Rules.createBoard();
401 setPlayer(b, Color.W);
402 Square f1 = BoardModel.findSquare(b, 'F', 1);
404 f1.setPieceColor(null);
405 Square g1 = BoardModel.findSquare(b, 'G', 1);
407 g1.setPieceColor(null);
408 Square e1 = BoardModel.findSquare(b, 'E', 1);
410 BoardModel.selected(b, e1);
411 assertTrue(g1.isAccessible(), "Can do 0-0");
414 @Test public void allowSmallRochadeForBlack() {
415 Board b = Rules.createBoard();
416 setPlayer(b, Color.B);
418 Square f8 = BoardModel.findSquare(b, 'F', 8);
420 f8.setPieceColor(null);
421 Square g8 = BoardModel.findSquare(b, 'G', 8);
423 g8.setPieceColor(null);
424 Square e8 = BoardModel.findSquare(b, 'E', 8);
426 BoardModel.selected(b, e8);
427 assertTrue(g8.isAccessible(), "Can do 0-0");
430 @Test public void disallowSmallRochadeWhenNoRock() {
431 Board b = Rules.createBoard();
432 setPlayer(b, Color.W);
433 Square f1 = BoardModel.findSquare(b, 'F', 1);
435 f1.setPieceColor(null);
436 Square g1 = BoardModel.findSquare(b, 'G', 1);
438 g1.setPieceColor(null);
439 Square h1 = BoardModel.findSquare(b, 'H', 1);
441 h1.setPieceColor(null);
442 Square e1 = BoardModel.findSquare(b, 'E', 1);
444 BoardModel.selected(b, e1);
445 assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is no rock");
448 @Test public void disallowSmallRochadeWhenBishop() {
449 Board b = Rules.createBoard();
450 setPlayer(b, Color.W);
451 Square g1 = BoardModel.findSquare(b, 'G', 1);
453 Square e1 = BoardModel.findSquare(b, 'E', 1);
455 BoardModel.selected(b, e1);
456 assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is bishop");
459 @Test public void disallowSmallRochadeWhenKnight() {
460 Board b = Rules.createBoard();
461 setPlayer(b, Color.W);
462 Square f1 = BoardModel.findSquare(b, 'F', 1);
464 Square e1 = BoardModel.findSquare(b, 'E', 1);
466 BoardModel.selected(b, e1);
467 assertFalse(f1.isAccessible(), "Cannot do 0-0 when there is knight");
470 @Test public void allowBigRochadeForBlack() {
471 Board b = Rules.createBoard();
472 setPlayer(b, Color.B);
474 Square b8 = BoardModel.findSquare(b, 'B', 8);
476 b8.setPieceColor(null);
477 Square c8 = BoardModel.findSquare(b, 'C', 8);
479 c8.setPieceColor(null);
480 Square d8 = BoardModel.findSquare(b, 'D', 8);
482 d8.setPieceColor(null);
483 Square e8 = BoardModel.findSquare(b, 'E', 8);
485 BoardModel.selected(b, e8);
486 assertTrue(c8.isAccessible(), "Can do 0-0-0");
489 @Test public void enPassant() {
490 Board b = Rules.createBoard();
491 setPlayer(b, Color.B);
494 Square e7 = BoardModel.findSquare(b, 'E', 7);
495 Square e4 = BoardModel.findSquare(b, 'E', 4);
498 Move move = new Move();
499 move.setFrom(position('D', 2));
500 move.setTo(position('D', 4));
501 move.setPiece(PieceType.PAWN);
502 b.getMoves().add(move);
504 Square d2 = BoardModel.findSquare(b, 'D', 2);
505 Square d4 = BoardModel.findSquare(b, 'D', 4);
508 BoardModel.selected(b, e4);
510 Square e3 = BoardModel.findSquare(b, 'E', 3);
511 assertTrue(e3.isAccessible(), "Obviously can move to e3");
513 Square d3 = BoardModel.findSquare(b, 'D', 3);
514 assertTrue(d3.isAccessible(), "Can also take on d3");
517 private void movePiece(Square from, Square to) {
518 to.setPiece(from.getPiece());
519 to.setPieceColor(from.getPieceColor());
521 from.setPieceColor(null);
524 private Position position(char c, int i) {
525 Position p = new Position();
531 private static void setPlayer(Board b, Color c) {
532 b.setWhitePlayer("x");
533 b.setBlackPlayer("y");