X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=2779bf8c83dfb27fb8d0c05822ecef8f9017add0;hp=02595ac53a58e751486ffa13aec6d58824b1e4c0;hb=a230dc14045691667ffce46619de60497edceb88;hpb=bd3fd6501baf11494e3919156f058980e20e9995 diff --git a/src/search.cpp b/src/search.cpp index 02595ac5..2779bf8c 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -51,10 +51,11 @@ namespace { // root move, we store a score, a node count, and a PV (really a refutation // in the case of moves which fail low). - class RootMove { + struct RootMove { - public: RootMove(); + bool operator<(const RootMove&); // used to sort + Move move; Value score; int64_t nodes, cumulativeNodes; @@ -75,14 +76,13 @@ namespace { void set_move_nodes(int moveNum, int64_t nodes); void set_move_pv(int moveNum, const Move pv[]); Move get_move_pv(int moveNum, int i) const; - int64_t get_move_cumulative_nodes(int moveNum); + int64_t get_move_cumulative_nodes(int moveNum) const; int move_count() const; Move scan_for_easy_move() const; void sort(); void sort_multipv(int n); private: - static bool compare_root_moves(const RootMove &rm1, const RootMove &rm2); static const int MaxRootMoves = 500; RootMove moves[MaxRootMoves]; int count; @@ -240,6 +240,7 @@ namespace { bool singleReply, bool mateThreat); bool ok_to_do_nullmove(const Position &pos); bool ok_to_prune(const Position &pos, Move m, Move threat, Depth d); + bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply); bool fail_high_ply_1(); int current_search_time(); @@ -458,7 +459,7 @@ void think(const Position &pos, bool infinite, bool ponder, int time, // We're ready to start thinking. Call the iterative deepening loop // function: - id_loop(pos, searchMoves); + id_loop(pos, searchMoves);; if(UseLogFile) LogFile.close(); @@ -859,14 +860,11 @@ namespace { // Transposition table lookup. At PV nodes, we don't use the TT for // pruning, but only for move ordering. - Value ttValue; - Depth ttDepth; - Move ttMove = MOVE_NONE; - ValueType ttValueType; + const TTEntry* tte = TT.retrieve(pos); - TT.retrieve(pos, &ttValue, &ttDepth, &ttMove, &ttValueType); + Move ttMove = (tte ? tte->move() : MOVE_NONE); - // Internal iterative deepening. + // Go with internal iterative deepening if we don't have a TT move. if(UseIIDAtPVNodes && ttMove == MOVE_NONE && depth >= 5*OnePly) { search_pv(pos, ss, alpha, beta, depth-2*OnePly, ply, threadID); ttMove = ss[ply].pv[ply]; @@ -1045,24 +1043,14 @@ namespace { return beta-1; // Transposition table lookup - bool ttFound; - Value ttValue; - Depth ttDepth; - Move ttMove = MOVE_NONE; - ValueType ttValueType; - - ttFound = TT.retrieve(pos, &ttValue, &ttDepth, &ttMove, &ttValueType); - if(ttFound) { - ttValue = value_from_tt(ttValue, ply); - if(ttDepth >= depth - || ttValue >= Max(value_mate_in(100), beta) - || ttValue < Min(value_mated_in(100), beta)) { - if((is_lower_bound(ttValueType) && ttValue >= beta) || - (is_upper_bound(ttValueType) && ttValue < beta)) { - ss[ply].currentMove = ttMove; - return ttValue; - } - } + const TTEntry* tte = TT.retrieve(pos); + + Move ttMove = (tte ? tte->move() : MOVE_NONE); + + if (tte && ok_to_use_TT(tte, depth, beta, ply)) + { + ss[ply].currentMove = ttMove; // can be MOVE_NONE ? + return value_from_tt(tte->value(), ply); } Value approximateEval = quick_evaluate(pos); @@ -1590,6 +1578,20 @@ namespace { lock_release(&(sp->lock)); } + // ok_to_use_TT() returns true if a transposition table score + // can be used at a given point in search. + + bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply) { + + Value v = value_from_tt(tte->value(), ply); + + return ( tte->depth() >= depth + || v >= Max(value_mate_in(100), beta) + || v < Min(value_mated_in(100), beta)) + + && ( (is_lower_bound(tte->type()) && v >= beta) + || (is_upper_bound(tte->type()) && v < beta)); + } /// The RootMove class @@ -1599,6 +1601,18 @@ namespace { nodes = cumulativeNodes = 0ULL; } + // RootMove::operator<() is the comparison function used when + // sorting the moves. A move m1 is considered to be better + // than a move m2 if it has a higher score, or if the moves + // have equal score but m1 has the higher node count. + + bool RootMove::operator<(const RootMove& m) { + + if (score != m.score) + return (score < m.score); + + return nodes <= m.nodes; + } /// The RootMoveList class @@ -1643,19 +1657,19 @@ namespace { // Simple accessor methods for the RootMoveList class - Move RootMoveList::get_move(int moveNum) const { + inline Move RootMoveList::get_move(int moveNum) const { return moves[moveNum].move; } - Value RootMoveList::get_move_score(int moveNum) const { + inline Value RootMoveList::get_move_score(int moveNum) const { return moves[moveNum].score; } - void RootMoveList::set_move_score(int moveNum, Value score) { + inline void RootMoveList::set_move_score(int moveNum, Value score) { moves[moveNum].score = score; } - void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) { + inline void RootMoveList::set_move_nodes(int moveNum, int64_t nodes) { moves[moveNum].nodes = nodes; moves[moveNum].cumulativeNodes += nodes; } @@ -1667,15 +1681,15 @@ namespace { moves[moveNum].pv[j] = MOVE_NONE; } - Move RootMoveList::get_move_pv(int moveNum, int i) const { + inline Move RootMoveList::get_move_pv(int moveNum, int i) const { return moves[moveNum].pv[i]; } - int64_t RootMoveList::get_move_cumulative_nodes(int moveNum) { + inline int64_t RootMoveList::get_move_cumulative_nodes(int moveNum) const { return moves[moveNum].cumulativeNodes; } - int RootMoveList::move_count() const { + inline int RootMoveList::move_count() const { return count; } @@ -1702,45 +1716,27 @@ namespace { return MOVE_NONE; } - - // RootMoveList::compare_root_moves() is the comparison function used by - // RootMoveList::sort when sorting the moves. A move m1 is considered to - // be better than a move m2 if it has a higher score, or if the moves have - // equal score but m1 has the higher node count. - - bool RootMoveList::compare_root_moves(const RootMove &rm1, - const RootMove &rm2) { - if (rm1.score != rm2.score) - return (rm1.score < rm2.score); - - return rm1.nodes <= rm2.nodes; - } - - // RootMoveList::sort() sorts the root move list at the beginning of a new // iteration. - void RootMoveList::sort() { - for(int i = 1; i < count; i++) { - RootMove rm = moves[i]; - int j; - for(j = i; j > 0 && compare_root_moves(moves[j-1], rm); j--) - moves[j] = moves[j-1]; - moves[j] = rm; - } + inline void RootMoveList::sort() { + + sort_multipv(count - 1); // all items } // RootMoveList::sort_multipv() sorts the first few moves in the root move - // list by their scores and depths. It is used to order the different PVs + // list by their scores and depths. It is used to order the different PVs // correctly in MultiPV mode. void RootMoveList::sort_multipv(int n) { - for(int i = 1; i <= n; i++) { + + for (int i = 1; i <= n; i++) + { RootMove rm = moves[i]; int j; - for(j = i; j > 0 && moves[j-1].score < rm.score; j--) - moves[j] = moves[j-1]; + for (j = i; j > 0 && moves[j-1] < rm; j--) + moves[j] = moves[j-1]; moves[j] = rm; } }