Search { final public int SEE(Move m) { final int kV = Evaluate.kV; final int square = m.to; if (square == pos.getEpSquare()) { captures[0] = Evaluate.pV; } else { captures[0] = Evaluate.pieceValue[pos.getPiece(square)]; if (captures[0] == kV) return kV; } int nCapt = 1; pos.makeSEEMove(m, seeUi); boolean white = pos.whiteMove; int valOnSquare = Evaluate.pieceValue[pos.getPiece(square)]; long occupied = pos.whiteBB | pos.blackBB; while (true) { int bestValue = Integer.MAX_VALUE; long atk; if (white) { atk = BitBoard.bPawnAttacks[square] & pos.pieceTypeBB[Piece.WPAWN] & occupied; if (atk != 0) { bestValue = Evaluate.pV; } else { atk = BitBoard.knightAttacks[square] & pos.pieceTypeBB[Piece.WKNIGHT] & occupied; if (atk != 0) { bestValue = Evaluate.nV; } else { long bAtk = BitBoard.bishopAttacks(square, occupied) & occupied; atk = bAtk & pos.pieceTypeBB[Piece.WBISHOP]; if (atk != 0) { bestValue = Evaluate.bV; } else { long rAtk = BitBoard.rookAttacks(square, occupied) & occupied; atk = rAtk & pos.pieceTypeBB[Piece.WROOK]; if (atk != 0) { bestValue = Evaluate.rV; } else { atk = (bAtk | rAtk) & pos.pieceTypeBB[Piece.WQUEEN]; if (atk != 0) { bestValue = Evaluate.qV; } else { atk = BitBoard.kingAttacks[square] & pos.pieceTypeBB[Piece.WKING] & occupied; if (atk != 0) { bestValue = kV; } else { break; } } } } } } } else { atk = BitBoard.wPawnAttacks[square] & pos.pieceTypeBB[Piece.BPAWN] & occupied; if (atk != 0) { bestValue = Evaluate.pV; } else { atk = BitBoard.knightAttacks[square] & pos.pieceTypeBB[Piece.BKNIGHT] & occupied; if (atk != 0) { bestValue = Evaluate.nV; } else { long bAtk = BitBoard.bishopAttacks(square, occupied) & occupied; atk = bAtk & pos.pieceTypeBB[Piece.BBISHOP]; if (atk != 0) { bestValue = Evaluate.bV; } else { long rAtk = BitBoard.rookAttacks(square, occupied) & occupied; atk = rAtk & pos.pieceTypeBB[Piece.BROOK]; if (atk != 0) { bestValue = Evaluate.rV; } else { atk = (bAtk | rAtk) & pos.pieceTypeBB[Piece.BQUEEN]; if (atk != 0) { bestValue = Evaluate.qV; } else { atk = BitBoard.kingAttacks[square] & pos.pieceTypeBB[Piece.BKING] & occupied; if (atk != 0) { bestValue = kV; } else { break; } } } } } } } captures[nCapt++] = valOnSquare; if (valOnSquare == kV) break; valOnSquare = bestValue; occupied &= ~(atk & -atk); white = !white; } pos.unMakeSEEMove(m, seeUi); int score = 0; for (int i = nCapt - 1; i > 0; i--) { score = Math.max(0, captures[i] - score); } return captures[0] - score; } Search(Position pos, long[] posHashList, int posHashListSize, TranspositionTable tt,
                  History ht); void setListener(Listener listener); final void timeLimit(int minTimeLimit, int maxTimeLimit); final void setStrength(int strength, long randomSeed, int maxNPS); final Move iterativeDeepening(MoveGen.MoveList scMovesIn,
            int maxDepth, long initialMaxNodes, boolean verbose); final int negaScout(int alpha, int beta, int ply, int depth, int recaptureSquare,
                               final boolean inCheck); final int signSEE(Move m); final boolean negSEE(Move m); final int SEE(Move m); static boolean canClaimDraw50(Position pos); static boolean canClaimDrawRep(Position pos, long[] posHashList, int posHashListSize, int posHashFirstNew); public int nodesBetweenTimeCheck; final static int MATE0; final static int UNKNOWN_SCORE; }
