mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 16:53:09 +00:00
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:
parent
a29dd88f75
commit
103b368ab7
5 changed files with 113 additions and 125 deletions
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "misc.h"
|
||||
|
@ -29,7 +28,6 @@
|
|||
#include "ucioption.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Search;
|
||||
|
||||
static const char* Defaults[] = {
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
|
@ -62,7 +60,7 @@ static const char* Defaults[] = {
|
|||
void benchmark(int argc, char* argv[]) {
|
||||
|
||||
vector<string> fens;
|
||||
LimitsType limits;
|
||||
Search::LimitsType limits;
|
||||
int time;
|
||||
int64_t nodes = 0;
|
||||
|
||||
|
@ -116,14 +114,14 @@ void benchmark(int argc, char* argv[]) {
|
|||
|
||||
if (valType == "perft")
|
||||
{
|
||||
int64_t cnt = perft(pos, limits.maxDepth * ONE_PLY);
|
||||
int64_t cnt = Search::perft(pos, limits.maxDepth * ONE_PLY);
|
||||
cerr << "\nPerft " << limits.maxDepth << " leaf nodes: " << cnt << endl;
|
||||
nodes += cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
Threads.start_thinking(pos, limits, set<Move>(), false);
|
||||
nodes += RootPosition.nodes_searched();
|
||||
Threads.start_thinking(pos, limits);
|
||||
nodes += Search::RootPosition.nodes_searched();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,13 +1758,15 @@ split_point_start: // At split points actual search starts from here
|
|||
return best;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// 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) {
|
||||
/// 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;
|
||||
|
@ -1831,14 +1793,14 @@ split_point_start: // At split points actual search starts from here
|
|||
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.
|
||||
/// 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) {
|
||||
void RootMove::insert_pv_in_tt(Position& pos) {
|
||||
|
||||
StateInfo state[MAX_PLY_PLUS_2], *st = state;
|
||||
TTEntry* tte;
|
||||
|
@ -1863,9 +1825,7 @@ split_point_start: // At split points actual search starts from here
|
|||
} while (pv[++ply] != MOVE_NONE);
|
||||
|
||||
do pos.undo_move(pv[--ply]); while (ply);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
}
|
||||
|
||||
|
||||
/// Thread::idle_loop() is where the thread is parked when it has no work to do.
|
||||
|
|
29
src/search.h
29
src/search.h
|
@ -21,7 +21,7 @@
|
|||
#define SEARCH_H_INCLUDED
|
||||
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
|
@ -48,6 +48,29 @@ struct Stack {
|
|||
};
|
||||
|
||||
|
||||
/// 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(){} // Needed by sort()
|
||||
RootMove(Move m) : score(-VALUE_INFINITE), 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;
|
||||
};
|
||||
|
||||
|
||||
/// The LimitsType struct stores information sent by GUI about available time
|
||||
/// to search the current move, maximum depth/time, if we are in analysis mode
|
||||
/// or if we have to ponder while is our opponent's side to move.
|
||||
|
@ -70,13 +93,13 @@ struct SignalsType {
|
|||
|
||||
extern volatile SignalsType Signals;
|
||||
extern LimitsType Limits;
|
||||
extern std::set<Move> SearchMoves;
|
||||
extern std::vector<RootMove> RootMoves;
|
||||
extern Position RootPosition;
|
||||
|
||||
extern void init();
|
||||
extern int64_t perft(Position& pos, Depth depth);
|
||||
extern void think();
|
||||
|
||||
} // namespace
|
||||
} // namespace Search
|
||||
|
||||
#endif // !defined(SEARCH_H_INCLUDED)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "movegen.h"
|
||||
#include "search.h"
|
||||
#include "thread.h"
|
||||
#include "ucioption.h"
|
||||
|
@ -420,7 +421,7 @@ void Thread::main_loop() {
|
|||
if (do_terminate)
|
||||
return;
|
||||
|
||||
think(); // This is the search entry point
|
||||
Search::think();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +432,7 @@ void Thread::main_loop() {
|
|||
// the search to finish.
|
||||
|
||||
void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limits,
|
||||
const std::set<Move>& searchMoves, bool asyncMode) {
|
||||
const std::set<Move>& searchMoves, bool async) {
|
||||
Thread& main = threads[0];
|
||||
|
||||
lock_grab(&main.sleepLock);
|
||||
|
@ -443,7 +444,13 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
|
|||
// Copy input arguments to initialize the search
|
||||
RootPosition.copy(pos, 0);
|
||||
Limits = limits;
|
||||
SearchMoves = searchMoves;
|
||||
RootMoves.clear();
|
||||
|
||||
// Populate RootMoves with all the legal moves (default) or, if a searchMoves
|
||||
// set 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()));
|
||||
|
||||
// Reset signals before to start the new search
|
||||
Signals.stopOnPonderhit = Signals.firstRootMove = false;
|
||||
|
@ -452,7 +459,7 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
|
|||
main.do_sleep = false;
|
||||
cond_signal(&main.sleepCond); // Wake up main thread and start searching
|
||||
|
||||
if (!asyncMode)
|
||||
if (!async)
|
||||
while (!main.do_sleep)
|
||||
cond_wait(&sleepCond, &main.sleepLock);
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
void wait_for_stop_or_ponderhit();
|
||||
void stop_thinking();
|
||||
void start_thinking(const Position& pos, const Search::LimitsType& limits,
|
||||
const std::set<Move>& searchMoves, bool asyncMode);
|
||||
const std::set<Move>& = std::set<Move>(), bool async = false);
|
||||
|
||||
template <bool Fake>
|
||||
Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue,
|
||||
|
|
Loading…
Add table
Reference in a new issue