X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=28da877525a4773a87b1f25c31bd8ccca1da068d;hp=1c63f2a97f98d0c5da58ad615ed51cac6b7b95ff;hb=e304db9d1ecf6a2318708483c90fadecf4fac4ee;hpb=6436e75858f02d42df72243461c8a5f8bc7cb695 diff --git a/src/position.cpp b/src/position.cpp index 1c63f2a9..28da8775 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -40,16 +40,16 @@ static const string PieceToChar(" PNBRQK pnbrqk"); CACHE_LINE_ALIGNMENT -Score pieceSquareTable[16][64]; // [piece][square] -Value PieceValue[2][18] = { // [Mg / Eg][piece / pieceType] +Score pieceSquareTable[PIECE_NB][SQUARE_NB]; +Value PieceValue[2][18] = { // [Mg / Eg][piece / pieceType] { VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg }, { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } }; namespace Zobrist { -Key psq[2][8][64]; // [color][pieceType][square / piece count] -Key enpassant[8]; // [file] -Key castle[16]; // [castleRight] +Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Key enpassant[FILE_NB]; +Key castle[CASTLE_RIGHT_NB]; Key side; Key exclusion; @@ -102,6 +102,40 @@ void init() { } // namespace Zobrist +namespace { + +/// next_attacker() is an helper function used by see() to locate the least +/// valuable attacker for the side to move, remove the attacker we just found +/// from the 'occupied' bitboard and scan for new X-ray attacks behind it. + +template FORCE_INLINE +PieceType next_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers, + Bitboard& occupied, Bitboard& attackers) { + + if (stmAttackers & bb[Pt]) + { + Bitboard b = stmAttackers & bb[Pt]; + occupied ^= b & ~(b - 1); + + if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN) + attackers |= attacks_bb(to, occupied) & (bb[BISHOP] | bb[QUEEN]); + + if (Pt == ROOK || Pt == QUEEN) + attackers |= attacks_bb(to, occupied) & (bb[ROOK] | bb[QUEEN]); + + return (PieceType)Pt; + } + return next_attacker(bb, to, stmAttackers, occupied, attackers); +} + +template<> FORCE_INLINE +PieceType next_attacker(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) { + return KING; // No need to update bitboards, it is the last cycle +} + +} // namespace + + /// CheckInfo c'tor CheckInfo::CheckInfo(const Position& pos) { @@ -1218,7 +1252,7 @@ int Position::see_sign(Move m) const { int Position::see(Move m) const { Square from, to; - Bitboard occupied, attackers, stmAttackers, b; + Bitboard occupied, attackers, stmAttackers; int swapList[32], slIndex = 1; PieceType captured; Color stm; @@ -1274,27 +1308,19 @@ int Position::see(Move m) const { swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[Mg][captured]; slIndex++; - // Locate the least valuable attacker for the side to move. The loop - // below looks like it is potentially infinite, but it isn't. We know - // that the side to move still has at least one attacker left. - for (captured = PAWN; (b = stmAttackers & pieces(captured)) == 0; captured++) - assert(captured < KING); + // Locate and remove from 'occupied' the next least valuable attacker + captured = next_attacker(byTypeBB, to, stmAttackers, occupied, attackers); - // Remove the attacker we just found from the 'occupied' bitboard, - // and scan for new X-ray attacks behind the attacker. - occupied ^= (b & (~b + 1)); - attackers |= (attacks_bb(to, occupied) & pieces(ROOK, QUEEN)) - | (attacks_bb(to, occupied) & pieces(BISHOP, QUEEN)); - - attackers &= occupied; // Cut out pieces we've already done + attackers &= occupied; // Remove the just found attacker stm = ~stm; stmAttackers = attackers & pieces(stm); - // Stop before processing a king capture - if (captured == KING && stmAttackers) + if (captured == KING) { - assert(slIndex < 32); - swapList[slIndex++] = QueenValueMg * 16; + // Stop before processing a king capture + if (stmAttackers) + swapList[slIndex++] = QueenValueMg * 16; + break; } @@ -1567,7 +1593,7 @@ bool Position::pos_is_ok(int* failedStep) const { if ((*step)++, debugKingCount) { - int kingCount[2] = {}; + int kingCount[COLOR_NB] = {}; for (Square s = SQ_A1; s <= SQ_H8; s++) if (type_of(piece_on(s)) == KING)