]> git.sesse.net Git - stockfish/commitdiff
Second cleanup wave on check_is_useless()
authorMarco Costalba <mcostalba@gmail.com>
Wed, 15 Dec 2010 08:14:01 +0000 (09:14 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 18 Dec 2010 09:20:15 +0000 (10:20 +0100)
No functional change.

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

index ded3dd172d735ac8a8870305d6b5bddcbab8222e..efac40b328a647414f64bb661da106fe023c59ea 100644 (file)
@@ -521,16 +521,24 @@ Bitboard Position::attacks_from(Piece p, Square s) const {
 
   switch (p)
   {
-  case WP:          return attacks_from<PAWN>(s, WHITE);
-  case BP:          return attacks_from<PAWN>(s, BLACK);
-  case WN: case BN: return attacks_from<KNIGHT>(s);
   case WB: case BB: return attacks_from<BISHOP>(s);
   case WR: case BR: return attacks_from<ROOK>(s);
   case WQ: case BQ: return attacks_from<QUEEN>(s);
-  case WK: case BK: return attacks_from<KING>(s);
-  default: break;
+  default: return StepAttackBB[p][s];
+  }
+}
+
+Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) {
+
+  assert(square_is_ok(s));
+
+  switch (p)
+  {
+  case WB: case BB: return bishop_attacks_bb(s, occ);
+  case WR: case BR: return rook_attacks_bb(s, occ);
+  case WQ: case BQ: return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ);
+  default: return StepAttackBB[p][s];
   }
-  return false;
 }
 
 
index cc70bcf815fbd8c58cf3366f9afca5905f5dd6d3..bb574e1642f263b7b380ac6be6f618b4faa47bb2 100644 (file)
@@ -197,6 +197,7 @@ public:
   // Information about attacks to or from a given square
   Bitboard attackers_to(Square s) const;
   Bitboard attacks_from(Piece p, Square s) const;
+  static Bitboard attacks_from(Piece p, Square s, Bitboard occ);
   template<PieceType> Bitboard attacks_from(Square s) const;
   template<PieceType> Bitboard attacks_from(Square s, Color c) const;
 
index 38e445b343d13440803ddd1de84c5182f63d5e0e..83d052bbeb54c5bb656c053913ab2f8ceb782e65 100644 (file)
@@ -297,8 +297,7 @@ namespace {
   template <NodeType PvNode>
   Depth extension(const Position& pos, Move m, bool captureOrPromotion, bool moveIsCheck, bool singleEvasion, bool mateThreat, bool* dangerous);
 
-  bool check_is_useless(Position &pos, Move move, Value eval, Value futilityBase, Value beta, Value *bValue);
-  Bitboard attacks(const Piece P, const Square sq, const Bitboard occ);
+  bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bValue);
   bool connected_moves(const Position& pos, Move m1, Move m2);
   bool value_is_mate(Value value);
   Value value_to_tt(Value v, int ply);
@@ -1588,12 +1587,17 @@ split_point_start: // At split points actual search starts from here
       // Don't search useless checks
       if (   !PvNode
           && !isCheck
-          && moveIsCheck
-          && move != ttMove
-          && !pos.move_is_capture(move)
-          && !move_is_promotion(move)
-          && check_is_useless(pos, move, ss->eval, futilityBase, beta, &bestValue))
+          &&  moveIsCheck
+          &&  move != ttMove
+          && !pos.move_is_capture_or_promotion(move)
+          &&  ss->eval + PawnValueMidgame / 4 < beta
+          && !check_is_dangerous(pos, move, futilityBase, beta, &bestValue))
+      {
+          if (ss->eval + PawnValueMidgame / 4 > bestValue)
+              bestValue = ss->eval + PawnValueMidgame / 4;
+
           continue;
+      }
 
       // Update current move
       ss->currentMove = move;
@@ -1631,94 +1635,63 @@ split_point_start: // At split points actual search starts from here
     return bestValue;
   }
 
-  // check_is_useless() tests if a checking move can be pruned in qsearch().
-  // bestValue is updated when necesary.
 
