/* CuckooChess - A java chess program. Copyright (C) 2011 Peter Ă–sterlund, peterosterlund2@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package chess; import java.util.ArrayList; import java.util.List; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author petero */ public class MoveGenTest { public MoveGenTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } /** * Test of pseudoLegalMoves method, of class MoveGen. */ @Test public void testPseudoLegalMoves() throws ChessParseError { System.out.println("pseudoLegalMoves"); String fen = "8/3k4/8/2n2pP1/1P6/1NB5/2QP4/R3K2R w KQ f6 0 2"; Position pos = TextIO.readFEN(fen); assertEquals(fen, TextIO.toFEN(pos)); List strMoves = getMoveList(pos, false); assertTrue(strMoves.contains("a1d1")); assertTrue(!strMoves.contains("a1e1")); assertTrue(!strMoves.contains("a1f1")); assertTrue(strMoves.contains("a1a7")); assertTrue(strMoves.contains("e1f2")); assertTrue(!strMoves.contains("e1g3")); assertTrue(strMoves.contains("c3f6")); assertTrue(!strMoves.contains("b3d2")); // Test castling assertTrue(strMoves.contains("e1g1")); assertTrue(strMoves.contains("e1c1")); assertEquals(49, strMoves.size()); pos.setPiece(Position.getSquare(4,3), Piece.BROOK); strMoves = getMoveList(pos, false); assertTrue(!strMoves.contains("e1g1")); // In check, no castling possible assertTrue(!strMoves.contains("e1c1")); pos.setPiece(Position.getSquare(4, 3), Piece.EMPTY); pos.setPiece(Position.getSquare(5, 3), Piece.BROOK); strMoves = getMoveList(pos, false); assertTrue(!strMoves.contains("e1g1")); // f1 attacked, short castle not possible assertTrue(strMoves.contains("e1c1")); pos.setPiece(Position.getSquare(5, 3), Piece.EMPTY); pos.setPiece(Position.getSquare(6, 3), Piece.BBISHOP); strMoves = getMoveList(pos, false); assertTrue(strMoves.contains("e1g1")); // d1 attacked, long castle not possible assertTrue(!strMoves.contains("e1c1")); pos.setPiece(Position.getSquare(6, 3), Piece.EMPTY); pos.setCastleMask(1 << Position.A1_CASTLE); strMoves = getMoveList(pos, false); assertTrue(!strMoves.contains("e1g1")); // short castle right has been lost assertTrue(strMoves.contains("e1c1")); } /** * Test of pseudoLegalMoves method, of class MoveGen. Pawn moves. */ @Test public void testPawnMoves() throws ChessParseError { System.out.println("pawnMoves"); String fen = "1r2k3/P1pppp1p/8/1pP3p1/1nPp2P1/n4p1P/1P2PP2/4KBNR w K b6 0 1"; Position pos = TextIO.readFEN(fen); assertEquals(fen, TextIO.toFEN(pos)); List strMoves = getMoveList(pos, false); assertTrue(strMoves.contains("c5b6")); // En passant capture assertTrue(strMoves.contains("a7a8q")); // promotion assertTrue(strMoves.contains("a7a8n")); // under promotion assertTrue(strMoves.contains("a7b8r")); // capture promotion assertTrue(strMoves.contains("b2b3")); // pawn single move assertTrue(strMoves.contains("b2a3")); // pawn capture to the left assertTrue(strMoves.contains("e2e4")); // pawn double move assertTrue(strMoves.contains("e2f3")); // pawn capture to the right assertEquals(22, strMoves.size()); pos.setEpSquare(-1); strMoves = getMoveList(pos, false); assertEquals(21, strMoves.size()); // No ep, one less move possible // Check black pawn moves pos.setWhiteMove(false); strMoves = getMoveList(pos, false); assertTrue(strMoves.contains("f3e2")); assertTrue(strMoves.contains("d4d3")); assertTrue(strMoves.contains("e7e6")); assertTrue(strMoves.contains("e7e5")); assertEquals(28, strMoves.size()); // Check black pawn promotion pos.setPiece(Position.getSquare(0,1), Piece.BPAWN); strMoves = getMoveList(pos, false); assertTrue(strMoves.contains("a2a1q")); assertTrue(strMoves.contains("a2a1r")); assertTrue(strMoves.contains("a2a1n")); assertTrue(strMoves.contains("a2a1b")); } /** * Test of inCheck method, of class MoveGen. */ @Test public void testInCheck() { System.out.println("inCheck"); Position pos = new Position(); pos.setPiece(Position.getSquare(4,2), Piece.WKING); pos.setPiece(Position.getSquare(4,7), Piece.BKING); assertEquals(false, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(3,3), Piece.BQUEEN); assertEquals(true, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(3,3), Piece.BROOK); assertEquals(false, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(3,3), Piece.BPAWN); assertEquals(true, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(3,3), Piece.EMPTY); pos.setPiece(Position.getSquare(5,3), Piece.WQUEEN); assertEquals(false, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(4, 6), Piece.BROOK); assertEquals(true, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(4, 4), Piece.WPAWN); assertEquals(false, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(2, 3), Piece.BKNIGHT); assertEquals(true, MoveGen.inCheck(pos)); pos.setPiece(Position.getSquare(2, 3), Piece.EMPTY); pos.setPiece(Position.getSquare(0, 4), Piece.BKNIGHT); assertEquals(false, MoveGen.inCheck(pos)); } /** * Test of givesCheck method, of class MoveGen. */ @Test public void testGivesCheck() throws ChessParseError { System.out.println("givesCheck"); Position pos = new Position(); UndoInfo ui = new UndoInfo(); pos.setPiece(TextIO.getSquare("e3"), Piece.WKING); pos.setPiece(TextIO.getSquare("e8"), Piece.BKING); pos.setPiece(TextIO.getSquare("c2"), Piece.WROOK); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Rc8"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Rc6"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Rc7"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Re2"))); pos.setPiece(TextIO.getSquare("c2"), Piece.EMPTY); pos.setPiece(TextIO.getSquare("e2"), Piece.WROOK); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Kd3"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Kd4"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Ke4"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Kf2"))); pos.setPiece(TextIO.getSquare("e4"), Piece.WBISHOP); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Bd5"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Bc6"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Kd3"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Re1"))); pos = TextIO.readFEN("4k3/3p4/8/8/4B3/2K5/4R3/8 w - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Bc6"))); pos = TextIO.readFEN("4k3/8/5K2/8/6N1/8/8/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Ke6"))); assertTrue(!MoveGen.givesCheck(pos, new Move(TextIO.getSquare("f6"), TextIO.getSquare("e7"), Piece.EMPTY))); pos = TextIO.readFEN("8/2k5/8/4N3/8/2K3B1/8/8 w - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Kc4"))); pos.setPiece(TextIO.getSquare("g3"), Piece.WROOK); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos.setPiece(TextIO.getSquare("g3"), Piece.WQUEEN); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos.setPiece(TextIO.getSquare("g3"), Piece.WKNIGHT); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos.setPiece(TextIO.getSquare("g3"), Piece.WPAWN); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos.setPiece(TextIO.getSquare("c3"), Piece.EMPTY); pos.setPiece(TextIO.getSquare("g3"), Piece.WKING); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos = TextIO.readFEN("8/2k5/3p4/4N3/8/2K3B1/8/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos = TextIO.readFEN("8/2k5/8/4N3/8/6q1/2K5/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos = TextIO.readFEN("8/2k5/8/4N3/8/8/2K5/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "Nf7"))); pos = TextIO.readFEN("2nk4/3P4/8/8/3R4/8/2K5/8 w - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc8N"))); pos = TextIO.readFEN("8/2k5/2p5/1P1P4/8/2K5/8/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "d6"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "bxc6"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "b6"))); pos = TextIO.readFEN("8/8/R1PkP2R/8/8/2K5/8/8 w - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c7"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "e7"))); // Test pawn promotion pos = TextIO.readFEN("8/1P6/2kP4/8/8/2K5/8/8 w - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "d7"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "b8Q"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "b8N"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "b8R"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "b8B"))); pos = TextIO.readFEN("8/2P1P3/2k5/8/8/2K5/8/8 w - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "e8Q"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "e8N"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "e8R"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "e8B"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c8Q"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c8N"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c8R"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c8B"))); // Test castling pos = TextIO.readFEN("8/8/8/8/5k2/8/8/R3K2R w KQ - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); pos = TextIO.readFEN("8/8/8/8/6k1/8/8/R3K2R w KQ - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); pos = TextIO.readFEN("8/8/8/8/3k4/8/8/R3K2R w KQ - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); pos = TextIO.readFEN("8/8/8/8/5k2/8/5P2/R3K2R w KQ - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); pos = TextIO.readFEN("8/8/8/8/8/8/8/R3K2k w Q - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); pos = TextIO.readFEN("8/8/8/8/8/8/8/2k1K2R w K - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); pos.setPiece(TextIO.getSquare("d1"), Piece.WKNIGHT); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); // Test en passant pos = TextIO.readFEN("8/1kp5/8/3P4/8/8/8/4K3 b - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "c5"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); pos = TextIO.readFEN("3k4/2p5/8/3P4/8/8/3R4/4K3 b - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "c5"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); pos = TextIO.readFEN("5k2/2p5/8/3P4/8/B7/8/4K3 b - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "c5"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); pos = TextIO.readFEN("5k2/2p5/8/3P4/1P6/B7/8/4K3 b - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "c5"), ui); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); pos = TextIO.readFEN("8/2p5/8/R2P1k2/8/8/8/4K3 b - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "c5"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "dxc6"))); // Black pawn moves pos = TextIO.readFEN("8/2p5/8/R4k2/1K6/8/8/8 b - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c5"))); pos = TextIO.readFEN("8/2p5/8/R4k2/2K5/8/8/8 b - - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c5"))); pos = TextIO.readFEN("8/2p5/8/R4k2/3K4/8/8/8 b - - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "c5"))); // Black castling pos = TextIO.readFEN("r3k2r/8/8/5K2/8/8/8/8 b kq - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); pos = TextIO.readFEN("r3k2r/8/8/6K1/8/8/8/8 b kq - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O"))); pos = TextIO.readFEN("r3k2r/8/8/2K5/8/8/8/8 b kq - 0 1"); assertTrue(!MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); pos = TextIO.readFEN("r3k2r/8/8/3K4/8/8/8/8 b kq - 0 1"); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "O-O-O"))); // Black en passant pos = TextIO.readFEN("8/8/4k3/8/4p3/8/5PK1/8 w - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "f4"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "exf3"))); pos = TextIO.readFEN("8/8/4k3/8/K3p1r1/8/5P2/8 w - - 0 1"); pos.makeMove(TextIO.stringToMove(pos, "f4"), ui); assertTrue(MoveGen.givesCheck(pos, TextIO.stringToMove(pos, "exf3"))); } /** * Test of removeIllegal method, of class MoveGen. */ @Test public void testRemoveIllegal() throws ChessParseError { System.out.println("removeIllegal"); Position pos = TextIO.readFEN("8/3k4/8/2n1rpP1/1P6/1NB5/2QP4/R3K2R w KQ f6 0 1"); List strMoves = getMoveList(pos, true); assertTrue(strMoves.contains("c2e4")); assertTrue(strMoves.contains("c3e5")); assertTrue(strMoves.contains("e1d1")); assertTrue(strMoves.contains("e1f1")); assertTrue(strMoves.contains("e1f2")); assertEquals(5, strMoves.size()); pos = TextIO.readFEN("4k3/8/8/2KPp1r1/8/8/8/8 w - e6 0 2"); strMoves = getMoveList(pos, true); assertTrue(!strMoves.contains("d5e6")); assertEquals(7, strMoves.size()); pos = TextIO.readFEN("8/6p1/4p3/2k1Pp1B/4KP1p/6rP/8/8 w - f6 0 55"); strMoves = getMoveList(pos, true); assertTrue(strMoves.contains("e5f6")); assertEquals(1, strMoves.size()); } /** * Test that if king capture is possible, only a king capture move is returned in the move list. */ @Test public void testKingCapture() throws ChessParseError { System.out.println("kingCapture"); Position pos = TextIO.readFEN("8/4k3/8/8/8/8/8/4RK2 b - - 0 1"); pos.setWhiteMove(true); List strMoves = getMoveList(pos, false); assertEquals(1, strMoves.size()); assertEquals("e1e7", strMoves.get(0)); pos.setPiece(Position.getSquare(0, 2), Piece.WBISHOP); pos.setPiece(Position.getSquare(4, 1), Piece.WPAWN); strMoves = getMoveList(pos, false); assertEquals(1, strMoves.size()); assertEquals("a3e7", strMoves.get(0)); pos.setPiece(Position.getSquare(1, 3), Piece.WPAWN); pos.setPiece(Position.getSquare(5, 5), Piece.WPAWN); strMoves = getMoveList(pos, false); assertEquals(1, strMoves.size()); assertEquals("f6e7", strMoves.get(0)); } /** Test that captureList and captureAndcheckList are generated correctly. */ @Test public void testCaptureList() throws ChessParseError { System.out.println("captureList"); Position pos = TextIO.readFEN("rnbqkbnr/ppp2ppp/3p1p2/R7/4N3/8/PPPPQPPP/2B1KB1R w Kkq - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("rnb1kbn1/ppp1qppp/5p2/4p3/3N3r/3P4/PPP2PPP/R1BQKB1R b KQq - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("rnb1k1n1/ppp1qppp/5p2/b3p3/1r1N4/3P4/PPP2PPP/R1BQKB1R b KQq - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("8/8/8/8/3k4/8/4P3/4K3 w - - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("8/8/8/3k4/8/8/4P3/4K3 w - - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("8/8/8/3k4/4p3/8/3KP3/8 b - - 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("3k4/r2p2K1/8/8/8/8/8/8 b - - 0 1"); getMoveList(pos, false); } @Test public void testCheckEvasions() throws ChessParseError { System.out.println("checkEvasions"); Position pos = TextIO.readFEN("n7/8/8/7k/5pP1/5K2/8/8 b - g3 0 1"); getMoveList(pos, false); pos = TextIO.readFEN("rn1qkbnr/pppB1ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq - 0 1"); getMoveList(pos, false); // King captures must be included in check evasions pos = TextIO.readFEN("r1bq2r1/pp3pbk/2p1p1P1/8/3P4/2PB1N2/PP3PPR/2KR4 b - - 0 1"); UndoInfo ui = new UndoInfo(); pos.makeMove(TextIO.uciStringToMove("g7h6"), ui); getMoveList(pos, false); List evList = getCheckEvasions(pos, false); assertTrue(evList.contains("g6h7")); pos = TextIO.readFEN("1R6/1brk2p1/2P1p2p/p3Pp2/P7/6P1/1P4P1/2R3K1 b - - 0 1"); getMoveList(pos, false); evList = getCheckEvasions(pos, false); assertTrue(evList.contains("b7c6")); } private List getMoveList(Position pos, boolean onlyLegal) { Position swap = EvaluateTest.swapColors(pos); List swapList = getMoveList0(swap, onlyLegal); List ret = getMoveList0(pos, onlyLegal); assertEquals(swapList.size(), ret.size()); // FIXME! Test that swapList contains swapped moves compared to ret return ret; } private List getMoveList0(Position pos, boolean onlyLegal) { MoveGen moveGen = new MoveGen(); MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos); if (onlyLegal) MoveGen.removeIllegal(pos, moves); ArrayList strMoves = new ArrayList(); for (int mi = 0; mi < moves.size; mi++) { Move m = moves.m[mi]; String mStr = TextIO.moveToUCIString(m); strMoves.add(mStr); } List capList1 = getCaptureList(pos, false, onlyLegal); assertTrue(strMoves.containsAll(capList1)); List capList2 = getCaptureList(pos, true, onlyLegal); assertTrue(strMoves.containsAll(capList2)); List evList = getCheckEvasions(pos, onlyLegal); if (evList != null) assertTrue(strMoves.containsAll(evList)); UndoInfo ui = new UndoInfo(); for (String sm : strMoves) { Move m = TextIO.uciStringToMove(sm); if (m != null) { pos.makeMove(m, ui); boolean invalid = MoveGen.canTakeKing(pos); pos.unMakeMove(m, ui); if (invalid) m = null; } if (m == null) // Move was illegal (but pseudo-legal) continue; boolean qProm = false; // Promotion types considered in qsearch switch (m.promoteTo) { case Piece.WQUEEN: case Piece.BQUEEN: case Piece.WKNIGHT: case Piece.BKNIGHT: case Piece.EMPTY: qProm = true; break; default: break; } if (!MoveGen.canTakeKing(pos) && MoveGen.givesCheck(pos, m)) { if (qProm) assertTrue(capList2.contains(sm)); } else { switch (m.promoteTo) { case Piece.WQUEEN: case Piece.BQUEEN: case Piece.WKNIGHT: case Piece.BKNIGHT: assertTrue(capList1.contains(sm)); // All queen/knight promotions assertTrue(capList2.contains(sm)); // All queen/knight promotions break; case Piece.EMPTY: break; default: assertTrue(!capList1.contains(sm)); // No rook/bishop promotions assertTrue(!capList2.contains(sm)); // No rook/bishop promotions break; } } if (pos.getPiece(m.to) != Piece.EMPTY) { if (qProm) { assertTrue(capList1.contains(sm)); assertTrue(capList2.contains(sm)); } } if (evList != null) { assertTrue(evList.contains(sm)); } } return strMoves; } private List getCaptureList(Position pos, boolean includeChecks, boolean onlyLegal) { MoveGen.MoveList moves; if (includeChecks) { moves = new MoveGen().pseudoLegalCapturesAndChecks(pos); } else { moves = new MoveGen().pseudoLegalCaptures(pos); } if (onlyLegal) MoveGen.removeIllegal(pos, moves); ArrayList strMoves = new ArrayList(); for (int mi = 0; mi < moves.size; mi++) { Move m = moves.m[mi]; String mStr = TextIO.moveToUCIString(m); strMoves.add(mStr); } return strMoves; } private List getCheckEvasions(Position pos, boolean onlyLegal) { if (!MoveGen.inCheck(pos)) return null; MoveGen.MoveList moves = new MoveGen().checkEvasions(pos); if (onlyLegal) MoveGen.removeIllegal(pos, moves); ArrayList strMoves = new ArrayList(); for (int mi = 0; mi < moves.size; mi++) { Move m = moves.m[mi]; String mStr = TextIO.moveToUCIString(m); strMoves.add(mStr); } return strMoves; } }