]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Document asymmetric SEE pruning trick
[stockfish] / src / position.cpp
index a51383f0d4eed8c2c9c08d318a6f422c743102a1..1b2defa54662a34718bb46c79e40ae9abffbe595 100644 (file)
@@ -1,7 +1,7 @@
 /*
   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
   Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
-  Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad
+  Copyright (C) 2008-2013 Marco Costalba, Joona Kiiski, Tord Romstad
 
   Stockfish is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include <cassert>
 #include <cstring>
+#include <iomanip>
 #include <iostream>
 #include <sstream>
 #include <algorithm>
@@ -400,7 +401,8 @@ const string Position::pretty(Move move) const {
       if (piece_on(sq) != NO_PIECE)
           brd[513 - 68*rank_of(sq) + 4*file_of(sq)] = PieceToChar[piece_on(sq)];
 
-  ss << brd << "\nFen: " << fen() << "\nKey: " << st->key << "\nCheckers: ";
+  ss << brd << "\nFen: " << fen() << "\nKey: " << std::hex << std::uppercase
+     << std::setfill('0') << std::setw(16) << st->key << "\nCheckers: ";
 
   for (Bitboard b = checkers(); b; )
       ss << square_to_string(pop_lsb(&b)) << " ";
@@ -1146,6 +1148,21 @@ int Position::see_sign(Move m) const {
 }
 
 int Position::see(Move m) const {
+  return do_see<false>(m, 0);
+}
+
+/// Position::see_asymm() takes tempi into account.
+/// If the side who initiated the capturing sequence does the last capture,
+/// he loses a tempo. In this case if the result is below asymmThreshold 
+/// the capturing sequence is considered bad.
+
+int Position::see_asymm(Move m, int asymmThreshold) const
+{
+  return do_see<true>(m, asymmThreshold);
+}
+
+template <bool Asymmetric>
+int Position::do_see(Move m, int asymmThreshold) const {
 
   Square from, to;
   Bitboard occupied, attackers, stmAttackers;
@@ -1222,6 +1239,18 @@ int Position::see(Move m) const {
 
   } while (stmAttackers);
 
+  // If we are doing asymmetric SEE evaluation and the same side does the first
+  // and the last capture, he loses a tempo and gain must be at least worth "asymmThreshold".
+  // If not, we replace the score with a very low value, before negamaxing.
+  if (Asymmetric)
+  {
+      for (int i = 0; i < slIndex ; i += 2)
+      {
+          if (swapList[i] < asymmThreshold)
+               swapList[i] = - QueenValueMg * 16;
+      }
+  }
+
   // Having built the swap list, we negamax through it to find the best
   // achievable score from the point of view of the side to move.
   while (--slIndex)