-  bool check_is_useless(Position &pos, Move move, Value eval, Value futilityBase, Value beta, Value *bValue)
-  {
-    Value bestValue = *bValue;
+  // check_is_dangerous() tests if a checking move can be pruned in qsearch().
+  // bestValue is updated only when returning false because in that case move
+  // will be pruned.
 
-    /// Rule 1. Using checks to reposition pieces when close to beta
-    if (eval + PawnValueMidgame / 4 < beta)
-    {
-        if (eval + PawnValueMidgame / 4 > bestValue)
-            bestValue = eval + PawnValueMidgame / 4;
-    }
-    else
-        return false;
-
-    Square from = move_from(move);
-    Square to = move_to(move);
-    Color oppColor = opposite_color(pos.side_to_move());
-    Square oppKing = pos.king_square(oppColor);
-
-    Bitboard occ = pos.occupied_squares() & ~(1ULL << from) & ~(1ULL <<oppKing);
-    Bitboard oppOcc = pos.pieces_of_color(oppColor) & ~(1ULL <<oppKing);
-    Bitboard oldAtt = attacks(pos.piece_on(from), from, occ);
-    Bitboard newAtt = attacks(pos.piece_on(from),   to, occ);
-
-    // Rule 2. Checks which give opponent's king at most one escape square are dangerous
-    Bitboard escapeBB = attacks(WK, oppKing, 0) & ~oppOcc & ~newAtt & ~(1ULL << to);
-
-    if (!escapeBB)
-        return false;
-
-    if (!(escapeBB & (escapeBB - 1)))
-        return false;
+  bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bestValue)
+  {
+    Bitboard b, occ, oldAtt, newAtt, kingAtt;
+    Square from, to, ksq, victimSq;
+    Piece pc;
+    Color them;
+    Value futilityValue, bv = *bestValue;
+
+    from = move_from(move);
+    to = move_to(move);
+    them = opposite_color(pos.side_to_move());
+    ksq = pos.king_square(them);
+    kingAtt = pos.attacks_from<KING>(ksq);
+    pc = pos.piece_on(from);
+
+    occ = pos.occupied_squares() & ~(1ULL << from) & ~(1ULL << ksq);
+    oldAtt = pos.attacks_from(pc, from, occ);
+    newAtt = pos.attacks_from(pc,   to, occ);
+
+    // Rule 1. Checks which give opponent's king at most one escape square are dangerous
+    b = kingAtt & ~pos.pieces_of_color(them) & ~newAtt & ~(1ULL << to);
+
+    if (!(b && (b & (b - 1))))
+        return true;
 
-    /// Rule 3. Queen contact check is very dangerous
-    if (   pos.type_of_piece_on(from) == QUEEN
-        && bit_is_set(attacks(WK, oppKing, 0), to))
-        return false;
+    // Rule 2. Queen contact check is very dangerous
+    if (   type_of_piece(pc) == QUEEN
+        && bit_is_set(kingAtt, to))
+        return true;
 
-    /// Rule 4. Creating new double threats with checks
-    Bitboard newVictims = oppOcc & ~oldAtt & newAtt;
+    // Rule 3. Creating new double threats with checks
+    b = pos.pieces_of_color(them) & newAtt & ~oldAtt & ~(1ULL << ksq);
 
-    while(newVictims)
+    while (b)
     {
-        Square victimSq = pop_1st_bit(&newVictims);
-
-        Value futilityValue = futilityBase + pos.endgame_value_of_piece_on(victimSq);
+        victimSq = pop_1st_bit(&b);
+        futilityValue = futilityBase + pos.endgame_value_of_piece_on(victimSq);
 
         // Note that here we generate illegal "double move"!
-        if (futilityValue >= beta && pos.see_sign(make_move(from, victimSq)) >= 0)
-            return false;
+        if (   futilityValue >= beta
+            && pos.see_sign(make_move(from, victimSq)) >= 0)
+            return true;
 
-        if (futilityValue > bestValue)
-            bestValue = futilityValue;
+        if (futilityValue > bv)
+            bv = futilityValue;
     }
 
-    *bValue = bestValue;
-    return true;
+    // Update bestValue only if check is not dangerous (because we will prune the move)
+    *bestValue = bv;
+    return false;
   }
 
-  // attacks() returns attacked squares.
-
-  Bitboard attacks(const Piece P, const Square sq, const Bitboard occ)
-  {
-    switch(P)
-    {
-      case WP:
-      case BP:
-      case WN:
-      case BN:
-      case WK:
-      case BK:
-        return StepAttackBB[P][sq];
-      case WB:
-      case BB:
-        return bishop_attacks_bb(sq, occ);
-      case WR:
-      case BR:
-        return rook_attacks_bb(sq, occ);
-      case WQ:
-      case BQ:
-        return bishop_attacks_bb(sq, occ) | rook_attacks_bb(sq, occ);
-      default:
-        assert(false);
-        return 0ULL;
-    }
-  }
 
   // connected_moves() tests whether two moves are 'connected' in the sense
   // that the first move somehow made the second move possible (for instance