MoveGen { public final MoveList pseudoLegalMoves(Position pos) { MoveList moveList = getMoveListObj(); final long occupied = pos.whiteBB | pos.blackBB; if (pos.whiteMove) { long squares = pos.pieceTypeBB[Piece.WQUEEN]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & ~pos.whiteBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } squares = pos.pieceTypeBB[Piece.WROOK]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = BitBoard.rookAttacks(sq, occupied) & ~pos.whiteBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } squares = pos.pieceTypeBB[Piece.WBISHOP]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = BitBoard.bishopAttacks(sq, occupied) & ~pos.whiteBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } { int sq = pos.getKingSq(true); long m = BitBoard.kingAttacks[sq] & ~pos.whiteBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; final int k0 = 4; if (sq == k0) { final long OO_SQ = 0x60L; final long OOO_SQ = 0xEL; if (((pos.getCastleMask() & (1 << Position.H1_CASTLE)) != 0) && ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) && (pos.getPiece(k0 + 3) == Piece.WROOK) && !sqAttacked(pos, k0) && !sqAttacked(pos, k0 + 1)) { setMove(moveList, k0, k0 + 2, Piece.EMPTY); } if (((pos.getCastleMask() & (1 << Position.A1_CASTLE)) != 0) && ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) && (pos.getPiece(k0 - 4) == Piece.WROOK) && !sqAttacked(pos, k0) && !sqAttacked(pos, k0 - 1)) { setMove(moveList, k0, k0 - 2, Piece.EMPTY); } } } long knights = pos.pieceTypeBB[Piece.WKNIGHT]; while (knights != 0) { int sq = BitBoard.numberOfTrailingZeros(knights); long m = BitBoard.knightAttacks[sq] & ~pos.whiteBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; knights &= knights-1; } long pawns = pos.pieceTypeBB[Piece.WPAWN]; long m = (pawns << 8) & ~occupied; if (addPawnMovesByMask(moveList, pos, m, -8, true)) return moveList; m = ((m & BitBoard.maskRow3) << 8) & ~occupied; addPawnDoubleMovesByMask(moveList, pos, m, -16); int epSquare = pos.getEpSquare(); long epMask = (epSquare >= 0) ? (1L << epSquare) : 0L; m = (pawns << 7) & BitBoard.maskAToGFiles & (pos.blackBB | epMask); if (addPawnMovesByMask(moveList, pos, m, -7, true)) return moveList; m = (pawns << 9) & BitBoard.maskBToHFiles & (pos.blackBB | epMask); if (addPawnMovesByMask(moveList, pos, m, -9, true)) return moveList; } else { long squares = pos.pieceTypeBB[Piece.BQUEEN]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = (BitBoard.rookAttacks(sq, occupied) | BitBoard.bishopAttacks(sq, occupied)) & ~pos.blackBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } squares = pos.pieceTypeBB[Piece.BROOK]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = BitBoard.rookAttacks(sq, occupied) & ~pos.blackBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } squares = pos.pieceTypeBB[Piece.BBISHOP]; while (squares != 0) { int sq = BitBoard.numberOfTrailingZeros(squares); long m = BitBoard.bishopAttacks(sq, occupied) & ~pos.blackBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; squares &= squares-1; } { int sq = pos.getKingSq(false); long m = BitBoard.kingAttacks[sq] & ~pos.blackBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; final int k0 = 60; if (sq == k0) { final long OO_SQ = 0x6000000000000000L; final long OOO_SQ = 0xE00000000000000L; if (((pos.getCastleMask() & (1 << Position.H8_CASTLE)) != 0) && ((OO_SQ & (pos.whiteBB | pos.blackBB)) == 0) && (pos.getPiece(k0 + 3) == Piece.BROOK) && !sqAttacked(pos, k0) && !sqAttacked(pos, k0 + 1)) { setMove(moveList, k0, k0 + 2, Piece.EMPTY); } if (((pos.getCastleMask() & (1 << Position.A8_CASTLE)) != 0) && ((OOO_SQ & (pos.whiteBB | pos.blackBB)) == 0) && (pos.getPiece(k0 - 4) == Piece.BROOK) && !sqAttacked(pos, k0) && !sqAttacked(pos, k0 - 1)) { setMove(moveList, k0, k0 - 2, Piece.EMPTY); } } } long knights = pos.pieceTypeBB[Piece.BKNIGHT]; while (knights != 0) { int sq = BitBoard.numberOfTrailingZeros(knights); long m = BitBoard.knightAttacks[sq] & ~pos.blackBB; if (addMovesByMask(moveList, pos, sq, m)) return moveList; knights &= knights-1; } long pawns = pos.pieceTypeBB[Piece.BPAWN]; long m = (pawns >>> 8) & ~occupied; if (addPawnMovesByMask(moveList, pos, m, 8, true)) return moveList; m = ((m & BitBoard.maskRow6) >>> 8) & ~occupied; addPawnDoubleMovesByMask(moveList, pos, m, 16); int epSquare = pos.getEpSquare(); long epMask = (epSquare >= 0) ? (1L << epSquare) : 0L; m = (pawns >>> 9) & BitBoard.maskAToGFiles & (pos.whiteBB | epMask); if (addPawnMovesByMask(moveList, pos, m, 9, true)) return moveList; m = (pawns >>> 7) & BitBoard.maskBToHFiles & (pos.whiteBB | epMask); if (addPawnMovesByMask(moveList, pos, m, 7, true)) return moveList; } return moveList; }  final MoveList pseudoLegalMoves(Position pos); final MoveList checkEvasions(Position pos); final MoveList pseudoLegalCapturesAndChecks(Position pos); final MoveList pseudoLegalCaptures(Position pos); static boolean inCheck(Position pos); static boolean givesCheck(Position pos, Move m); static boolean canTakeKing(Position pos); static boolean sqAttacked(Position pos, int sq); static void removeIllegal(Position pos, MoveList moveList); final void returnMoveList(MoveList moveList);  }
@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<String> 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")); 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")); 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")); 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")); 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")); assertTrue(strMoves.contains("e1c1")); }