X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsearch.cpp;h=189e11d0fe9991231393ebece1d657774f0520b1;hb=fb4b4f772e270033560e429a694376caa03a3f52;hp=f976908ec31b0e5b2a9f9d36235b365461a3d9e7;hpb=24417a6cd9577e8574eadc26765e366888cc9b1e;p=stockfish diff --git a/src/search.cpp b/src/search.cpp index f976908e..189e11d0 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1,7 +1,7 @@ /* Stockfish, a UCI chess playing engine derived from Glaurung 2.1 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) - Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad + Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad Stockfish is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -67,7 +67,6 @@ namespace { RootMove(){} RootMove(Move m) { - nodes = 0; score = prevScore = -VALUE_INFINITE; pv.push_back(m); pv.push_back(MOVE_NONE); @@ -79,7 +78,6 @@ namespace { void extract_pv_from_tt(Position& pos); void insert_pv_in_tt(Position& pos); - int64_t nodes; Value score; Value prevScore; std::vector pv; @@ -254,22 +252,22 @@ void Search::init() { int64_t Search::perft(Position& pos, Depth depth) { StateInfo st; - int64_t sum = 0; + int64_t cnt = 0; MoveList ml(pos); // At the last ply just return the number of moves (leaf nodes) - if (depth <= ONE_PLY) + if (depth == ONE_PLY) return ml.size(); CheckInfo ci(pos); for ( ; !ml.end(); ++ml) { pos.do_move(ml.move(), st, ci, pos.move_gives_check(ml.move(), ci)); - sum += perft(pos, depth - ONE_PLY); + cnt += perft(pos, depth - ONE_PLY); pos.undo_move(ml.move()); } - return sum; + return cnt; } @@ -296,12 +294,12 @@ void Search::think() { || count(SearchMoves.begin(), SearchMoves.end(), ml.move())) RootMoves.push_back(RootMove(ml.move())); - if (Options["OwnBook"].value()) + if (Options["OwnBook"]) { - if (Options["Book File"].value() != book.name()) - book.open(Options["Book File"].value()); + if (book.name() != (string)Options["Book File"]) + book.open(Options["Book File"]); - Move bookMove = book.probe(pos, Options["Best Book Move"].value()); + Move bookMove = book.probe(pos, Options["Best Book Move"]); if ( bookMove != MOVE_NONE && count(RootMoves.begin(), RootMoves.end(), bookMove)) @@ -315,24 +313,24 @@ void Search::think() { read_evaluation_uci_options(pos.side_to_move()); Threads.read_uci_options(); - TT.set_size(Options["Hash"].value()); - if (Options["Clear Hash"].value()) + TT.set_size(Options["Hash"]); + if (Options["Clear Hash"]) { Options["Clear Hash"] = false; TT.clear(); } - UCIMultiPV = Options["MultiPV"].value(); - SkillLevel = Options["Skill Level"].value(); + UCIMultiPV = Options["MultiPV"]; + SkillLevel = Options["Skill Level"]; // Do we have to play with skill handicap? In this case enable MultiPV that // we will use behind the scenes to retrieve a set of possible moves. SkillLevelEnabled = (SkillLevel < 20); MultiPV = (SkillLevelEnabled ? std::max(UCIMultiPV, (size_t)4) : UCIMultiPV); - if (Options["Use Search Log"].value()) + if (Options["Use Search Log"]) { - Log log(Options["Search Log Filename"].value()); + Log log(Options["Search Log Filename"]); log << "\nSearching: " << pos.to_fen() << "\ninfinite: " << Limits.infinite << " ponder: " << Limits.ponder @@ -362,11 +360,11 @@ void Search::think() { Threads.set_timer(0); Threads.set_size(1); - if (Options["Use Search Log"].value()) + if (Options["Use Search Log"]) { int e = elapsed_time(); - Log log(Options["Search Log Filename"].value()); + Log log(Options["Search Log Filename"]); log << "Nodes: " << pos.nodes_searched() << "\nNodes/second: " << (e > 0 ? pos.nodes_searched() * 1000 / e : 0) << "\nBest move: " << move_to_san(pos, RootMoves[0].pv[0]); @@ -399,7 +397,7 @@ namespace { void id_loop(Position& pos) { - Stack ss[PLY_MAX_PLUS_2]; + Stack ss[MAX_PLY_PLUS_2]; int depth, prevBestMoveChanges; Value bestValue, alpha, beta, delta; bool bestMoveNeverChanged = true; @@ -410,10 +408,10 @@ namespace { bestValue = delta = -VALUE_INFINITE; ss->currentMove = MOVE_NULL; // Hack to skip update gains - // Handle the special case of a mate/stalemate position + // Handle the special case of a mated/stalemate position if (RootMoves.empty()) { - cout << "info depth 0" + cout << "info depth 0 score " << score_to_uci(pos.in_check() ? -VALUE_MATE : VALUE_DRAW) << endl; RootMoves.push_back(MOVE_NONE); @@ -421,7 +419,7 @@ namespace { } // Iterative deepening loop until requested to stop or target depth reached - while (!Signals.stop && ++depth <= PLY_MAX && (!Limits.maxDepth || depth <= Limits.maxDepth)) + while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.maxDepth || depth <= Limits.maxDepth)) { // Save last iteration's scores before first PV line is searched and all // the move scores but the (new) PV are set to -VALUE_INFINITE. @@ -512,7 +510,7 @@ namespace { if (SkillLevelEnabled && depth == 1 + SkillLevel) skillBest = do_skill_level(); - if (Options["Use Search Log"].value()) + if (Options["Use Search Log"]) pv_info_to_log(pos, depth, bestValue, elapsed_time(), &RootMoves[0].pv[0]); // Filter out startup noise when monitoring best move stability @@ -594,7 +592,6 @@ namespace { assert(pos.thread() >= 0 && pos.thread() < Threads.size()); Move movesSearched[MAX_MOVES]; - int64_t nodes; StateInfo st; const TTEntry *tte; Key posKey; @@ -637,7 +634,7 @@ namespace { // Step 2. Check for aborted search and immediate draw if (( Signals.stop || pos.is_draw() - || ss->ply > PLY_MAX) && !RootNode) + || ss->ply > MAX_PLY) && !RootNode) return VALUE_DRAW; // Step 3. Mate distance pruning. Even if we mate at the next move our score @@ -719,7 +716,7 @@ namespace { && !inCheck && refinedValue + razor_margin(depth) < beta && ttMove == MOVE_NONE - && abs(beta) < VALUE_MATE_IN_PLY_MAX + && abs(beta) < VALUE_MATE_IN_MAX_PLY && !pos.has_pawn_on_7th(pos.side_to_move())) { Value rbeta = beta - razor_margin(depth); @@ -738,7 +735,7 @@ namespace { && depth < RazorDepth && !inCheck && refinedValue - futility_margin(depth, 0) >= beta - && abs(beta) < VALUE_MATE_IN_PLY_MAX + && abs(beta) < VALUE_MATE_IN_MAX_PLY && pos.non_pawn_material(pos.side_to_move())) return refinedValue - futility_margin(depth, 0); @@ -748,7 +745,7 @@ namespace { && depth > ONE_PLY && !inCheck && refinedValue >= beta - && abs(beta) < VALUE_MATE_IN_PLY_MAX + && abs(beta) < VALUE_MATE_IN_MAX_PLY && pos.non_pawn_material(pos.side_to_move())) { ss->currentMove = MOVE_NULL; @@ -770,7 +767,7 @@ namespace { if (nullValue >= beta) { // Do not return unproven mate scores - if (nullValue >= VALUE_MATE_IN_PLY_MAX) + if (nullValue >= VALUE_MATE_IN_MAX_PLY) nullValue = beta; if (depth < 6 * ONE_PLY) @@ -811,7 +808,7 @@ namespace { && !inCheck && !ss->skipNullMove && excludedMove == MOVE_NONE - && abs(beta) < VALUE_MATE_IN_PLY_MAX) + && abs(beta) < VALUE_MATE_IN_MAX_PLY) { Value rbeta = beta + 200; Depth rdepth = depth - ONE_PLY - 3 * ONE_PLY; @@ -901,7 +898,6 @@ split_point_start: // At split points actual search starts from here if (RootNode) { Signals.firstRootMove = (moveCount == 1); - nodes = pos.nodes_searched(); if (pos.thread() == 0 && elapsed_time() > 2000) cout << "info depth " << depth / ONE_PLY @@ -958,7 +954,7 @@ split_point_start: // At split points actual search starts from here && !dangerous && move != ttMove && !is_castle(move) - && (bestValue > VALUE_MATED_IN_PLY_MAX || bestValue == -VALUE_INFINITE)) + && (bestValue > VALUE_MATED_IN_MAX_PLY || bestValue == -VALUE_INFINITE)) { // Move count based pruning if ( moveCount >= futility_move_count(depth) @@ -1068,7 +1064,6 @@ split_point_start: // At split points actual search starts from here if (RootNode && !Signals.stop) { RootMove& rm = *find(RootMoves.begin(), RootMoves.end(), move); - rm.nodes += pos.nodes_searched() - nodes; // PV move or new best move ? if (isPvMove || value > alpha) @@ -1213,7 +1208,7 @@ split_point_start: // At split points actual search starts from here ss->ply = (ss-1)->ply + 1; // Check for an instant draw or maximum ply reached - if (pos.is_draw() || ss->ply > PLY_MAX) + if (pos.is_draw() || ss->ply > MAX_PLY) return VALUE_DRAW; // Decide whether or not to include checks, this fixes also the type of @@ -1314,7 +1309,7 @@ split_point_start: // At split points actual search starts from here // Detect non-capture evasions that are candidate to be pruned evasionPrunable = !PvNode && inCheck - && bestValue > VALUE_MATED_IN_PLY_MAX + && bestValue > VALUE_MATED_IN_MAX_PLY && !pos.is_capture(move) && !pos.can_castle(pos.side_to_move()); @@ -1500,10 +1495,10 @@ split_point_start: // At split points actual search starts from here Value value_to_tt(Value v, int ply) { - if (v >= VALUE_MATE_IN_PLY_MAX) + if (v >= VALUE_MATE_IN_MAX_PLY) return v + ply; - if (v <= VALUE_MATED_IN_PLY_MAX) + if (v <= VALUE_MATED_IN_MAX_PLY) return v - ply; return v; @@ -1516,10 +1511,10 @@ split_point_start: // At split points actual search starts from here Value value_from_tt(Value v, int ply) { - if (v >= VALUE_MATE_IN_PLY_MAX) + if (v >= VALUE_MATE_IN_MAX_PLY) return v - ply; - if (v <= VALUE_MATED_IN_PLY_MAX) + if (v <= VALUE_MATED_IN_MAX_PLY) return v + ply; return v; @@ -1574,8 +1569,8 @@ split_point_start: // At split points actual search starts from here Value v = value_from_tt(tte->value(), ply); return ( tte->depth() >= depth - || v >= std::max(VALUE_MATE_IN_PLY_MAX, beta) - || v < std::min(VALUE_MATED_IN_PLY_MAX, beta)) + || v >= std::max(VALUE_MATE_IN_MAX_PLY, beta) + || v < std::min(VALUE_MATED_IN_MAX_PLY, beta)) && ( ((tte->type() & VALUE_TYPE_LOWER) && v >= beta) || ((tte->type() & VALUE_TYPE_UPPER) && v < beta)); @@ -1624,10 +1619,10 @@ split_point_start: // At split points actual search starts from here std::stringstream s; - if (abs(v) < VALUE_MATE - PLY_MAX * ONE_PLY) - s << " score cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to centipawns + if (abs(v) < VALUE_MATE_IN_MAX_PLY) + s << "cp " << v * 100 / int(PawnValueMidgame); else - s << " score mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; + s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; s << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : ""); @@ -1664,7 +1659,7 @@ split_point_start: // At split points actual search starts from here cout << "info depth " << d << " seldepth " << selDepth - << (i == PVIdx ? score_to_uci(v, alpha, beta) : score_to_uci(v)) + << " score " << (i == PVIdx ? score_to_uci(v, alpha, beta) : score_to_uci(v)) << " nodes " << pos.nodes_searched() << " nps " << (t > 0 ? pos.nodes_searched() * 1000 / t : 0) << " time " << t @@ -1701,9 +1696,9 @@ split_point_start: // At split points actual search starts from here std::stringstream s; - if (v >= VALUE_MATE_IN_PLY_MAX) + if (v >= VALUE_MATE_IN_MAX_PLY) s << "#" << (VALUE_MATE - v + 1) / 2; - else if (v <= VALUE_MATED_IN_PLY_MAX) + else if (v <= VALUE_MATED_IN_MAX_PLY) s << "-#" << (VALUE_MATE + v) / 2; else s << std::setprecision(2) << std::fixed << std::showpos @@ -1717,7 +1712,7 @@ split_point_start: // At split points actual search starts from here const int64_t K = 1000; const int64_t M = 1000000; - StateInfo state[PLY_MAX_PLUS_2], *st = state; + StateInfo state[MAX_PLY_PLUS_2], *st = state; Move* m = pv; string san, padding; size_t length; @@ -1758,7 +1753,7 @@ split_point_start: // At split points actual search starts from here while (m != pv) pos.undo_move(*--m); - Log l(Options["Search Log Filename"].value()); + Log l(Options["Search Log Filename"]); l << s.str() << endl; } @@ -1815,7 +1810,7 @@ split_point_start: // At split points actual search starts from here void RootMove::extract_pv_from_tt(Position& pos) { - StateInfo state[PLY_MAX_PLUS_2], *st = state; + StateInfo state[MAX_PLY_PLUS_2], *st = state; TTEntry* tte; int ply = 1; Move m = pv[0]; @@ -1830,7 +1825,7 @@ split_point_start: // At split points actual search starts from here && tte->move() != MOVE_NONE && pos.is_pseudo_legal(tte->move()) && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces()) - && ply < PLY_MAX + && ply < MAX_PLY && (!pos.is_draw() || ply < 2)) { pv.push_back(tte->move()); @@ -1849,7 +1844,7 @@ split_point_start: // At split points actual search starts from here void RootMove::insert_pv_in_tt(Position& pos) { - StateInfo state[PLY_MAX_PLUS_2], *st = state; + StateInfo state[MAX_PLY_PLUS_2], *st = state; TTEntry* tte; Key k; Value v, m = VALUE_NONE; @@ -1925,7 +1920,7 @@ void Thread::idle_loop(SplitPoint* sp) { assert(!do_terminate); // Copy split point position and search stack and call search() - Stack ss[PLY_MAX_PLUS_2]; + Stack ss[MAX_PLY_PLUS_2]; SplitPoint* tsp = splitPoint; Position pos(*tsp->pos, threadID); @@ -1979,9 +1974,7 @@ void do_timer_event() { if (system_time() - lastInfoTime >= 1000 || !lastInfoTime) { lastInfoTime = system_time(); - - dbg_print_mean(); - dbg_print_hit_rate(); + dbg_print(); } if (Limits.ponder)