From: Marco Costalba Date: Mon, 9 Aug 2010 10:45:02 +0000 (+0100) Subject: Cleanup and optimize Position::has_mate_threat() X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=252537fd9c8cb60f765ea390d2464a42adeafc0a;ds=sidebyside Cleanup and optimize Position::has_mate_threat() There is a functional change because we now skip more moves and because do_move() / undo_move() is well known to be not reversible we end up with a change in node count, although there is actually no change but a bit speed up. Signed-off-by: Marco Costalba --- diff --git a/src/position.cpp b/src/position.cpp index 35e26276..c8132d5e 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1733,82 +1733,79 @@ bool Position::is_draw() const { bool Position::is_mate() const { MoveStack moves[256]; - return is_check() && (generate_moves(*this, moves, false) == moves); + return is_check() && (generate_moves(*this, moves) == moves); } -/// Position::has_mate_threat() tests whether a given color has a mate in one -/// from the current position. +/// Position::has_mate_threat() tests whether the side to move is under +/// a threat of being mated in one from the current position. -bool Position::has_mate_threat(Color c) { +bool Position::has_mate_threat() { + MoveStack mlist[256], *last, *cur; StateInfo st1, st2; - Color stm = side_to_move(); + bool mateFound = false; + // If we are under check it's up to evasions to do the job if (is_check()) return false; - // If the input color is not equal to the side to move, do a null move - if (c != stm) - do_null_move(st1); + // First pass the move to our opponent doing a null move + do_null_move(st1); - MoveStack mlist[120]; - bool result = false; - Bitboard pinned = pinned_pieces(sideToMove); - - // Generate pseudo-legal non-capture and capture check moves - MoveStack* last = generate_non_capture_checks(*this, mlist); + // Then generate pseudo-legal moves that give check + last = generate_non_capture_checks(*this, mlist); last = generate_captures(*this, last); - // Loop through the moves, and see if one of them is mate - for (MoveStack* cur = mlist; cur != last; cur++) + // Loop through the moves, and see if one of them gives mate + Bitboard pinned = pinned_pieces(sideToMove); + CheckInfo ci(*this); + for (cur = mlist; cur != last && !mateFound; cur++) { Move move = cur->move; - if (!pl_move_is_legal(move, pinned)) + if ( !pl_move_is_legal(move, pinned) + || !move_is_check(move, ci)) continue; - do_move(move, st2); + do_move(move, st2, ci, true); + if (is_mate()) - result = true; + mateFound = true; undo_move(move); } - // Undo null move, if necessary - if (c != stm) - undo_null_move(); - - return result; + undo_null_move(); + return mateFound; } -/// Position::init_zobrist() is a static member function which initializes the -/// various arrays used to compute hash keys. +/// Position::init_zobrist() is a static member function which initializes at +/// startup the various arrays used to compute hash keys. void Position::init_zobrist() { - for (int i = 0; i < 2; i++) - for (int j = 0; j < 8; j++) - for (int k = 0; k < 64; k++) - zobrist[i][j][k] = Key(genrand_int64()); + int i,j, k; - for (int i = 0; i < 64; i++) + for (i = 0; i < 2; i++) for (j = 0; j < 8; j++) for (k = 0; k < 64; k++) + zobrist[i][j][k] = Key(genrand_int64()); + + for (i = 0; i < 64; i++) zobEp[i] = Key(genrand_int64()); - for (int i = 0; i < 16; i++) - zobCastle[i] = genrand_int64(); + for (i = 0; i < 16; i++) + zobCastle[i] = Key(genrand_int64()); - zobSideToMove = genrand_int64(); - zobExclusion = genrand_int64(); + zobSideToMove = Key(genrand_int64()); + zobExclusion = Key(genrand_int64()); } /// Position::init_piece_square_tables() initializes the piece square tables. -/// This is a two-step operation: -/// First, the white halves of the tables are -/// copied from the MgPST[][] and EgPST[][] arrays. -/// Second, the black halves of the tables are initialized by mirroring -/// and changing the sign of the corresponding white scores. +/// This is a two-step operation: First, the white halves of the tables are +/// copied from the MgPST[][] and EgPST[][] arrays. Second, the black halves +/// of the tables are initialized by mirroring and changing the sign of the +/// corresponding white scores. void Position::init_piece_square_tables() { diff --git a/src/position.h b/src/position.h index e921b350..6d7ea0ef 100644 --- a/src/position.h +++ b/src/position.h @@ -264,8 +264,8 @@ public: bool is_mate() const; bool is_draw() const; - // Check if one side threatens a mate in one - bool has_mate_threat(Color c); + // Check if side to move could be mated in one + bool has_mate_threat(); // Number of plies since the last non-reversible move int rule_50_counter() const; diff --git a/src/search.cpp b/src/search.cpp index 97ed340d..65289328 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1168,7 +1168,7 @@ namespace { // Expensive mate threat detection (only for PV nodes) if (PvNode) - mateThreat = pos.has_mate_threat(opposite_color(pos.side_to_move())); + mateThreat = pos.has_mate_threat(); // Initialize a MovePicker object for the current position MovePicker mp = MovePicker(pos, ttMove, depth, H, ss, (PvNode ? -VALUE_INFINITE : beta));