-/// Position::init_new_state() copies from the current state the fields
-/// that will be updated incrementally, skips the fields, like bitboards
-/// that will be recalculated form scratch anyway.
+/// Position::update_hidden_checks() udpates pinned, pinners and dcCandidates
+/// bitboards incrementally, given the move. It is called in do_move and is
+/// faster then find_hidden_checks().
+
+void Position::update_hidden_checks(Square from, Square to) {
+
+ Color us = sideToMove;
+ Color them = opposite_color(us);
+ Square ksq = king_square(opposite_color(us));
+
+ Bitboard moveSquares = EmptyBoardBB;
+ set_bit(&moveSquares, from);
+ set_bit(&moveSquares, to);
+
+ // Our moving piece could have been a possible pinner or hidden checker behind a dcCandidates?
+ bool checkerMoved = (st->dcCandidates[us] | st->pinners[them]) && (moveSquares & sliders());
+
+ // If we are moving from/to an opponent king attack direction and we was a possible hidden checker
+ // or there exsist some possible hidden checker on that line then recalculate the position
+ // otherwise skip because our dcCandidates and opponent pinned pieces are not changed.
+ if ( (moveSquares & RookPseudoAttacks[ksq]) && (checkerMoved || (rooks_and_queens(us) & RookPseudoAttacks[ksq]))
+ || (moveSquares & BishopPseudoAttacks[ksq]) && (checkerMoved || (bishops_and_queens(us) & BishopPseudoAttacks[ksq])))
+ find_hidden_checks(us);
+
+ ksq = king_square(us);