@Test public void testSEE() throws ChessParseError { System.out.println("SEE"); final int pV = Evaluate.pV; final int nV = Evaluate.nV; final int bV = Evaluate.bV; final int rV = Evaluate.rV; Position pos = TextIO.readFEN("r2qk2r/ppp2ppp/1bnp1nb1/1N2p3/3PP3/1PP2N2/1P3PPP/R1BQRBK1 w kq - 0 1"); Search sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "dxe5"))); assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxe5"))); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa7"))); assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxa7"))); assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxd6"))); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "d5"))); assertEquals(-bV, getSEE(sc, TextIO.stringToMove(pos, "Bf4"))); assertEquals(-bV, getSEE(sc, TextIO.stringToMove(pos, "Bh6"))); assertEquals(-rV, getSEE(sc, TextIO.stringToMove(pos, "Ra5"))); assertEquals(-rV, getSEE(sc, TextIO.stringToMove(pos, "Ra6"))); pos.setWhiteMove(false); sc = new Search(pos, nullHist, 0, tt, ht); assertTrue(nV <= bV); assertEquals(pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxd4"))); assertEquals(pV - bV, getSEE(sc, TextIO.stringToMove(pos, "Bxd4"))); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exd4"))); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Nxe4"))); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Bxe4"))); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "d5"))); assertEquals(-nV, getSEE(sc, TextIO.stringToMove(pos, "Nd5"))); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "a6"))); pos = TextIO.readFEN("3r2k1/pp1q1ppp/1bnr1nb1/1Np1p3/1P1PP3/2P1BN2/1Q1R1PPP/3R1BK1 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exd4"))); assertEquals(2 * pV - nV, getSEE(sc, TextIO.stringToMove(pos, "Nxd4"))); pos.setPiece(TextIO.getSquare("b2"), Piece.EMPTY); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exd4"))); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "cxb4"))); pos.setPiece(TextIO.getSquare("b5"), Piece.EMPTY); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "exd4"))); pos.setPiece(TextIO.getSquare("b2"), Piece.WQUEEN); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "exd4"))); pos.setPiece(TextIO.getSquare("b6"), Piece.EMPTY); pos.setPiece(TextIO.getSquare("c6"), Piece.EMPTY); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(-pV, getSEE(sc, TextIO.stringToMove(pos, "a5"))); pos = TextIO.readFEN("2b3k1/1p3ppp/8/pP6/8/2PB4/5PPP/6K1 w - a6 0 2"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "bxa6"))); pos.setPiece(TextIO.getSquare("b7"), Piece.EMPTY); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "bxa6"))); pos = TextIO.readFEN("8/8/8/4k3/r3P3/4K3/8/4R3 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+"))); pos = TextIO.readFEN("8/8/8/4k3/r3P1R1/4K3/8/8 b - - 0 1"); final int kV = Evaluate.kV; sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+"))); assertEquals(pV - kV, getSEE(sc, new Move(TextIO.getSquare("e5"), TextIO.getSquare("e4"), Piece.EMPTY))); pos = TextIO.readFEN("8/8/4k3/8/r3P3/4K3/8/8 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+"))); pos = TextIO.readFEN("8/8/4k3/8/r3P3/8/4K3/8 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxe4+"))); pos = TextIO.readFEN("8/3k4/8/8/r1K5/8/8/2R5 w - - 0 1"); pos.setWhiteMove(false); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(kV, getSEE(sc, new Move(TextIO.getSquare("a4"), TextIO.getSquare("c4"), Piece.EMPTY))); pos = TextIO.readFEN("r7/p2k4/8/r7/P7/8/4K3/R7 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos.setPiece(TextIO.getSquare("a7"), Piece.BBISHOP); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos.setPiece(TextIO.getSquare("a7"), Piece.BPAWN); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos.setPiece(TextIO.getSquare("a7"), Piece.BQUEEN); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos = TextIO.readFEN("8/3k4/R7/r7/P7/8/4K3/8 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos = TextIO.readFEN("Q7/q6k/R7/r7/P7/8/4K3/8 b - - 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); assertEquals(pV - rV, getSEE(sc, TextIO.stringToMove(pos, "Rxa4"))); pos = TextIO.readFEN("8/3k4/5R2/8/4pP2/8/8/3K4 b - f3 0 1"); sc = new Search(pos, nullHist, 0, tt, ht); int score1 = EvaluateTest.evalWhite(sc.pos); long h1 = sc.pos.zobristHash(); assertEquals(0, getSEE(sc, TextIO.stringToMove(pos, "exf3"))); int score2 = EvaluateTest.evalWhite(sc.pos); long h2 = sc.pos.zobristHash(); assertEquals(score1, score2); assertEquals(h1, h2); }