X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=b4ccff5df3c053d1753934150f1c86deb0eb1232;hp=45d0147aef1f2c6d4b244ef8ae261ebe36bc4d7a;hb=807844eab194adc7c5378575f81d28ce9ca66287;hpb=2f01d67a925e01508b4f3ae3bdc1c44d14b85c8e diff --git a/src/position.cpp b/src/position.cpp index 45d0147a..b4ccff5d 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -51,6 +51,7 @@ Key Position::zobEp[64]; Key Position::zobCastle[16]; Key Position::zobMaterial[2][8][16]; Key Position::zobSideToMove; +Key Position::zobExclusion; Score Position::PieceSquareTable[16][64]; @@ -338,21 +339,20 @@ void Position::copy(const Position& pos) { /// king) pieces for the given color and for the given pinner type. Or, when /// template parameter FindPinned is false, the pieces of the given color /// candidate for a discovery check against the enemy king. -/// Note that checkersBB bitboard must be already updated. +/// Bitboard checkersBB must be already updated when looking for pinners. template Bitboard Position::hidden_checkers(Color c) const { - Bitboard pinners, result = EmptyBoardBB; + Bitboard result = EmptyBoardBB; + Bitboard pinners = pieces_of_color(FindPinned ? opposite_color(c) : c); // Pinned pieces protect our king, dicovery checks attack // the enemy king. Square ksq = king_square(FindPinned ? c : opposite_color(c)); - // Pinners are sliders, not checkers, that give check when - // candidate pinned is removed. - pinners = (pieces(ROOK, QUEEN, FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq]) - | (pieces(BISHOP, QUEEN, FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]); + // Pinners are sliders, not checkers, that give check when candidate pinned is removed + pinners &= (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq]) | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq]); if (FindPinned && pinners) pinners &= ~st->checkersBB; @@ -373,7 +373,8 @@ Bitboard Position::hidden_checkers(Color c) const { /// Position:pinned_pieces() returns a bitboard of all pinned (against the -/// king) pieces for the given color. +/// king) pieces for the given color. Note that checkersBB bitboard must +/// be already updated. Bitboard Position::pinned_pieces(Color c) const { @@ -383,7 +384,8 @@ Bitboard Position::pinned_pieces(Color c) const { /// Position:discovered_check_candidates() returns a bitboard containing all /// pieces for the given side which are candidates for giving a discovered -/// check. +/// check. Contrary to pinned_pieces() here there is no need of checkersBB +/// to be already updated. Bitboard Position::discovered_check_candidates(Color c) const { @@ -647,51 +649,17 @@ bool Position::move_is_check(Move m, const CheckInfo& ci) const { } -/// Position::update_checkers() udpates chekers info given the move. It is called -/// in do_move() and is faster then find_checkers(). - -template -inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square from, - Square to, Bitboard dcCandidates) { - - const bool Bishop = (Piece == QUEEN || Piece == BISHOP); - const bool Rook = (Piece == QUEEN || Piece == ROOK); - const bool Slider = Bishop || Rook; - - // Direct checks - if ( ( (Bishop && bit_is_set(BishopPseudoAttacks[ksq], to)) - || (Rook && bit_is_set(RookPseudoAttacks[ksq], to))) - && bit_is_set(attacks_from(ksq), to)) // slow, try to early skip - set_bit(pCheckersBB, to); - - else if ( Piece != KING - && !Slider - && bit_is_set(Piece == PAWN ? attacks_from(ksq, opposite_color(sideToMove)) - : attacks_from(ksq), to)) - set_bit(pCheckersBB, to); - - // Discovery checks - if (Piece != QUEEN && bit_is_set(dcCandidates, from)) - { - if (Piece != ROOK) - (*pCheckersBB) |= (attacks_from(ksq) & pieces(ROOK, QUEEN, side_to_move())); - - if (Piece != BISHOP) - (*pCheckersBB) |= (attacks_from(ksq) & pieces(BISHOP, QUEEN, side_to_move())); - } -} - - /// Position::do_move() makes a move, and saves all information necessary /// to a StateInfo object. The move is assumed to be legal. /// Pseudo-legal moves should be filtered out before this function is called. void Position::do_move(Move m, StateInfo& newSt) { - do_move(m, newSt, discovered_check_candidates(side_to_move())); + CheckInfo ci(*this); + do_move(m, newSt, ci, move_is_check(m, ci)); } -void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { +void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveIsCheck) { assert(is_ok()); assert(move_is_ok(m)); @@ -705,7 +673,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { Key pawnKey, materialKey; int castleRights, rule50, pliesFromNull; Square epSquare; - Value value; + Score value; Value npMaterial[2]; }; @@ -860,21 +828,27 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { st->key = key; // Update checkers bitboard, piece must be already moved - if (ep | pm) - st->checkersBB = attackers_to(king_square(them)) & pieces_of_color(us); - else + st->checkersBB = EmptyBoardBB; + + if (moveIsCheck) { - st->checkersBB = EmptyBoardBB; - Square ksq = king_square(them); - switch (pt) + if (ep | pm) + st->checkersBB = attackers_to(king_square(them)) & pieces_of_color(us); + else { - case PAWN: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - case KNIGHT: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - case BISHOP: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - case ROOK: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - case QUEEN: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - case KING: update_checkers(&(st->checkersBB), ksq, from, to, dcCandidates); break; - default: assert(false); break; + // Direct checks + if (bit_is_set(ci.checkSq[pt], to)) + st->checkersBB = SetMaskBB[to]; + + // Discovery checks + if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from)) + { + if (pt != ROOK) + st->checkersBB |= (attacks_from(ci.ksq) & pieces(ROOK, QUEEN, us)); + + if (pt != BISHOP) + st->checkersBB |= (attacks_from(ci.ksq) & pieces(BISHOP, QUEEN, us)); + } } } @@ -997,7 +971,7 @@ void Position::do_castle_move(Move m) { set_bit(&(byColorBB[us]), rto); set_bit(&(byTypeBB[ROOK]), rto); set_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares - + // Update board array Piece king = piece_of_color_and_type(us, KING); Piece rook = piece_of_color_and_type(us, ROOK); @@ -1182,7 +1156,7 @@ void Position::undo_castle_move(Move m) { assert(piece_on(kto) == piece_of_color_and_type(us, KING)); assert(piece_on(rto) == piece_of_color_and_type(us, ROOK)); - + // Remove pieces from destination squares: clear_bit(&(byColorBB[us]), kto); clear_bit(&(byTypeBB[KING]), kto); @@ -1190,7 +1164,7 @@ void Position::undo_castle_move(Move m) { clear_bit(&(byColorBB[us]), rto); clear_bit(&(byTypeBB[ROOK]), rto); clear_bit(&(byTypeBB[0]), rto); // HACK: byTypeBB[0] == occupied squares - + // Put pieces on source squares: set_bit(&(byColorBB[us]), kfrom); set_bit(&(byTypeBB[KING]), kfrom); @@ -1765,6 +1739,8 @@ void Position::init_zobrist() { for (int i = 0; i < 16; i++) zobMaterial[0][KING][i] = zobMaterial[1][KING][i] = Key(0ULL); + + zobExclusion = genrand_int64(); }