diff --git a/src/position.cpp b/src/position.cpp index c193f266..f5081bd1 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -425,23 +425,28 @@ Phase Position::game_phase() const { /// slider if removing that piece from the board would result in a position where /// square 's' is attacked. For example, a king-attack blocking piece can be either /// a pinned or a discovered check piece, according if its color is the opposite -/// or the same of the color of the slider. The pinners bitboard get filled with -/// real and potential pinners. +/// or the same of the color of the slider. Bitboard Position::slider_blockers(Bitboard sliders, Square s, Bitboard& pinners) const { - Bitboard b, p, result = 0; + Bitboard result = 0; + pinners = 0; - // Pinners are sliders that attack 's' when a pinned piece is removed - pinners = p = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK)) - | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders; + // Snipers are sliders that attack 's' when a piece is removed + Bitboard snipers = ( (PseudoAttacks[ROOK ][s] & pieces(QUEEN, ROOK)) + | (PseudoAttacks[BISHOP][s] & pieces(QUEEN, BISHOP))) & sliders; - while (p) + while (snipers) { - b = between_bb(s, pop_lsb(&p)) & pieces(); + Square sniperSq = pop_lsb(&snipers); + Bitboard b = between_bb(s, sniperSq) & pieces(); - if (!more_than_one(b)) - result |= b; + if (!more_than_one(b)) + { + result |= b; + if (b & pieces(color_of(piece_on(s)))) + pinners |= sniperSq; + } } return result; } @@ -972,7 +977,7 @@ Value Position::see(Move m) const { Bitboard occupied, attackers, stmAttackers; Value swapList[32]; int slIndex = 1; - PieceType captured; + PieceType nextVictim; Color stm; assert(is_ok(m)); @@ -1004,8 +1009,8 @@ Value Position::see(Move m) const { stmAttackers = attackers & pieces(stm); occupied ^= to; // For the case when captured piece is a pinner - // Don't allow pinned pieces to attack as long all pinners (this includes also - // potential ones) are on their original square. When a pinner moves to the + // Don't allow pinned pieces to attack pieces except the king as long all + // pinners are on their original square. When a pinner moves to the // exchange-square or get captured on it, we fall back to standard SEE behaviour. if ( (stmAttackers & pinned_pieces(stm)) && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm]) @@ -1020,25 +1025,26 @@ Value Position::see(Move m) const { // destination square, where the sides alternately capture, and always // capture with the least valuable piece. After each capture, we look for // new X-ray attacks from behind the capturing piece. - captured = type_of(piece_on(from)); + nextVictim = type_of(piece_on(from)); do { assert(slIndex < 32); // Add the new entry to the swap list - swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured]; + swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][nextVictim]; // Locate and remove the next least valuable attacker - captured = min_attacker(byTypeBB, to, stmAttackers, occupied, attackers); + nextVictim = min_attacker(byTypeBB, to, stmAttackers, occupied, attackers); stm = ~stm; stmAttackers = attackers & pieces(stm); - if ( (stmAttackers & pinned_pieces(stm)) + if ( nextVictim != KING + && (stmAttackers & pinned_pieces(stm)) && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm]) stmAttackers &= ~pinned_pieces(stm); ++slIndex; - } while (stmAttackers && (captured != KING || (--slIndex, false))); // Stop before a king capture + } while (stmAttackers && (nextVictim != KING || (--slIndex, false))); // Stop before a king capture // Having built the swap list, we negamax through it to find the best // achievable score from the point of view of the side to move.