Skip to content

Commit

Permalink
Syntaxic sugar for Position::see_ge(move, threshold)
Browse files Browse the repository at this point in the history
Syntactic sugar around Position::see_ge(), so that we can use
the more readable pos.see(move) >= threshold instead of
pos.see_ge(move, threshold), and similar readable code for
the other comparison operators.

Closes #5529

No functional change.
  • Loading branch information
snicolet committed Aug 8, 2024
1 parent ae9e55c commit 29d1260
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
6 changes: 3 additions & 3 deletions src/movepick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, int th, const CapturePieceTo
assert(!pos.checkers());

stage = PROBCUT_TT
+ !(ttm && pos.capture_stage(ttm) && pos.pseudo_legal(ttm) && pos.see_ge(ttm, threshold));
+ !(ttm && pos.capture_stage(ttm) && pos.pseudo_legal(ttm) && pos.see(ttm) >= threshold);
}

// Assigns a numerical value to each move in a list, used for sorting.
Expand Down Expand Up @@ -238,7 +238,7 @@ Move MovePicker::next_move(bool skipQuiets) {
case GOOD_CAPTURE :
if (select<Next>([&]() {
// Move losing capture to endBadCaptures to be tried later
return pos.see_ge(*cur, -cur->value / 18) ? true
return pos.see(*cur) >= (-cur->value / 18) ? true
: (*endBadCaptures++ = *cur, false);
}))
return *(cur - 1);
Expand Down Expand Up @@ -305,7 +305,7 @@ Move MovePicker::next_move(bool skipQuiets) {
return select<Best>([]() { return true; });

case PROBCUT :
return select<Next>([&]() { return pos.see_ge(*cur, threshold); });
return select<Next>([&]() { return pos.see(*cur) >= threshold; });

case QCAPTURE :
return select<Next>([]() { return true; });
Expand Down
6 changes: 3 additions & 3 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1022,9 +1022,9 @@ Key Position::key_after(Move m) const {
}


// Tests if the SEE (Static Exchange Evaluation)
// value of move is greater or equal to the given threshold. We'll use an
// algorithm similar to alpha-beta pruning with a null window.
// Tests if the SEE (Static Exchange Evaluation) value of a move is
// greater or equal to the given threshold. We will use an algorithm
// similar to alpha-beta pruning with a null window.
bool Position::see_ge(Move m, int threshold) const {

assert(m.is_ok());
Expand Down
16 changes: 16 additions & 0 deletions src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>

#include "bitboard.h"
#include "nnue/nnue_accumulator.h"
Expand Down Expand Up @@ -73,6 +74,12 @@ struct StateInfo {
using StateListPtr = std::unique_ptr<std::deque<StateInfo>>;


/// A temporary type to get a nice syntax for SEE comparisons. Never use this type
/// directly or assign a value to a variable of this type, instead use the syntax
/// "if (pos.see(move) >= threshold) ..." and similar for other comparisons.
typedef std::pair<const Position&, Move> SEE;


// Position class stores information regarding the board representation as
// pieces, side to move, hash keys, castling info, etc. Important methods are
// do_move() and undo_move(), used by the search to update node info when
Expand Down Expand Up @@ -144,6 +151,7 @@ class Position {

// Static Exchange Evaluation
bool see_ge(Move m, int threshold = 0) const;
inline const SEE see(Move m) const { return SEE(*this, m); }

// Accessing hash keys
Key key() const;
Expand Down Expand Up @@ -359,6 +367,14 @@ inline void Position::do_move(Move m, StateInfo& newSt) { do_move(m, newSt, give

inline StateInfo* Position::state() const { return st; }

// Syntactic sugar around Position::see_ge(), so that we can use the more readable
// pos.see(move) >= threshold instead of pos.see_ge(move, threshold), and similar
// readable code for the three other comparison operators.
inline bool operator>=(const SEE& s, Value threshold) { return s.first.see_ge(s.second, threshold);}
inline bool operator> (const SEE& s, Value threshold) { return (s >= threshold + 1); }
inline bool operator< (const SEE& s, Value threshold) { return !(s >= threshold); }
inline bool operator<=(const SEE& s, Value threshold) { return !(s >= threshold + 1); }

} // namespace Stockfish

#endif // #ifndef POSITION_H_INCLUDED
10 changes: 5 additions & 5 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ Value Search::Worker::search(

// SEE based pruning for captures and checks (~11 Elo)
int seeHist = std::clamp(captHist / 32, -182 * depth, 166 * depth);
if (!pos.see_ge(move, -168 * depth - seeHist))
if (pos.see(move) < -168 * depth - seeHist)
continue;
}
else
Expand Down Expand Up @@ -1019,7 +1019,7 @@ Value Search::Worker::search(
lmrDepth = std::max(lmrDepth, 0);

// Prune moves with negative SEE (~4 Elo)
if (!pos.see_ge(move, -24 * lmrDepth * lmrDepth))
if (pos.see(move) < -24 * lmrDepth * lmrDepth)
continue;
}
}
Expand Down Expand Up @@ -1566,15 +1566,15 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)

// If static eval is much lower than alpha and move is
// not winning material, we can prune this move. (~2 Elo)
if (futilityBase <= alpha && !pos.see_ge(move, 1))
if (futilityBase <= alpha && pos.see(move) <= 0)
{
bestValue = std::max(bestValue, futilityBase);
continue;
}

// If static exchange evaluation is much worse than what
// is needed to not fall below alpha, we can prune this move.
if (futilityBase > alpha && !pos.see_ge(move, (alpha - futilityBase) * 4))
if (futilityBase > alpha && pos.see(move) < (alpha - futilityBase) * 4)
{
bestValue = alpha;
continue;
Expand All @@ -1591,7 +1591,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
continue;

// Do not search moves with bad enough SEE values (~5 Elo)
if (!pos.see_ge(move, -83))
if (pos.see(move) < -83)
continue;
}

Expand Down

0 comments on commit 29d1260

Please sign in to comment.