From: ceebo Date: Wed, 8 Nov 2017 17:21:46 +0000 (+0000) Subject: Add comments to pos.see_ge() X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=3f44f5303bb0f3c9c02385ea25f32c14dedfd09b;ds=sidebyside Add comments to pos.see_ge() In terms of technical changes this patch eliminates the return statements from the main loop of pos.see_ge() and replaces two conditional computations with a single bitwise negation. No functional change --- diff --git a/src/position.cpp b/src/position.cpp index 42c1adff..14490cdd 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1003,17 +1003,21 @@ bool Position::see_ge(Move m, Value threshold) const { Value balance; // Values of the pieces taken by us minus opponent's ones Bitboard occupied, stmAttackers; - balance = PieceValue[MG][piece_on(to)]; + // The opponent may be able to recapture so this is the best result + // we can hope for. + balance = PieceValue[MG][piece_on(to)] - threshold; - if (balance < threshold) + if (balance < VALUE_ZERO) return false; + // Now assume the worst possible result: that the opponent can + // capture our piece for free. balance -= PieceValue[MG][nextVictim]; - if (balance >= threshold) // Always true if nextVictim == KING + if (balance >= VALUE_ZERO) // Always true if nextVictim == KING return true; - bool relativeStm = true; // True if the opponent is to move + bool opponentToMove = true; occupied = pieces() ^ from ^ to; // Find all attackers to the destination square, with the moving piece removed, @@ -1022,6 +1026,12 @@ bool Position::see_ge(Move m, Value threshold) const { while (true) { + // The balance is negative only because we assumed we could win + // the last piece for free. We are truly winning only if we can + // win the last piece _cheaply enough_. Test if we can actually + // do this otherwise "give up". + assert(balance < VALUE_ZERO); + stmAttackers = attackers & pieces(stm); // Don't allow pinned pieces to attack pieces except the king as long all @@ -1029,25 +1039,40 @@ bool Position::see_ge(Move m, Value threshold) const { if (!(st->pinnersForKing[stm] & ~occupied)) stmAttackers &= ~st->blockersForKing[stm]; + // If we have no more attackers we must give up if (!stmAttackers) - return relativeStm; + break; // Locate and remove the next least valuable attacker nextVictim = min_attacker(byTypeBB, to, stmAttackers, occupied, attackers); if (nextVictim == KING) - return relativeStm == bool(attackers & pieces(~stm)); - - balance += relativeStm ? PieceValue[MG][nextVictim] - : -PieceValue[MG][nextVictim]; + { + // Our only attacker is the king. If the opponent still has + // attackers we must give up. Otherwise we make the move and + // (having no more attackers) the opponent must give up. + if (!(attackers & pieces(~stm))) + opponentToMove = !opponentToMove; + break; + } - relativeStm = !relativeStm; + // Assume the opponent can win the next piece for free and switch sides + balance += PieceValue[MG][nextVictim]; + opponentToMove = !opponentToMove; - if (relativeStm == (balance >= threshold)) - return relativeStm; + // If balance is negative after receiving a free piece then give up + if (balance < VALUE_ZERO) + break; + // Complete the process of switching sides. The first line swaps + // all negative numbers with non-negative numbers. The compiler + // probably knows that it is just the bitwise negation ~balance. + balance = -balance-1; stm = ~stm; } + + // If the opponent gave up we win, otherwise we lose. + return opponentToMove; }