]> git.sesse.net Git - stockfish/blobdiff - src/movegen.cpp
Speed up polynomial material imbalance loop
[stockfish] / src / movegen.cpp
index d4024b1145a36de890f7f9040decf0819124bdcc..eb65e7b9f18977dc1bcb9f730aab1e175ced4d61 100644 (file)
@@ -31,6 +31,9 @@
 // hardcoded list name 'mlist' and from square 'from'.
 #define SERIALIZE_MOVES(b) while (b) (*mlist++).move = make_move(from, pop_1st_bit(&b))
 
+// Version used for pawns, where the 'from' square is given as a delta from the 'to' square
+#define SERIALIZE_MOVES_D(b, d) while (b) { to = pop_1st_bit(&b); (*mlist++).move = make_move(to + (d), to); }
+
 ////
 //// Local definitions
 ////
@@ -564,6 +567,29 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) {
 }
 
 
+/// Another version of move_is_legal(), which takes only a position and a move
+/// as input. This function does not require that the side to move is not in
+/// check. It is not optimized for speed, and is only used for verifying move
+/// legality when building a PV from the transposition table.
+
+bool move_is_legal(const Position& pos, const Move m) {
+
+  Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
+  if (!pos.is_check())
+      return move_is_legal(pos, m, pinned);
+  else
+  {
+      Position p(pos);
+      MoveStack moves[64];
+      int n = generate_evasions(p, moves, pinned);
+      for (int i = 0; i < n; i++)
+          if (moves[i].move == m)
+              return true;
+      return false;
+  }
+}
+
+
 namespace {
 
   template<PieceType Piece>
@@ -638,11 +664,7 @@ namespace {
     }
 
     // Capturing non-promotions
-    while (b1)
-    {
-        to = pop_1st_bit(&b1);
-        (*mlist++).move = make_move(to - TTDELTA_NE, to);
-    }
+    SERIALIZE_MOVES_D(b1, -TTDELTA_NE);
     return mlist;
   }
 
@@ -746,19 +768,11 @@ namespace {
 
     // Single pawn pushes
     b2 = b1 = move_pawns<Us, DELTA_N>(pawns) & emptySquares & ~TRank8BB;
-    while (b2)
-    {
-        to = pop_1st_bit(&b2);
-        (*mlist++).move = make_move(to - TDELTA_N, to);
-    }
+    SERIALIZE_MOVES_D(b2, -TDELTA_N);
 
     // Double pawn pushes
     b2 = move_pawns<Us, DELTA_N>(b1 & TRank3BB) & emptySquares;
-    while (b2)
-    {
-        to = pop_1st_bit(&b2);
-        (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
-    }
+    SERIALIZE_MOVES_D(b2, -TDELTA_N -TDELTA_N);
     return mlist;
   }
 
@@ -773,6 +787,7 @@ namespace {
     const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S);
     const SquareDelta TDELTA_S = (Us == WHITE ? DELTA_S : DELTA_N);
 
+    Square to;
     Bitboard b1, b2, b3;
     Bitboard pawns = pos.pawns(Us);
 
@@ -787,19 +802,11 @@ namespace {
 
         // Discovered checks, single pawn pushes, no promotions
         b2 = b3 = move_pawns<Us, DELTA_N>(b1 & dc) & empty & ~TRank8BB;
-        while (b3)
-        {
-            Square to = pop_1st_bit(&b3);
-            (*mlist++).move = make_move(to - TDELTA_N, to);
-        }
+        SERIALIZE_MOVES_D(b3, -TDELTA_N);
 
         // Discovered checks, double pawn pushes
         b3 = move_pawns<Us, DELTA_N>(b2 & TRank3BB) & empty;
-        while (b3)
-        {
-            Square to = pop_1st_bit(&b3);
-            (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
-        }
+        SERIALIZE_MOVES_D(b3, -TDELTA_N -TDELTA_N);
     }
 
     // Direct checks. These are possible only for pawns on neighboring files
@@ -816,19 +823,11 @@ namespace {
     Bitboard empty = pos.empty_squares();
     b2 = move_pawns<Us, DELTA_N>(b1) & empty;
     b3 = b2 & pos.pawn_attacks(Them, ksq);
-    while (b3)
-    {
-        Square to = pop_1st_bit(&b3);
-        (*mlist++).move = make_move(to - TDELTA_N, to);
-    }
+    SERIALIZE_MOVES_D(b3, -TDELTA_N);
 
     // Direct checks, double pawn pushes
     b3 =  move_pawns<Us, DELTA_N>(b2 & TRank3BB) & empty & pos.pawn_attacks(Them, ksq);
-    while (b3)
-    {
-        Square to = pop_1st_bit(&b3);
-        (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
-    }
+    SERIALIZE_MOVES_D(b3, -TDELTA_N -TDELTA_N);
     return mlist;
   }