Use CheckInfo to generate checks
authorMarco Costalba <mcostalba@gmail.com>
Sun, 8 Jan 2012 14:08:20 +0000 (15:08 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 8 Jan 2012 15:09:18 +0000 (16:09 +0100)
It should help to avoid recalculating check squares
of sliding attackers for queen when already done for
bishops and rooks. Of course this helps when there are
bishop, rook and queen on the board !

Fixed also a subtle bug (use of same variable b in while
condition and in condition body) introduced recently by
revision d655147e8c that triggers
in case we have at least 2 non-pawn discovered check pieces.
This is very rare that's why didn't show in the node count
verification where we actually have a case of 2 dc pieces
in position 14, but one is a pawn.

No functional change.

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

index 1820fee2fbcb2af58aeeacae07db46df9e126efb..865f9a8229ad947477324ddedb5eed3b6c3dd2df 100644 (file)
@@ -247,8 +247,8 @@ namespace {
 
 
   template<PieceType Pt>
-  inline MoveStack* generate_direct_checks(const Position& pos, MoveStack* mlist, Color us,
-                                           Bitboard dc, Square ksq) {
+  inline MoveStack* generate_direct_checks(const Position& pos, MoveStack* mlist,
+                                           Color us, const CheckInfo& ci) {
     assert(Pt != KING && Pt != PAWN);
 
     Bitboard checkSqs, b;
@@ -258,7 +258,7 @@ namespace {
     if ((from = *pl++) == SQ_NONE)
         return mlist;
 
-    checkSqs = pos.attacks_from<Pt>(ksq) & pos.empty_squares();
+    checkSqs = ci.checkSq[Pt] & pos.empty_squares();
 
     do
     {
@@ -267,7 +267,7 @@ namespace {
             || (Pt == BISHOP && !(BishopPseudoAttacks[from] & checkSqs)))
             continue;
 
-        if (dc && bit_is_set(dc, from))
+        if (ci.dcCandidates && bit_is_set(ci.dcCandidates, from))
             continue;
 
         b = pos.attacks_from<Pt>(from) & checkSqs;
@@ -280,10 +280,11 @@ namespace {
 
 
   template<>
-  FORCE_INLINE MoveStack* generate_direct_checks<PAWN>(const Position& p, MoveStack* m, Color us, Bitboard dc, Square ksq) {
+  FORCE_INLINE MoveStack* generate_direct_checks<PAWN>(const Position& p, MoveStack* m,
+                                                       Color us, const CheckInfo& ci) {
 
-    return us == WHITE ? generate_pawn_moves<WHITE, MV_NON_CAPTURE_CHECK>(p, m, dc, ksq)
-                       : generate_pawn_moves<BLACK, MV_NON_CAPTURE_CHECK>(p, m, dc, ksq);
+    return us == WHITE ? generate_pawn_moves<WHITE, MV_NON_CAPTURE_CHECK>(p, m, ci.dcCandidates, ci.ksq)
+                       : generate_pawn_moves<BLACK, MV_NON_CAPTURE_CHECK>(p, m, ci.dcCandidates, ci.ksq);
   }
 
 
@@ -383,37 +384,31 @@ MoveStack* generate<MV_NON_CAPTURE_CHECK>(const Position& pos, MoveStack* mlist)
 
   assert(!pos.in_check());
 
-  Bitboard b, dc;
-  Square from;
-  PieceType pt;
   Color us = pos.side_to_move();
-  Square ksq = pos.king_square(flip(us));
+  CheckInfo ci(pos);
+  Bitboard dc = ci.dcCandidates;
 
-  assert(pos.piece_on(ksq) == make_piece(flip(us), KING));
-
-  b = dc = pos.discovered_check_candidates();
-
-  while (b)
+  while (dc)
   {
-     from = pop_1st_bit(&b);
-     pt = type_of(pos.piece_on(from));
+     Square from = pop_1st_bit(&dc);
+     PieceType pt = type_of(pos.piece_on(from));
 
      if (pt == PAWN)
          continue; // Will be generated togheter with direct checks
 
-     b = pos.attacks_from(Piece(pt), from) & pos.empty_squares();
+     Bitboard b = pos.attacks_from(Piece(pt), from) & pos.empty_squares();
 
      if (pt == KING)
-         b &= ~QueenPseudoAttacks[ksq];
+         b &= ~QueenPseudoAttacks[ci.ksq];
 
      SERIALIZE(b);
   }
 
-  mlist = generate_direct_checks<PAWN>(pos, mlist, us, dc, ksq);
-  mlist = generate_direct_checks<KNIGHT>(pos, mlist, us, dc, ksq);
-  mlist = generate_direct_checks<BISHOP>(pos, mlist, us, dc, ksq);
-  mlist = generate_direct_checks<ROOK>(pos, mlist, us, dc, ksq);
-  mlist = generate_direct_checks<QUEEN>(pos, mlist, us, dc, ksq);
+  mlist = generate_direct_checks<PAWN>(pos, mlist, us, ci);
+  mlist = generate_direct_checks<KNIGHT>(pos, mlist, us, ci);
+  mlist = generate_direct_checks<BISHOP>(pos, mlist, us, ci);
+  mlist = generate_direct_checks<ROOK>(pos, mlist, us, ci);
+  mlist = generate_direct_checks<QUEEN>(pos, mlist, us, ci);
 
   if (pos.can_castle(us))
   {
index 98f49c756fe989cee80a1d553889e84dd476aa7c..1c9663000e011af6df038d459a1bdb96337a25fa 100644 (file)
@@ -79,7 +79,7 @@ namespace {
 CheckInfo::CheckInfo(const Position& pos) {
 
   Color them = flip(pos.side_to_move());
-  Square ksq = pos.king_square(them);
+  ksq = pos.king_square(them);
 
   pinned = pos.pinned_pieces();
   dcCandidates = pos.discovered_check_candidates();
index 36d8869598292e87b158c96e4c4d4a93dc3d2690..4583212c5eaa4384aa3311fca345fd34ed58c1da 100644 (file)
@@ -37,6 +37,7 @@ struct CheckInfo {
   Bitboard dcCandidates;
   Bitboard pinned;
   Bitboard checkSq[8];
+  Square ksq;
 };