mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 09:13:08 +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 <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <set>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
#include "ucioption.h"
|
#include "ucioption.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Search;
|
|
||||||
|
|
||||||
static const char* Defaults[] = {
|
static const char* Defaults[] = {
|
||||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
"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[]) {
|
void benchmark(int argc, char* argv[]) {
|
||||||
|
|
||||||
vector<string> fens;
|
vector<string> fens;
|
||||||
LimitsType limits;
|
Search::LimitsType limits;
|
||||||
int time;
|
int time;
|
||||||
int64_t nodes = 0;
|
int64_t nodes = 0;
|
||||||
|
|
||||||
|
@ -116,14 +114,14 @@ void benchmark(int argc, char* argv[]) {
|
||||||
|
|
||||||
if (valType == "perft")
|
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;
|
cerr << "\nPerft " << limits.maxDepth << " leaf nodes: " << cnt << endl;
|
||||||
nodes += cnt;
|
nodes += cnt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Threads.start_thinking(pos, limits, set<Move>(), false);
|
Threads.start_thinking(pos, limits);
|
||||||
nodes += RootPosition.nodes_searched();
|
nodes += Search::RootPosition.nodes_searched();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "book.h"
|
#include "book.h"
|
||||||
#include "evaluate.h"
|
#include "evaluate.h"
|
||||||
|
@ -42,7 +41,7 @@ namespace Search {
|
||||||
|
|
||||||
volatile SignalsType Signals;
|
volatile SignalsType Signals;
|
||||||
LimitsType Limits;
|
LimitsType Limits;
|
||||||
std::set<Move> SearchMoves;
|
std::vector<RootMove> RootMoves;
|
||||||
Position RootPosition;
|
Position RootPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,33 +58,6 @@ namespace {
|
||||||
// Different node types, used as template parameter
|
// Different node types, used as template parameter
|
||||||
enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV };
|
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
|
// 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 };
|
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]; }
|
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)];
|
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
|
// Easy move margin. An easy move candidate must be at least this much better
|
||||||
// better than the second best move.
|
// than the second best move.
|
||||||
const Value EasyMoveMargin = Value(0x150);
|
const Value EasyMoveMargin = Value(0x150);
|
||||||
|
|
||||||
// This is the minimum interval in msec between two check_time() calls
|
// This is the minimum interval in msec between two check_time() calls
|
||||||
const int TimerResolution = 5;
|
const int TimerResolution = 5;
|
||||||
|
|
||||||
|
|
||||||
/// Namespace variables
|
|
||||||
|
|
||||||
std::vector<RootMove> RootMoves;
|
|
||||||
size_t MultiPV, UCIMultiPV, PVIdx;
|
size_t MultiPV, UCIMultiPV, PVIdx;
|
||||||
TimeManager TimeMgr;
|
TimeManager TimeMgr;
|
||||||
int BestMoveChanges;
|
int BestMoveChanges;
|
||||||
|
@ -154,8 +123,6 @@ namespace {
|
||||||
History H;
|
History H;
|
||||||
|
|
||||||
|
|
||||||
/// Local functions
|
|
||||||
|
|
||||||
template <NodeType NT>
|
template <NodeType NT>
|
||||||
Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth);
|
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());
|
TimeMgr.init(Limits, pos.startpos_ply_counter());
|
||||||
TT.new_search();
|
TT.new_search();
|
||||||
H.clear();
|
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())
|
if (RootMoves.empty())
|
||||||
{
|
{
|
||||||
|
@ -1798,11 +1758,13 @@ split_point_start: // At split points actual search starts from here
|
||||||
return best;
|
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
|
/// RootMove::extract_pv_from_tt() builds a PV by adding moves from the TT table.
|
||||||
// allow to always have a ponder move even when we fail high at root and also a
|
/// We consider also failing high nodes and not only VALUE_TYPE_EXACT nodes so
|
||||||
// long PV to print that is important for position analysis.
|
/// 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) {
|
void RootMove::extract_pv_from_tt(Position& pos) {
|
||||||
|
|
||||||
|
@ -1834,9 +1796,9 @@ split_point_start: // At split points actual search starts from here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// insert_pv_in_tt() is called at the end of a search iteration, and inserts
|
/// RootMove::insert_pv_in_tt() is called at the end of a search iteration, and
|
||||||
// the PV back into the TT. This makes sure the old PV moves are searched
|
/// 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.
|
/// 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) {
|
||||||
|
|
||||||
|
@ -1865,8 +1827,6 @@ split_point_start: // At split points actual search starts from here
|
||||||
do pos.undo_move(pv[--ply]); while (ply);
|
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.
|
/// 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
|
/// The parameter 'sp', if non-NULL, is a pointer to an active SplitPoint object
|
||||||
|
|
29
src/search.h
29
src/search.h
|
@ -21,7 +21,7 @@
|
||||||
#define SEARCH_H_INCLUDED
|
#define SEARCH_H_INCLUDED
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <set>
|
#include <vector>
|
||||||
|
|
||||||
#include "types.h"
|
#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
|
/// 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
|
/// 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.
|
/// 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 volatile SignalsType Signals;
|
||||||
extern LimitsType Limits;
|
extern LimitsType Limits;
|
||||||
extern std::set<Move> SearchMoves;
|
extern std::vector<RootMove> RootMoves;
|
||||||
extern Position RootPosition;
|
extern Position RootPosition;
|
||||||
|
|
||||||
extern void init();
|
extern void init();
|
||||||
extern int64_t perft(Position& pos, Depth depth);
|
extern int64_t perft(Position& pos, Depth depth);
|
||||||
extern void think();
|
extern void think();
|
||||||
|
|
||||||
} // namespace
|
} // namespace Search
|
||||||
|
|
||||||
#endif // !defined(SEARCH_H_INCLUDED)
|
#endif // !defined(SEARCH_H_INCLUDED)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "movegen.h"
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "ucioption.h"
|
#include "ucioption.h"
|
||||||
|
@ -420,7 +421,7 @@ void Thread::main_loop() {
|
||||||
if (do_terminate)
|
if (do_terminate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
think(); // This is the search entry point
|
Search::think();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +432,7 @@ void Thread::main_loop() {
|
||||||
// the search to finish.
|
// the search to finish.
|
||||||
|
|
||||||
void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limits,
|
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];
|
Thread& main = threads[0];
|
||||||
|
|
||||||
lock_grab(&main.sleepLock);
|
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
|
// Copy input arguments to initialize the search
|
||||||
RootPosition.copy(pos, 0);
|
RootPosition.copy(pos, 0);
|
||||||
Limits = limits;
|
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
|
// Reset signals before to start the new search
|
||||||
Signals.stopOnPonderhit = Signals.firstRootMove = false;
|
Signals.stopOnPonderhit = Signals.firstRootMove = false;
|
||||||
|
@ -452,7 +459,7 @@ void ThreadsManager::start_thinking(const Position& pos, const LimitsType& limit
|
||||||
main.do_sleep = false;
|
main.do_sleep = false;
|
||||||
cond_signal(&main.sleepCond); // Wake up main thread and start searching
|
cond_signal(&main.sleepCond); // Wake up main thread and start searching
|
||||||
|
|
||||||
if (!asyncMode)
|
if (!async)
|
||||||
while (!main.do_sleep)
|
while (!main.do_sleep)
|
||||||
cond_wait(&sleepCond, &main.sleepLock);
|
cond_wait(&sleepCond, &main.sleepLock);
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ public:
|
||||||
void wait_for_stop_or_ponderhit();
|
void wait_for_stop_or_ponderhit();
|
||||||
void stop_thinking();
|
void stop_thinking();
|
||||||
void start_thinking(const Position& pos, const Search::LimitsType& limits,
|
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>
|
template <bool Fake>
|
||||||
Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue,
|
Value split(Position& pos, Search::Stack* ss, Value alpha, Value beta, Value bestValue,
|
||||||
|
|
Loading…
Add table
Reference in a new issue