X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fmovepick.cpp;h=eb686f7938837d23acb86e0812ea52e1f442d72d;hp=ee747c94525cdee18b9f78ea585abd3854cd23e8;hb=5a0581498cde3d0904924d8ef7ed25ea1a2c855a;hpb=8a0dd93c56f63de467190145116ed6c5cfd54bc1 diff --git a/src/movepick.cpp b/src/movepick.cpp index ee747c94..eb686f79 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -66,7 +66,7 @@ namespace { /// move ordering is at the current node. MovePicker::MovePicker(const Position& p, bool pv, Move ttm, - const SearchStack& ss, Depth d, EvalInfo* ei) : pos(p) { + const SearchStack& ss, Depth d) : pos(p) { pvNode = pv; ttMove = ttm; mateKiller = (ss.mateKiller == ttm)? MOVE_NONE : ss.mateKiller; @@ -81,23 +81,18 @@ MovePicker::MovePicker(const Position& p, bool pv, Move ttm, // generating them. So avoid generating in case we know are zero. Color us = pos.side_to_move(); Color them = opposite_color(us); - bool noCaptures = ei - && (ei->attackedBy[us][0] & pos.pieces_of_color(them)) == 0 - && !ei->mi->specialized_eval_exists() - && (pos.ep_square() == SQ_NONE) - && !pos.has_pawn_on_7th(us); if (p.is_check()) phaseIndex = EvasionsPhaseIndex; else if (depth > Depth(0)) phaseIndex = MainSearchPhaseIndex; else if (depth == Depth(0)) - phaseIndex = (noCaptures ? QsearchNoCapturesPhaseIndex : QsearchWithChecksPhaseIndex); + phaseIndex = QsearchWithChecksPhaseIndex; else - phaseIndex = (noCaptures ? NoMovesPhaseIndex : QsearchWithoutChecksPhaseIndex); + phaseIndex = QsearchWithoutChecksPhaseIndex; dc = p.discovered_check_candidates(us); - pinned = p.pinned_pieces(p.side_to_move()); + pinned = p.pinned_pieces(us); finished = false; } @@ -141,8 +136,8 @@ Move MovePicker::get_next_move() { assert(move_is_ok(mateKiller)); if (move_is_legal(pos, mateKiller, pinned)) return mateKiller; - } - break; + } + break; case PH_GOOD_CAPTURES: numOfMoves = generate_captures(pos, moves); @@ -151,7 +146,7 @@ Move MovePicker::get_next_move() { break; case PH_BAD_CAPTURES: - badCapturesPicked = 0; + movesPicked = 0; break; case PH_NONCAPTURES: @@ -162,7 +157,7 @@ Move MovePicker::get_next_move() { case PH_EVASIONS: assert(pos.is_check()); - numOfMoves = generate_evasions(pos, moves); + numOfMoves = generate_evasions(pos, moves, pinned); score_evasions(); movesPicked = 0; break; @@ -270,10 +265,11 @@ void MovePicker::score_noncaptures() { else hs = H.move_ordering_score(pos.piece_on(move_from(m)), m); - // Ensure moves in history are always sorted as first + // Ensure history is always preferred to pst if (hs > 0) hs += 1000; + // pst based scoring moves[i].score = hs + pos.mg_pst_delta(m); } } @@ -309,17 +305,19 @@ void MovePicker::score_qcaptures() { } -/// find_best_index() loops across the moves and returns index of -/// the highest scored one. There is also a second version that -/// lowers the priority of moves that attack the same square, -/// so that if the best move that attack a square fails the next +/// find_best_index() loops across the moves and returns index of +/// the highest scored one. There is also a second version that +/// lowers the priority of moves that attack the same square, +/// so that if the best move that attack a square fails the next /// move picked attacks a different square if any, not the same one. int MovePicker::find_best_index() { - int bestScore = -10000000, bestIndex = -1; + assert(movesPicked < numOfMoves); - for (int i = movesPicked; i < numOfMoves; i++) + int bestIndex = movesPicked, bestScore = moves[movesPicked].score; + + for (int i = movesPicked + 1; i < numOfMoves; i++) if (moves[i].score > bestScore) { bestIndex = i; @@ -328,41 +326,43 @@ int MovePicker::find_best_index() { return bestIndex; } -int MovePicker::find_best_index(Bitboard* squares, int values[]) { - - int hs; - Move m; - Square to; - int bestScore = -10000000, bestIndex = -1; - - for (int i = movesPicked; i < numOfMoves; i++) - { - m = moves[i].move; - to = move_to(m); - - if (!bit_is_set(*squares, to)) - { - // Init at first use - set_bit(squares, to); - values[to] = 0; - } - - hs = moves[i].score - values[to]; - if (hs > bestScore) - { - bestIndex = i; - bestScore = hs; - } - } - - if (bestIndex != -1) - { - // Raise value of the picked square, so next attack - // to the same square will get low priority. - to = move_to(moves[bestIndex].move); - values[to] += 0xB00; - } - return bestIndex; +int MovePicker::find_best_index(Bitboard* squares, int values[]) { + + assert(movesPicked < numOfMoves); + + int hs; + Move m; + Square to; + int bestScore = -10000000, bestIndex = -1; + + for (int i = movesPicked; i < numOfMoves; i++) + { + m = moves[i].move; + to = move_to(m); + + if (!bit_is_set(*squares, to)) + { + // Init at first use + set_bit(squares, to); + values[to] = 0; + } + + hs = moves[i].score - values[to]; + if (hs > bestScore) + { + bestIndex = i; + bestScore = hs; + } + } + + if (bestIndex != -1) + { + // Raise value of the picked square, so next attack + // to the same square will get low priority. + to = move_to(moves[bestIndex].move); + values[to] += 0xB00; + } + return bestIndex; } @@ -377,6 +377,7 @@ Move MovePicker::pick_move_from_list() { Move move; switch (PhaseTable[phaseIndex]) { + case PH_GOOD_CAPTURES: assert(!pos.is_check()); assert(movesPicked >= 0); @@ -384,16 +385,12 @@ Move MovePicker::pick_move_from_list() { while (movesPicked < numOfMoves) { bestIndex = find_best_index(); - - if (bestIndex != -1) // Found a good capture - { - move = moves[bestIndex].move; - moves[bestIndex] = moves[movesPicked++]; - if ( move != ttMove - && move != mateKiller - && pos.pl_move_is_legal(move, pinned)) - return move; - } + move = moves[bestIndex].move; + moves[bestIndex] = moves[movesPicked++]; + if ( move != ttMove + && move != mateKiller + && pos.pl_move_is_legal(move, pinned)) + return move; } break; @@ -408,16 +405,12 @@ Move MovePicker::pick_move_from_list() { // been searched and it is not a PV node, we are probably failing low // anyway, so we just pick the first move from the list. bestIndex = (pvNode || movesPicked < 12) ? find_best_index() : movesPicked; - - if (bestIndex != -1) - { - move = moves[bestIndex].move; - moves[bestIndex] = moves[movesPicked++]; - if ( move != ttMove - && move != mateKiller - && pos.pl_move_is_legal(move, pinned)) - return move; - } + move = moves[bestIndex].move; + moves[bestIndex] = moves[movesPicked++]; + if ( move != ttMove + && move != mateKiller + && pos.pl_move_is_legal(move, pinned)) + return move; } break; @@ -428,24 +421,20 @@ Move MovePicker::pick_move_from_list() { while (movesPicked < numOfMoves) { bestIndex = find_best_index(); - - if (bestIndex != -1) - { - move = moves[bestIndex].move; - moves[bestIndex] = moves[movesPicked++]; - return move; - } + move = moves[bestIndex].move; + moves[bestIndex] = moves[movesPicked++]; + return move; } break; case PH_BAD_CAPTURES: assert(!pos.is_check()); - assert(badCapturesPicked >= 0); + assert(movesPicked >= 0); // It's probably a good idea to use SEE move ordering here, instead // of just picking the first move. FIXME - while (badCapturesPicked < numOfBadCaptures) + while (movesPicked < numOfBadCaptures) { - move = badCaptures[badCapturesPicked++].move; + move = badCaptures[movesPicked++].move; if ( move != ttMove && move != mateKiller && pos.pl_move_is_legal(move, pinned)) @@ -459,16 +448,12 @@ Move MovePicker::pick_move_from_list() { while (movesPicked < numOfMoves) { bestIndex = (movesPicked < 4 ? find_best_index() : movesPicked); - - if (bestIndex != -1) - { - move = moves[bestIndex].move; - moves[bestIndex] = moves[movesPicked++]; - // Remember to change the line below if we decide to hash the qsearch! - // Maybe also postpone the legality check until after futility pruning? - if (/* move != ttMove && */ pos.pl_move_is_legal(move, pinned)) - return move; - } + move = moves[bestIndex].move; + moves[bestIndex] = moves[movesPicked++]; + // Remember to change the line below if we decide to hash the qsearch! + // Maybe also postpone the legality check until after futility pruning? + if (/* move != ttMove && */ pos.pl_move_is_legal(move, pinned)) + return move; } break;