mirror of
https://github.com/sockspls/badfish
synced 2025-04-29 16:23:09 +00:00
Add user-defined conversions to UCIOption
Greatly improves the usage. User defined conversions are a novelity for SF, another amazing C++ facility at work ! No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
ae65ab25d5
commit
0759d8f430
6 changed files with 44 additions and 54 deletions
|
@ -412,7 +412,7 @@ void read_evaluation_uci_options(Color us) {
|
||||||
|
|
||||||
// If running in analysis mode, make sure we use symmetrical king safety. We do this
|
// If running in analysis mode, make sure we use symmetrical king safety. We do this
|
||||||
// by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] by their average.
|
// by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] by their average.
|
||||||
if (Options["UCI_AnalyseMode"].value<bool>())
|
if (Options["UCI_AnalyseMode"])
|
||||||
Weights[kingDangerUs] = Weights[kingDangerThem] = (Weights[kingDangerUs] + Weights[kingDangerThem]) / 2;
|
Weights[kingDangerUs] = Weights[kingDangerThem] = (Weights[kingDangerUs] + Weights[kingDangerThem]) / 2;
|
||||||
|
|
||||||
init_safety();
|
init_safety();
|
||||||
|
@ -1101,8 +1101,8 @@ namespace {
|
||||||
Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight) {
|
Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight) {
|
||||||
|
|
||||||
// Scale option value from 100 to 256
|
// Scale option value from 100 to 256
|
||||||
int mg = Options[mgOpt].value<int>() * 256 / 100;
|
int mg = Options[mgOpt] * 256 / 100;
|
||||||
int eg = Options[egOpt].value<int>() * 256 / 100;
|
int eg = Options[egOpt] * 256 / 100;
|
||||||
|
|
||||||
return apply_weight(make_score(mg, eg), internalWeight);
|
return apply_weight(make_score(mg, eg), internalWeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,12 +296,12 @@ void Search::think() {
|
||||||
|| count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
|
|| count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
|
||||||
RootMoves.push_back(RootMove(ml.move()));
|
RootMoves.push_back(RootMove(ml.move()));
|
||||||
|
|
||||||
if (Options["OwnBook"].value<bool>())
|
if (Options["OwnBook"])
|
||||||
{
|
{
|
||||||
if (Options["Book File"].value<string>() != book.name())
|
if (book.name() != (string)Options["Book File"])
|
||||||
book.open(Options["Book File"].value<string>());
|
book.open(Options["Book File"]);
|
||||||
|
|
||||||
Move bookMove = book.probe(pos, Options["Best Book Move"].value<bool>());
|
Move bookMove = book.probe(pos, Options["Best Book Move"]);
|
||||||
|
|
||||||
if ( bookMove != MOVE_NONE
|
if ( bookMove != MOVE_NONE
|
||||||
&& count(RootMoves.begin(), RootMoves.end(), bookMove))
|
&& count(RootMoves.begin(), RootMoves.end(), bookMove))
|
||||||
|
@ -315,24 +315,24 @@ void Search::think() {
|
||||||
read_evaluation_uci_options(pos.side_to_move());
|
read_evaluation_uci_options(pos.side_to_move());
|
||||||
Threads.read_uci_options();
|
Threads.read_uci_options();
|
||||||
|
|
||||||
TT.set_size(Options["Hash"].value<int>());
|
TT.set_size(Options["Hash"]);
|
||||||
if (Options["Clear Hash"].value<bool>())
|
if (Options["Clear Hash"])
|
||||||
{
|
{
|
||||||
Options["Clear Hash"] = false;
|
Options["Clear Hash"] = false;
|
||||||
TT.clear();
|
TT.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
UCIMultiPV = Options["MultiPV"].value<size_t>();
|
UCIMultiPV = Options["MultiPV"];
|
||||||
SkillLevel = Options["Skill Level"].value<int>();
|
SkillLevel = Options["Skill Level"];
|
||||||
|
|
||||||
// Do we have to play with skill handicap? In this case enable MultiPV that
|
// 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.
|
// we will use behind the scenes to retrieve a set of possible moves.
|
||||||
SkillLevelEnabled = (SkillLevel < 20);
|
SkillLevelEnabled = (SkillLevel < 20);
|
||||||
MultiPV = (SkillLevelEnabled ? std::max(UCIMultiPV, (size_t)4) : UCIMultiPV);
|
MultiPV = (SkillLevelEnabled ? std::max(UCIMultiPV, (size_t)4) : UCIMultiPV);
|
||||||
|
|
||||||
if (Options["Use Search Log"].value<bool>())
|
if (Options["Use Search Log"])
|
||||||
{
|
{
|
||||||
Log log(Options["Search Log Filename"].value<string>());
|
Log log(Options["Search Log Filename"]);
|
||||||
log << "\nSearching: " << pos.to_fen()
|
log << "\nSearching: " << pos.to_fen()
|
||||||
<< "\ninfinite: " << Limits.infinite
|
<< "\ninfinite: " << Limits.infinite
|
||||||
<< " ponder: " << Limits.ponder
|
<< " ponder: " << Limits.ponder
|
||||||
|
@ -362,11 +362,11 @@ void Search::think() {
|
||||||
Threads.set_timer(0);
|
Threads.set_timer(0);
|
||||||
Threads.set_size(1);
|
Threads.set_size(1);
|
||||||
|
|
||||||
if (Options["Use Search Log"].value<bool>())
|
if (Options["Use Search Log"])
|
||||||
{
|
{
|
||||||
int e = elapsed_time();
|
int e = elapsed_time();
|
||||||
|
|
||||||
Log log(Options["Search Log Filename"].value<string>());
|
Log log(Options["Search Log Filename"]);
|
||||||
log << "Nodes: " << pos.nodes_searched()
|
log << "Nodes: " << pos.nodes_searched()
|
||||||
<< "\nNodes/second: " << (e > 0 ? pos.nodes_searched() * 1000 / e : 0)
|
<< "\nNodes/second: " << (e > 0 ? pos.nodes_searched() * 1000 / e : 0)
|
||||||
<< "\nBest move: " << move_to_san(pos, RootMoves[0].pv[0]);
|
<< "\nBest move: " << move_to_san(pos, RootMoves[0].pv[0]);
|
||||||
|
@ -512,7 +512,7 @@ namespace {
|
||||||
if (SkillLevelEnabled && depth == 1 + SkillLevel)
|
if (SkillLevelEnabled && depth == 1 + SkillLevel)
|
||||||
skillBest = do_skill_level();
|
skillBest = do_skill_level();
|
||||||
|
|
||||||
if (Options["Use Search Log"].value<bool>())
|
if (Options["Use Search Log"])
|
||||||
pv_info_to_log(pos, depth, bestValue, elapsed_time(), &RootMoves[0].pv[0]);
|
pv_info_to_log(pos, depth, bestValue, elapsed_time(), &RootMoves[0].pv[0]);
|
||||||
|
|
||||||
// Filter out startup noise when monitoring best move stability
|
// Filter out startup noise when monitoring best move stability
|
||||||
|
@ -1758,7 +1758,7 @@ split_point_start: // At split points actual search starts from here
|
||||||
while (m != pv)
|
while (m != pv)
|
||||||
pos.undo_move(*--m);
|
pos.undo_move(*--m);
|
||||||
|
|
||||||
Log l(Options["Search Log Filename"].value<string>());
|
Log l(Options["Search Log Filename"]);
|
||||||
l << s.str() << endl;
|
l << s.str() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,11 +112,11 @@ bool Thread::is_available_to(int master) const {
|
||||||
|
|
||||||
void ThreadsManager::read_uci_options() {
|
void ThreadsManager::read_uci_options() {
|
||||||
|
|
||||||
maxThreadsPerSplitPoint = Options["Max Threads per Split Point"].value<int>();
|
maxThreadsPerSplitPoint = Options["Max Threads per Split Point"];
|
||||||
minimumSplitDepth = Options["Min Split Depth"].value<int>() * ONE_PLY;
|
minimumSplitDepth = Options["Min Split Depth"] * ONE_PLY;
|
||||||
useSleepingThreads = Options["Use Sleeping Threads"].value<bool>();
|
useSleepingThreads = Options["Use Sleeping Threads"];
|
||||||
|
|
||||||
set_size(Options["Threads"].value<int>());
|
set_size(Options["Threads"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,10 +104,10 @@ void TimeManager::init(const Search::LimitsType& limits, int currentPly)
|
||||||
int hypMTG, hypMyTime, t1, t2;
|
int hypMTG, hypMyTime, t1, t2;
|
||||||
|
|
||||||
// Read uci parameters
|
// Read uci parameters
|
||||||
int emergencyMoveHorizon = Options["Emergency Move Horizon"].value<int>();
|
int emergencyMoveHorizon = Options["Emergency Move Horizon"];
|
||||||
int emergencyBaseTime = Options["Emergency Base Time"].value<int>();
|
int emergencyBaseTime = Options["Emergency Base Time"];
|
||||||
int emergencyMoveTime = Options["Emergency Move Time"].value<int>();
|
int emergencyMoveTime = Options["Emergency Move Time"];
|
||||||
int minThinkingTime = Options["Minimum Thinking Time"].value<int>();
|
int minThinkingTime = Options["Minimum Thinking Time"];
|
||||||
|
|
||||||
// Initialize to maximum values but unstablePVExtraTime that is reset
|
// Initialize to maximum values but unstablePVExtraTime that is reset
|
||||||
unstablePVExtraTime = 0;
|
unstablePVExtraTime = 0;
|
||||||
|
@ -132,7 +132,7 @@ void TimeManager::init(const Search::LimitsType& limits, int currentPly)
|
||||||
maximumSearchTime = std::min(maximumSearchTime, t2);
|
maximumSearchTime = std::min(maximumSearchTime, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Options["Ponder"].value<bool>())
|
if (Options["Ponder"])
|
||||||
optimumSearchTime += optimumSearchTime / 4;
|
optimumSearchTime += optimumSearchTime / 4;
|
||||||
|
|
||||||
// Make sure that maxSearchTime is not over absoluteMaxSearchTime
|
// Make sure that maxSearchTime is not over absoluteMaxSearchTime
|
||||||
|
|
12
src/uci.cpp
12
src/uci.cpp
|
@ -157,7 +157,7 @@ namespace {
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pos.from_fen(fen, Options["UCI_Chess960"].value<bool>());
|
pos.from_fen(fen, Options["UCI_Chess960"]);
|
||||||
|
|
||||||
// Parse move list (if any)
|
// Parse move list (if any)
|
||||||
while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)
|
while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)
|
||||||
|
@ -188,10 +188,14 @@ namespace {
|
||||||
while (is >> token)
|
while (is >> token)
|
||||||
value += string(" ", !value.empty()) + token;
|
value += string(" ", !value.empty()) + token;
|
||||||
|
|
||||||
if (Options.count(name))
|
if (!Options.count(name))
|
||||||
Options[name] = (value.empty() ? "true" : value); // UCI buttons don't have "value"
|
|
||||||
else
|
|
||||||
cout << "No such option: " << name << endl;
|
cout << "No such option: " << name << endl;
|
||||||
|
|
||||||
|
else if (value.empty()) // UCI buttons don't have a value
|
||||||
|
Options[name] = true;
|
||||||
|
|
||||||
|
else
|
||||||
|
Options[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,19 @@ public:
|
||||||
UCIOption(bool v, std::string type = "check");
|
UCIOption(bool v, std::string type = "check");
|
||||||
UCIOption(int v, int min, int max);
|
UCIOption(int v, int min, int max);
|
||||||
|
|
||||||
template<typename T> T value() const;
|
|
||||||
void operator=(const std::string& v);
|
void operator=(const std::string& v);
|
||||||
void operator=(bool v) { *this = std::string(v ? "true" : "false"); }
|
void operator=(bool v) { *this = std::string(v ? "true" : "false"); }
|
||||||
|
|
||||||
|
operator int() const {
|
||||||
|
assert(type == "check" || type == "button" || type == "spin");
|
||||||
|
return (type == "spin" ? atoi(currentValue.c_str()) : currentValue == "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::string() const {
|
||||||
|
assert(type == "string");
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend std::ostream& operator<<(std::ostream&, const OptionsMap&);
|
friend std::ostream& operator<<(std::ostream&, const OptionsMap&);
|
||||||
|
|
||||||
|
@ -48,29 +57,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// UCIOption::value() definition and specializations
|
|
||||||
template<typename T>
|
|
||||||
T UCIOption::value() const {
|
|
||||||
|
|
||||||
assert(type == "spin");
|
|
||||||
return T(atoi(currentValue.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline std::string UCIOption::value<std::string>() const {
|
|
||||||
|
|
||||||
assert(type == "string");
|
|
||||||
return currentValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool UCIOption::value<bool>() const {
|
|
||||||
|
|
||||||
assert(type == "check" || type == "button");
|
|
||||||
return currentValue == "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Custom comparator because UCI options should be case insensitive
|
/// Custom comparator because UCI options should be case insensitive
|
||||||
struct CaseInsensitiveLess {
|
struct CaseInsensitiveLess {
|
||||||
bool operator() (const std::string&, const std::string&) const;
|
bool operator() (const std::string&, const std::string&) const;
|
||||||
|
|
Loading…
Add table
Reference in a new issue