Fully correct stealmate detection
authorMarco Costalba <mcostalba@gmail.com>
Sat, 3 May 2014 10:09:56 +0000 (12:09 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 3 May 2014 10:12:22 +0000 (12:12 +0200)
In the (rare) cases when the two conditions
are true, then fully check again with a slow
but correct MoveList<LEGAL>(pos).size().

This is able to detect false positives like
this one:

8/8/8/Q7/5k1p/5P2/4KP2/8 b - - 0 17

When we have a possible simple pawn push that
is not stored in attacks[] array. Because the
third condition triggers very rarely, even if
it is slow, it does not alters in a measurable
way the average speed of the engine.

bench: 8678654

src/evaluate.cpp

index 29d71ea9e0cce28078ccf4a715521d85b3f6bbac..34a87771aea96a120e14f5858ffebd510f73d60f 100644 (file)
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <algorithm>
 #include <cassert>
 #include <iomanip>
 #include <sstream>
-#include <algorithm>
 
 #include "bitcount.h"
 #include "evaluate.h"
@@ -790,7 +790,8 @@ namespace {
     // Stealmate detection
     Color stm = pos.side_to_move();
     if (   (ei.attackedBy[stm][ALL_PIECES] == ei.attackedBy[stm][KING])
-        && (!(ei.attackedBy[stm][KING] & ~ei.attackedBy[~stm][ALL_PIECES])))
+        && (!(ei.attackedBy[stm][KING] & ~ei.attackedBy[~stm][ALL_PIECES]))
+        && !MoveList<LEGAL>(pos).size())
         sf = SCALE_FACTOR_DRAW;
 
     // Interpolate between a middlegame and a (scaled by 'sf') endgame score