Shortcut see_sign() when SEE is known negative
authorMarco Costalba <mcostalba@gmail.com>
Fri, 30 Oct 2009 12:34:45 +0000 (13:34 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 1 Nov 2009 20:06:14 +0000 (21:06 +0100)
This patch cuts 30% of SEE calculations, as a drawback
a returned negative value is no more always correct if
a shortcut is found.

This could impact move order when based on negative see
score as example bad captures and evasions.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/evaluate.cpp
src/position.cpp
src/position.h

index fd0ef5b22cd558f9873560edc1e45b93b3e0eef1..82edeec8ac0c43b666ea6df70d728da0989b62b9 100644 (file)
@@ -1171,8 +1171,8 @@ namespace {
     Square b8 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B8 : SQ_G8);
 
     if (   pos.piece_on(b6) == piece_of_color_and_type(opposite_color(us), PAWN)
-        && pos.see(s, b6) < 0
-        && pos.see(s, b8) < 0)
+        && pos.see(s, b6, false) < 0
+        && pos.see(s, b8, false) < 0)
     {
         ei.mgValue -= Sign[us] * TrappedBishopA7H7Penalty;
         ei.egValue -= Sign[us] * TrappedBishopA7H7Penalty;
index 388f91f34172806157a7f44573a6177b7a94193d..b6a8d7465d5911a84b06f52e5e48edfec5e86965 100644 (file)
@@ -1300,13 +1300,13 @@ void Position::undo_null_move() {
 int Position::see(Square to) const {
 
   assert(square_is_ok(to));
-  return see(SQ_NONE, to);
+  return see(SQ_NONE, to, false);
 }
 
 int Position::see(Move m) const {
 
   assert(move_is_ok(m));
-  return see(move_from(m), move_to(m));
+  return see(move_from(m), move_to(m), false);
 }
 
 int Position::see_sign(Move m) const {
@@ -1322,10 +1322,10 @@ int Position::see_sign(Move m) const {
       && type_of_piece_on(from) != KING)
          return 1;
 
-  return see(from, to);
+  return see(from, to, true);
 }
 
-int Position::see(Square from, Square to) const {
+int Position::see(Square from, Square to, bool shortcut) const {
 
   // Material values
   static const int seeValues[18] = {
@@ -1338,6 +1338,7 @@ int Position::see(Square from, Square to) const {
 
   Bitboard attackers, stmAttackers, b;
 
+  assert(!shortcut || from != SQ_NONE);
   assert(square_is_ok(from) || from == SQ_NONE);
   assert(square_is_ok(to));
 
@@ -1350,6 +1351,22 @@ int Position::see(Square from, Square to) const {
   Piece capture = piece_on(to);
   Bitboard occ = occupied_squares();
 
+  // If captured piece is defended by enemy pawns or knights then SEE is negative
+  // when captured piece value is not enough to compensate the lost of capturing one.
+  if (shortcut)
+  {
+      int diff = seeValues[piece] - seeValues[capture];
+
+      if (   diff > seeValues[PAWN]
+          &&(attacks_from<PAWN>(to, us) & pieces(PAWN, them)))
+          return -(diff - seeValues[PAWN] / 2);
+
+      if (   diff > seeValues[KNIGHT]
+          && pieces(KNIGHT, them)
+          &&(pieces(KNIGHT, them) & attacks_from<KNIGHT>(to)))
+          return -(diff - seeValues[KNIGHT] / 2);
+  }
+
   // Handle en passant moves
   if (st->epSquare == to && type_of_piece_on(from) == PAWN)
   {
index f2f517e219445a601f4d90690572cb1a40e1b288..a55d1770fe59d225f550e97b11e75aaabd1c7ced 100644 (file)
@@ -229,7 +229,7 @@ public:
   void undo_null_move();
 
   // Static exchange evaluation
-  int see(Square from, Square to) const;
+  int see(Square from, Square to, bool shortcut) const;
   int see(Move m) const;
   int see(Square to) const;
   int see_sign(Move m) const;