X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=68b19cd34b116bf229e26e9e1dee9c1de7d728aa;hp=239cd3860ab77db1fd4f25c11e81d8250f0a1828;hb=a44f79141eb887f6fbcf06282ff91ed125a70ef4;hpb=4aeffc8c9a7ba870702974f62d1d3553ed227c00 diff --git a/src/search.cpp b/src/search.cpp index 239cd386..68b19cd3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -117,7 +117,7 @@ namespace { struct RootMove { - RootMove() { nodes = cumulativeNodes = ourBeta = theirBeta = 0ULL; } + RootMove() { mp_score = 0; nodes = cumulativeNodes = ourBeta = theirBeta = 0ULL; } // RootMove::operator<() is the comparison function used when // sorting the moves. A move m1 is considered to be better @@ -125,11 +125,12 @@ namespace { // have equal score but m1 has the higher beta cut-off count. bool operator<(const RootMove& m) const { - return score != m.score ? score < m.score : theirBeta <= m.theirBeta; + return score != m.score ? score < m.score : mp_score <= m.mp_score; } Move move; Value score; + int mp_score; int64_t nodes, cumulativeNodes, ourBeta, theirBeta; Move pv[PLY_MAX_PLUS_2]; }; @@ -143,6 +144,8 @@ namespace { public: RootMoveList(Position& pos, Move searchMoves[]); + void set_mp_scores(const Position &pos); + int move_count() const { return count; } Move get_move(int moveNum) const { return moves[moveNum].move; } Value get_move_score(int moveNum) const { return moves[moveNum].score; } @@ -739,6 +742,7 @@ namespace { while (1) { // Sort the moves before to (re)search + rml.set_mp_scores(pos); rml.sort(); // Step 10. Loop through all moves in the root move list @@ -824,7 +828,7 @@ namespace { value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, 1); doFullDepthSearch = (value > alpha); } - ss->reduction = Depth(0); // Restore original reduction + ss->reduction = DEPTH_ZERO; // Restore original reduction } // Step 15. Full depth search @@ -996,7 +1000,7 @@ namespace { // Step 2. Check for aborted search and immediate draw if (AbortSearch || ThreadsMgr.thread_should_stop(threadID)) - return Value(0); + return VALUE_ZERO; if (pos.is_draw() || ply >= PLY_MAX - 1) return VALUE_DRAW; @@ -1067,7 +1071,7 @@ namespace { && !pos.has_pawn_on_7th(pos.side_to_move())) { Value rbeta = beta - razor_margin(depth); - Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply); + Value v = qsearch(pos, ss, rbeta-1, rbeta, DEPTH_ZERO, ply); if (v < rbeta) // Logically we should return (v + razor_margin(depth)), but // surprisingly this did slightly weaker in tests. @@ -1110,7 +1114,7 @@ namespace { pos.do_null_move(st); (ss+1)->skipNullMove = true; - nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, Depth(0), ply+1) + nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1) : - search(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1); (ss+1)->skipNullMove = false; pos.undo_null_move(); @@ -1179,7 +1183,7 @@ namespace { && tte && tte->move() && !excludedMove // Do not allow recursive singular extension search - && is_lower_bound(tte->type()) + && (tte->type() & VALUE_TYPE_LOWER) && tte->depth() >= depth - 3 * ONE_PLY; // Step 10. Loop through moves @@ -1263,7 +1267,7 @@ namespace { // Step extra. pv search (only in PV nodes) // The first move in list is the expected PV if (PvNode && moveCount == 1) - value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, Depth(0), ply+1) + value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1) : - search(pos, ss+1, -beta, -alpha, newDepth, ply+1); else { @@ -1281,7 +1285,7 @@ namespace { if (ss->reduction) { Depth d = newDepth - ss->reduction; - value = d < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, Depth(0), ply+1) + value = d < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1) : - search(pos, ss+1, -(alpha+1), -alpha, d, ply+1); doFullDepthSearch = (value > alpha); @@ -1298,20 +1302,20 @@ namespace { value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, ply+1); doFullDepthSearch = (value > alpha); } - ss->reduction = Depth(0); // Restore original reduction + ss->reduction = DEPTH_ZERO; // Restore original reduction } // Step 15. Full depth search if (doFullDepthSearch) { - value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, Depth(0), ply+1) + value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1) : - search(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1); // Step extra. pv search (only in PV nodes) // Search only for possible new PV nodes, if instead value >= beta then // parent node fails low with value <= alpha and tries another move. if (PvNode && value > alpha && value < beta) - value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, Depth(0), ply+1) + value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1) : - search(pos, ss+1, -beta, -alpha, newDepth, ply+1); } } @@ -1471,7 +1475,7 @@ namespace { // to search the moves. Because the depth is <= 0 here, only captures, // queen promotions and checks (only if depth == 0 or depth == -ONE_PLY // and we are near beta) will be generated. - MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H); + MovePicker mp = MovePicker(pos, ttMove, deepChecks ? DEPTH_ZERO : depth, H); CheckInfo ci(pos); // Loop through the moves until no moves remain or a beta cutoff occurs @@ -1493,7 +1497,7 @@ namespace { { futilityValue = futilityBase + pos.endgame_value_of_piece_on(move_to(move)) - + (move_is_ep(move) ? PawnValueEndgame : Value(0)); + + (move_is_ep(move) ? PawnValueEndgame : VALUE_ZERO); if (futilityValue < alpha) { @@ -1546,7 +1550,7 @@ namespace { return value_mated_in(ply); // Update transposition table - Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1)); + Depth d = (depth == DEPTH_ZERO ? DEPTH_ZERO : DEPTH_ZERO - ONE_PLY); ValueType vt = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT); TT.store(pos.get_key(), value_to_tt(bestValue, ply), vt, d, ss->bestMove, ss->eval, ei.kingDanger[pos.side_to_move()]); @@ -1660,7 +1664,7 @@ namespace { { Value localAlpha = sp->alpha; Depth d = newDepth - ss->reduction; - value = d < ONE_PLY ? -qsearch(pos, ss+1, -(localAlpha+1), -localAlpha, Depth(0), sp->ply+1) + value = d < ONE_PLY ? -qsearch(pos, ss+1, -(localAlpha+1), -localAlpha, DEPTH_ZERO, sp->ply+1) : - search(pos, ss+1, -(localAlpha+1), -localAlpha, d, sp->ply+1); doFullDepthSearch = (value > localAlpha); @@ -1678,21 +1682,21 @@ namespace { value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, sp->ply+1); doFullDepthSearch = (value > localAlpha); } - ss->reduction = Depth(0); // Restore original reduction + ss->reduction = DEPTH_ZERO; // Restore original reduction } // Step 15. Full depth search if (doFullDepthSearch) { Value localAlpha = sp->alpha; - value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -(localAlpha+1), -localAlpha, Depth(0), sp->ply+1) + value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -(localAlpha+1), -localAlpha, DEPTH_ZERO, sp->ply+1) : - search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1); // Step extra. pv search (only in PV nodes) // Search only for possible new PV nodes, if instead value >= beta then // parent node fails low with value <= alpha and tries another move. if (PvNode && value > localAlpha && value < sp->beta) - value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -sp->beta, -sp->alpha, Depth(0), sp->ply+1) + value = newDepth < ONE_PLY ? -qsearch(pos, ss+1, -sp->beta, -sp->alpha, DEPTH_ZERO, sp->ply+1) : - search(pos, ss+1, -sp->beta, -sp->alpha, newDepth, sp->ply+1); } @@ -1851,7 +1855,7 @@ namespace { assert(m != MOVE_NONE); - Depth result = Depth(0); + Depth result = DEPTH_ZERO; *dangerous = moveIsCheck | singleEvasion | mateThreat; if (*dangerous) @@ -1884,7 +1888,7 @@ namespace { if ( captureOrPromotion && pos.type_of_piece_on(move_to(m)) != PAWN && ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) - - pos.midgame_value_of_piece_on(move_to(m)) == Value(0)) + - pos.midgame_value_of_piece_on(move_to(m)) == VALUE_ZERO) && !move_is_promotion(m) && !move_is_ep(m)) { @@ -1957,8 +1961,8 @@ namespace { || v >= Max(value_mate_in(PLY_MAX), beta) || v < Min(value_mated_in(PLY_MAX), beta)) - && ( (is_lower_bound(tte->type()) && v >= beta) - || (is_upper_bound(tte->type()) && v < beta)); + && ( ((tte->type() & VALUE_TYPE_LOWER) && v >= beta) + || ((tte->type() & VALUE_TYPE_UPPER) && v < beta)); } @@ -1971,8 +1975,8 @@ namespace { Value v = value_from_tt(tte->value(), ply); - if ( (is_lower_bound(tte->type()) && v >= defaultEval) - || (is_upper_bound(tte->type()) && v < defaultEval)) + if ( ((tte->type() & VALUE_TYPE_LOWER) && v >= defaultEval) + || ((tte->type() & VALUE_TYPE_UPPER) && v < defaultEval)) return v; return defaultEval; @@ -2165,7 +2169,7 @@ namespace { { ss->excludedMove = MOVE_NONE; ss->skipNullMove = false; - ss->reduction = Depth(0); + ss->reduction = DEPTH_ZERO; if (i < 3) ss->killers[0] = ss->killers[1] = ss->mateKiller = MOVE_NONE; @@ -2603,7 +2607,7 @@ namespace { assert(*bestValue <= *alpha); assert(*alpha < beta); assert(beta <= VALUE_INFINITE); - assert(depth > Depth(0)); + assert(depth > DEPTH_ZERO); assert(p.thread() >= 0 && p.thread() < ActiveThreads); assert(ActiveThreads > 1); @@ -2767,7 +2771,7 @@ namespace { pos.do_move(cur->move, st); ss[0].currentMove = cur->move; moves[count].move = cur->move; - moves[count].score = -qsearch(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1); + moves[count].score = -qsearch(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, DEPTH_ZERO, 1); moves[count].pv[0] = cur->move; moves[count].pv[1] = MOVE_NONE; pos.undo_move(cur->move); @@ -2777,6 +2781,26 @@ namespace { } + void RootMoveList::set_mp_scores(const Position &pos) + { + MovePicker mp = MovePicker(pos, MOVE_NONE, ONE_PLY, H); + Move move; + + int moveCount = 0; + while ((move = mp.get_next_move()) != MOVE_NONE) + { + moveCount++; + for (int i = 0; i < count; i++) + { + if (moves[i].move == move) + { + moves[i].mp_score = 512 - moveCount; + break; + } + } + } + } + // RootMoveList simple methods definitions void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) {