From: Marco Costalba Date: Wed, 15 Dec 2010 08:14:01 +0000 (+0100) Subject: Second cleanup wave on check_is_useless() X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=201e8d5f87a2bbd2d199b744cf8e92213c1e4bc4 Second cleanup wave on check_is_useless() No functional change. Signed-off-by: Marco Costalba --- diff --git a/src/position.cpp b/src/position.cpp index ded3dd17..efac40b3 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -521,16 +521,24 @@ Bitboard Position::attacks_from(Piece p, Square s) const { switch (p) { - case WP: return attacks_from(s, WHITE); - case BP: return attacks_from(s, BLACK); - case WN: case BN: return attacks_from(s); case WB: case BB: return attacks_from(s); case WR: case BR: return attacks_from(s); case WQ: case BQ: return attacks_from(s); - case WK: case BK: return attacks_from(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; } diff --git a/src/position.h b/src/position.h index cc70bcf8..bb574e16 100644 --- a/src/position.h +++ b/src/position.h @@ -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 Bitboard attacks_from(Square s) const; template Bitboard attacks_from(Square s, Color c) const; diff --git a/src/search.cpp b/src/search.cpp index 38e445b3..83d052bb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -297,8 +297,7 @@ namespace { template 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 <(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