diff --git a/src/movepick.cpp b/src/movepick.cpp index c8738c568..0360c2bde 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -19,8 +19,8 @@ #include "movepick.h" #include -#include #include +#include #include "bitboard.h" #include "misc.h" @@ -223,6 +223,7 @@ top: case QSEARCH_TT : case PROBCUT_TT : ++stage; + cur = moves + 1; return ttMove; case CAPTURE_INIT : @@ -238,9 +239,12 @@ top: case GOOD_CAPTURE : if (select([&]() { - // Move losing capture to endBadCaptures to be tried later - return pos.see_ge(*cur, -cur->value / 18) ? true - : (*endBadCaptures++ = *cur, false); + if (!pos.see_ge(*cur, -cur->value / 18)) + { + std::swap(*endBadCaptures++, *cur); + return false; + } + return true; })) return *(cur - 1); @@ -250,7 +254,6 @@ top: case QUIET_INIT : if (!skipQuiets) { - cur = endBadCaptures; endMoves = beginBadQuiets = endBadQuiets = generate(pos, cur); score(); @@ -317,30 +320,23 @@ top: void MovePicker::skip_quiet_moves() { skipQuiets = true; } -bool MovePicker::otherPieceTypesMobile(PieceType pt, ValueList& capturesSearched) { - if (stage != GOOD_QUIET && stage != BAD_QUIET) - return true; +bool MovePicker::other_piece_types_mobile(PieceType pt) { + assert(stage == GOOD_QUIET || stage == BAD_QUIET || stage == EVASION); - // verify good captures - for (std::size_t i = 0; i < capturesSearched.size(); i++) - if (type_of(pos.moved_piece(capturesSearched[i])) != pt) + // verify all generated captures and quiets + for (ExtMove* m = moves; m < endMoves; ++m) + { + if (*m && type_of(pos.moved_piece(*m)) != pt) { - if (type_of(pos.moved_piece(capturesSearched[i])) != KING) + if (type_of(pos.moved_piece(*m)) != KING) return true; - if (pos.legal(capturesSearched[i])) - return true; - } - - // now verify bad captures and quiets - for (ExtMove* c = moves; c < endBadQuiets; ++c) - if (type_of(pos.moved_piece(*c)) != pt) - { - if (type_of(pos.moved_piece(*c)) != KING) - return true; - if (pos.legal(*c)) + if (pos.legal(*m)) return true; } + } return false; } +void MovePicker::mark_current_illegal() { *(cur - 1) = Move::none(); } + } // namespace Stockfish diff --git a/src/movepick.h b/src/movepick.h index dfafe69a5..72a6f4e1c 100644 --- a/src/movepick.h +++ b/src/movepick.h @@ -19,8 +19,6 @@ #ifndef MOVEPICK_H_INCLUDED #define MOVEPICK_H_INCLUDED -#include - #include "history.h" #include "movegen.h" #include "types.h" @@ -29,9 +27,6 @@ namespace Stockfish { class Position; -template -class ValueList; - // The MovePicker class is used to pick one pseudo-legal move at a time from the // current position. The most important method is next_move(), which emits one // new pseudo-legal move on every call, until there are no moves left, when @@ -55,7 +50,8 @@ class MovePicker { MovePicker(const Position&, Move, int, const CapturePieceToHistory*); Move next_move(); void skip_quiet_moves(); - bool otherPieceTypesMobile(PieceType pt, ValueList& capturesSearched); + bool other_piece_types_mobile(PieceType pt); + void mark_current_illegal(); private: template diff --git a/src/search.cpp b/src/search.cpp index f673ba340..05d522b19 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1011,8 +1011,10 @@ moves_loop: // When in check, search starts here // Check for legality if (!pos.legal(move)) + { + mp.mark_current_illegal(); continue; - + } // At root obey the "searchmoves" option and skip moves not listed in Root // Move List. In MultiPV mode we also skip PV moves that have been already // searched and those of lower "TB rank" if we are in a TB root position. @@ -1084,9 +1086,8 @@ moves_loop: // When in check, search starts here && pos.non_pawn_material(us) == PieceValue[movedPiece] && PieceValue[movedPiece] >= RookValue && !(PseudoAttacks[KING][pos.square(us)] & move.from_sq())) - skip = mp.otherPieceTypesMobile( - type_of(movedPiece), - capturesSearched); // if the opponent captures last mobile piece it might be stalemate + // if the opponent captures last mobile piece it might be stalemate + skip = mp.other_piece_types_mobile(type_of(movedPiece)); if (skip) continue;