X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=9fe5f893c9da5f199577abeb283fa7942d4bee6e;hp=779c2640b3be24b261f77af64ae2dff30f4839cf;hb=0162fb83c21b9ac4d5ed302d4bc5a12b7a0cfc43;hpb=ace8e951d70c2986a0af83effcc0d2b2312d29e3 diff --git a/src/position.cpp b/src/position.cpp index 779c2640..9fe5f893 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -20,7 +20,8 @@ #include #include -#include // For std::memset, std::memcmp +#include // For offsetof() +#include // For std::memset, std::memcmp #include #include @@ -34,6 +35,10 @@ using std::string; +namespace PSQT { + extern Score psq[PIECE_NB][SQUARE_NB]; +} + namespace Zobrist { Key psq[PIECE_NB][SQUARE_NB]; @@ -420,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(); - - if (!more_than_one(b)) - result |= b; + Square sniperSq = pop_lsb(&snipers); + Bitboard b = between_bb(s, sniperSq) & pieces(); + + if (!more_than_one(b)) + { + result |= b; + if (b & pieces(color_of(piece_on(s)))) + pinners |= sniperSq; + } } return result; } @@ -967,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)); @@ -999,12 +1009,10 @@ 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 - // 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]) - stmAttackers &= ~pinned_pieces(stm); + // Don't allow pinned pieces to attack pieces except the king as long all + // pinners are on their original square. + if (!(st->pinnersForKing[stm] & ~occupied)) + stmAttackers &= ~st->blockersForKing[stm]; if (!stmAttackers) return swapList[0]; @@ -1015,25 +1023,27 @@ 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)) - && (st->pinnersForKing[stm] & occupied) == st->pinnersForKing[stm]) - stmAttackers &= ~pinned_pieces(stm); + + // Don't allow pinned pieces to attack pieces except the king + if ( nextVictim != KING + && !(st->pinnersForKing[stm] & ~occupied)) + stmAttackers &= ~st->blockersForKing[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.