Move struct RootMove to Search namespace

And directly pass RootMoves instead of SearchMoves
to main thread. A class declaration is better suited
in a header and slims a bit the fatty search.cpp

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba
2012-01-14 13:49:25 +01:00
parent a29dd88f75
commit 103b368ab7
5 changed files with 113 additions and 125 deletions
+70 -110
View File
@@ -24,7 +24,6 @@
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>
#include "book.h"
#include "evaluate.h"
@@ -42,7 +41,7 @@ namespace Search {
volatile SignalsType Signals;
LimitsType Limits;
std::set<Move> SearchMoves;
std::vector<RootMove> RootMoves;
Position RootPosition;
}
@@ -59,33 +58,6 @@ namespace {
// Different node types, used as template parameter
enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV };
// RootMove struct is used for moves at the root of the tree. For each root
// move we store a score, a node count, and a PV (really a refutation in the
// case of moves which fail low). Score is normally set at -VALUE_INFINITE for
// all non-pv moves.
struct RootMove {
RootMove(){}
RootMove(Move m) {
score = prevScore = -VALUE_INFINITE;
pv.push_back(m);
pv.push_back(MOVE_NONE);
}
bool operator<(const RootMove& m) const { return score < m.score; }
bool operator==(const Move& m) const { return pv[0] == m; }
void extract_pv_from_tt(Position& pos);
void insert_pv_in_tt(Position& pos);
Value score;
Value prevScore;
std::vector<Move> pv;
};
/// Constants
// Lookup table to check if a Piece is a slider and its access function
const bool Slidings[18] = { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1 };
inline bool piece_is_slider(Piece p) { return Slidings[p]; }
@@ -135,17 +107,14 @@ namespace {
return (Depth) Reductions[PvNode][std::min(int(d) / ONE_PLY, 63)][std::min(mn, 63)];
}
// Easy move margin. An easy move candidate must be at least this much
// better than the second best move.
// Easy move margin. An easy move candidate must be at least this much better
// than the second best move.
const Value EasyMoveMargin = Value(0x150);
// This is the minimum interval in msec between two check_time() calls
const int TimerResolution = 5;
/// Namespace variables
std::vector<RootMove> RootMoves;
size_t MultiPV, UCIMultiPV, PVIdx;
TimeManager TimeMgr;
int BestMoveChanges;
@@ -154,8 +123,6 @@ namespace {
History H;
/// Local functions
template <NodeType NT>
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
@@ -289,13 +256,6 @@ void Search::think() {
TimeMgr.init(Limits, pos.startpos_ply_counter());
TT.new_search();
H.clear();
RootMoves.clear();
// Populate RootMoves with all the legal moves (default) or, if a SearchMoves
// is given, with the subset of legal moves to search.
for (MoveList<MV_LEGAL> ml(pos); !ml.end(); ++ml)
if (SearchMoves.empty() || SearchMoves.count(ml.move()))
RootMoves.push_back(RootMove(ml.move()));
if (RootMoves.empty())
{
@@ -1798,76 +1758,76 @@ split_point_start: // At split points actual search starts from here
return best;
}
// extract_pv_from_tt() builds a PV by adding moves from the transposition table.
// We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes. This
// allow to always have a ponder move even when we fail high at root and also a
// long PV to print that is important for position analysis.
void RootMove::extract_pv_from_tt(Position& pos) {
StateInfo state[MAX_PLY_PLUS_2], *st = state;
TTEntry* tte;
int ply = 1;
Move m = pv[0];
assert(m != MOVE_NONE && pos.is_pseudo_legal(m));
pv.clear();
pv.push_back(m);
pos.do_move(m, *st++);
while ( (tte = TT.probe(pos.key())) != NULL
&& tte->move() != MOVE_NONE
&& pos.is_pseudo_legal(tte->move())
&& pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
&& ply < MAX_PLY
&& (!pos.is_draw<false>() || ply < 2))
{
pv.push_back(tte->move());
pos.do_move(tte->move(), *st++);
ply++;
}
pv.push_back(MOVE_NONE);
do pos.undo_move(pv[--ply]); while (ply);
}
// insert_pv_in_tt() is called at the end of a search iteration, and inserts
// the PV back into the TT. This makes sure the old PV moves are searched
// first, even if the old TT entries have been overwritten.
void RootMove::insert_pv_in_tt(Position& pos) {
StateInfo state[MAX_PLY_PLUS_2], *st = state;
TTEntry* tte;
Key k;
Value v, m = VALUE_NONE;
int ply = 0;
assert(pv[ply] != MOVE_NONE && pos.is_pseudo_legal(pv[ply]));
do {
k = pos.key();
tte = TT.probe(k);
// Don't overwrite existing correct entries
if (!tte || tte->move() != pv[ply])
{
v = (pos.in_check() ? VALUE_NONE : evaluate(pos, m));
TT.store(k, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[ply], v, m);
}
pos.do_move(pv[ply], *st++);
} while (pv[++ply] != MOVE_NONE);
do pos.undo_move(pv[--ply]); while (ply);
}
} // namespace
/// RootMove::extract_pv_from_tt() builds a PV by adding moves from the TT table.
/// We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes so
/// to allow to always have a ponder move even when we fail high at root, and
/// a long PV to print that is important for position analysis.
void RootMove::extract_pv_from_tt(Position& pos) {
StateInfo state[MAX_PLY_PLUS_2], *st = state;
TTEntry* tte;
int ply = 1;
Move m = pv[0];
assert(m != MOVE_NONE && pos.is_pseudo_legal(m));
pv.clear();
pv.push_back(m);
pos.do_move(m, *st++);
while ( (tte = TT.probe(pos.key())) != NULL
&& tte->move() != MOVE_NONE
&& pos.is_pseudo_legal(tte->move())
&& pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
&& ply < MAX_PLY
&& (!pos.is_draw<false>() || ply < 2))
{
pv.push_back(tte->move());
pos.do_move(tte->move(), *st++);
ply++;
}
pv.push_back(MOVE_NONE);
do pos.undo_move(pv[--ply]); while (ply);
}
/// RootMove::insert_pv_in_tt() is called at the end of a search iteration, and
/// inserts the PV back into the TT. This makes sure the old PV moves are searched
/// first, even if the old TT entries have been overwritten.
void RootMove::insert_pv_in_tt(Position& pos) {
StateInfo state[MAX_PLY_PLUS_2], *st = state;
TTEntry* tte;
Key k;
Value v, m = VALUE_NONE;
int ply = 0;
assert(pv[ply] != MOVE_NONE && pos.is_pseudo_legal(pv[ply]));
do {
k = pos.key();
tte = TT.probe(k);
// Don't overwrite existing correct entries
if (!tte || tte->move() != pv[ply])
{
v = (pos.in_check() ? VALUE_NONE : evaluate(pos, m));
TT.store(k, VALUE_NONE, VALUE_TYPE_NONE, DEPTH_NONE, pv[ply], v, m);
}
pos.do_move(pv[ply], *st++);
} while (pv[++ply] != MOVE_NONE);
do pos.undo_move(pv[--ply]); while (ply);
}
/// Thread::idle_loop() is where the thread is parked when it has no work to do.
/// The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint object
/// for which the thread is the master.