Mostly of times we are interested only in the sign of SEE,
namely if a capture is negative or not.
If the capturing piece is smaller then the captured one we
already know SEE cannot be negative and this information
is enough most of the times. And of course it is much
faster to detect then a full SEE.
Note that in case see_sign() is negative then the returned
value is exactly the see() value, this is very important,
especially for ordering capturing moves.
With this patch the calls to the costly see() are reduced
of almost 30%.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
for (int i = 0; i < numOfMoves; i++)
{
m = moves[i].move;
for (int i = 0; i < numOfMoves; i++)
{
m = moves[i].move;
+ seeValue = pos.see_sign(m);
if (seeValue >= 0)
{
if (move_is_promotion(m))
if (seeValue >= 0)
{
if (move_is_promotion(m))
return see(move_from(m), move_to(m));
}
return see(move_from(m), move_to(m));
}
+int Position::see_sign(Move m) const {
+
+ assert(move_is_ok(m));
+
+ Square from = move_from(m);
+ Square to = move_to(m);
+
+ // Early return if SEE cannot be negative because capturing piece value
+ // is not bigger then captured one.
+ if ( midgame_value_of_piece_on(from) <= midgame_value_of_piece_on(to)
+ && type_of_piece_on(from) != KING)
+ return 1;
+
+ return see(from, to);
+}
+
int Position::see(Square from, Square to) const {
// Material values
int Position::see(Square from, Square to) const {
// Material values
int see(Square from, Square to) const;
int see(Move m) const;
int see(Square to) const;
int see(Square from, Square to) const;
int see(Move m) const;
int see(Square to) const;
+ int see_sign(Move m) const;
// Accessing hash keys
Key get_key() const;
// Accessing hash keys
Key get_key() const;
// Don't search captures and checks with negative SEE values
if ( !isCheck
&& !move_is_promotion(move)
// Don't search captures and checks with negative SEE values
if ( !isCheck
&& !move_is_promotion(move)
- && (pos.midgame_value_of_piece_on(move_from(move)) >
- pos.midgame_value_of_piece_on(move_to(move)))
- && pos.see(move) < 0)
+ && pos.see_sign(move) < 0)
continue;
// Make and search the move.
continue;
// Make and search the move.
if ( pvNode
&& capture
&& pos.type_of_piece_on(move_to(m)) != PAWN
if ( pvNode
&& capture
&& pos.type_of_piece_on(move_to(m)) != PAWN
+ && pos.see_sign(m) >= 0)
{
result += OnePly/2;
*dangerous = true;
{
result += OnePly/2;
*dangerous = true;
&& threat != MOVE_NONE
&& piece_is_slider(pos.piece_on(tfrom))
&& bit_is_set(squares_between(tfrom, tto), mto)
&& threat != MOVE_NONE
&& piece_is_slider(pos.piece_on(tfrom))
&& bit_is_set(squares_between(tfrom, tto), mto)
+ && pos.see_sign(m) >= 0)
return false;
return true;
return false;
return true;