mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-20 17:16:33 +08:00
Explicitly pass RootMoves to TB probes
Currently Search::RootMoves is accessed and even modified by TB probing functions in a hidden and sneaky way. This is bad practice and makes the code tricky. Instead explicily pass the vector as function argument so to clarify that the vector is modified inside the functions. No functional change.
This commit is contained in:
committed by
Joona Kiiski
parent
eeb6d923fa
commit
ba1464751d
@@ -39,7 +39,7 @@ namespace Search {
|
|||||||
|
|
||||||
volatile SignalsType Signals;
|
volatile SignalsType Signals;
|
||||||
LimitsType Limits;
|
LimitsType Limits;
|
||||||
std::vector<RootMove> RootMoves;
|
RootMoveVector RootMoves;
|
||||||
Position RootPos;
|
Position RootPos;
|
||||||
Time::point SearchTime;
|
Time::point SearchTime;
|
||||||
StateStackPtr SetupStates;
|
StateStackPtr SetupStates;
|
||||||
@@ -206,9 +206,9 @@ void Search::think() {
|
|||||||
TB::Cardinality = Options["SyzygyProbeLimit"];
|
TB::Cardinality = Options["SyzygyProbeLimit"];
|
||||||
|
|
||||||
// Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality
|
// Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality
|
||||||
if (TB::Cardinality > TB::TBLargest)
|
if (TB::Cardinality > TB::MaxCardinality)
|
||||||
{
|
{
|
||||||
TB::Cardinality = TB::TBLargest;
|
TB::Cardinality = TB::MaxCardinality;
|
||||||
TB::ProbeDepth = DEPTH_ZERO;
|
TB::ProbeDepth = DEPTH_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ void Search::think() {
|
|||||||
{
|
{
|
||||||
// If the current root position is in the tablebases then RootMoves
|
// If the current root position is in the tablebases then RootMoves
|
||||||
// contains only moves that preserve the draw or win.
|
// contains only moves that preserve the draw or win.
|
||||||
TB::RootInTB = Tablebases::root_probe(RootPos, TB::Score);
|
TB::RootInTB = Tablebases::root_probe(RootPos, RootMoves, TB::Score);
|
||||||
|
|
||||||
if (TB::RootInTB)
|
if (TB::RootInTB)
|
||||||
TB::Cardinality = 0; // Do not probe tablebases during the search
|
TB::Cardinality = 0; // Do not probe tablebases during the search
|
||||||
@@ -234,7 +234,7 @@ void Search::think() {
|
|||||||
else // If DTZ tables are missing, use WDL tables as a fallback
|
else // If DTZ tables are missing, use WDL tables as a fallback
|
||||||
{
|
{
|
||||||
// Filter out moves that do not preserve a draw or win
|
// Filter out moves that do not preserve a draw or win
|
||||||
TB::RootInTB = Tablebases::root_probe_wdl(RootPos, TB::Score);
|
TB::RootInTB = Tablebases::root_probe_wdl(RootPos, RootMoves, TB::Score);
|
||||||
|
|
||||||
// Only probe during search if winning
|
// Only probe during search if winning
|
||||||
if (TB::Score <= VALUE_DRAW)
|
if (TB::Score <= VALUE_DRAW)
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ struct RootMove {
|
|||||||
std::vector<Move> pv;
|
std::vector<Move> pv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<RootMove> RootMoveVector;
|
||||||
|
|
||||||
/// 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
|
||||||
@@ -98,7 +99,7 @@ typedef std::auto_ptr<std::stack<StateInfo> > StateStackPtr;
|
|||||||
|
|
||||||
extern volatile SignalsType Signals;
|
extern volatile SignalsType Signals;
|
||||||
extern LimitsType Limits;
|
extern LimitsType Limits;
|
||||||
extern std::vector<RootMove> RootMoves;
|
extern RootMoveVector RootMoves;
|
||||||
extern Position RootPos;
|
extern Position RootPos;
|
||||||
extern Time::point SearchTime;
|
extern Time::point SearchTime;
|
||||||
extern StateStackPtr SetupStates;
|
extern StateStackPtr SetupStates;
|
||||||
|
|||||||
@@ -223,8 +223,8 @@ static void init_tb(char *str)
|
|||||||
entry->num += pcs[i];
|
entry->num += pcs[i];
|
||||||
entry->symmetric = (key == key2);
|
entry->symmetric = (key == key2);
|
||||||
entry->has_pawns = (pcs[TB_WPAWN] + pcs[TB_BPAWN] > 0);
|
entry->has_pawns = (pcs[TB_WPAWN] + pcs[TB_BPAWN] > 0);
|
||||||
if (entry->num > Tablebases::TBLargest)
|
if (entry->num > Tablebases::MaxCardinality)
|
||||||
Tablebases::TBLargest = entry->num;
|
Tablebases::MaxCardinality = entry->num;
|
||||||
|
|
||||||
if (entry->has_pawns) {
|
if (entry->has_pawns) {
|
||||||
struct TBEntry_pawn *ptr = (struct TBEntry_pawn *)entry;
|
struct TBEntry_pawn *ptr = (struct TBEntry_pawn *)entry;
|
||||||
@@ -301,7 +301,7 @@ void Tablebases::init(const std::string& path)
|
|||||||
LOCK_INIT(TB_mutex);
|
LOCK_INIT(TB_mutex);
|
||||||
|
|
||||||
TBnum_piece = TBnum_pawn = 0;
|
TBnum_piece = TBnum_pawn = 0;
|
||||||
TBLargest = 0;
|
MaxCardinality = 0;
|
||||||
|
|
||||||
for (i = 0; i < (1 << TBHASHBITS); i++)
|
for (i = 0; i < (1 << TBHASHBITS); i++)
|
||||||
for (j = 0; j < HSHMAX; j++) {
|
for (j = 0; j < HSHMAX; j++) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Zobrist {
|
|||||||
extern Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
extern Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Tablebases::TBLargest = 0;
|
int Tablebases::MaxCardinality = 0;
|
||||||
|
|
||||||
// Given a position with 6 or fewer pieces, produce a text string
|
// Given a position with 6 or fewer pieces, produce a text string
|
||||||
// of the form KQPvKRP, where "KQP" represents the white pieces if
|
// of the form KQPvKRP, where "KQP" represents the white pieces if
|
||||||
@@ -681,7 +681,7 @@ static Value wdl_to_Value[5] = {
|
|||||||
//
|
//
|
||||||
// A return value false indicates that not all probes were successful and that
|
// A return value false indicates that not all probes were successful and that
|
||||||
// no moves were filtered out.
|
// no moves were filtered out.
|
||||||
bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
bool Tablebases::root_probe(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
|
||||||
{
|
{
|
||||||
int success;
|
int success;
|
||||||
|
|
||||||
@@ -692,8 +692,8 @@ bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
|||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
|
|
||||||
// Probe each move.
|
// Probe each move.
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
Move move = Search::RootMoves[i].pv[0];
|
Move move = rootMoves[i].pv[0];
|
||||||
pos.do_move(move, st, ci, pos.gives_check(move, ci));
|
pos.do_move(move, st, ci, pos.gives_check(move, ci));
|
||||||
int v = 0;
|
int v = 0;
|
||||||
if (pos.checkers() && dtz > 0) {
|
if (pos.checkers() && dtz > 0) {
|
||||||
@@ -713,7 +713,7 @@ bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
|||||||
}
|
}
|
||||||
pos.undo_move(move);
|
pos.undo_move(move);
|
||||||
if (!success) return false;
|
if (!success) return false;
|
||||||
Search::RootMoves[i].score = (Value)v;
|
rootMoves[i].score = (Value)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtain 50-move counter for the root position.
|
// Obtain 50-move counter for the root position.
|
||||||
@@ -729,21 +729,21 @@ bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
|||||||
wdl = (-dtz + cnt50 <= 100) ? -2 : -1;
|
wdl = (-dtz + cnt50 <= 100) ? -2 : -1;
|
||||||
|
|
||||||
// Determine the score to report to the user.
|
// Determine the score to report to the user.
|
||||||
TBScore = wdl_to_Value[wdl + 2];
|
score = wdl_to_Value[wdl + 2];
|
||||||
// If the position is winning or losing, but too few moves left, adjust the
|
// If the position is winning or losing, but too few moves left, adjust the
|
||||||
// score to show how close it is to winning or losing.
|
// score to show how close it is to winning or losing.
|
||||||
// NOTE: int(PawnValueEg) is used as scaling factor in score_to_uci().
|
// NOTE: int(PawnValueEg) is used as scaling factor in score_to_uci().
|
||||||
if (wdl == 1 && dtz <= 100)
|
if (wdl == 1 && dtz <= 100)
|
||||||
TBScore = (Value)(((200 - dtz - cnt50) * int(PawnValueEg)) / 200);
|
score = (Value)(((200 - dtz - cnt50) * int(PawnValueEg)) / 200);
|
||||||
else if (wdl == -1 && dtz >= -100)
|
else if (wdl == -1 && dtz >= -100)
|
||||||
TBScore = -(Value)(((200 + dtz - cnt50) * int(PawnValueEg)) / 200);
|
score = -(Value)(((200 + dtz - cnt50) * int(PawnValueEg)) / 200);
|
||||||
|
|
||||||
// Now be a bit smart about filtering out moves.
|
// Now be a bit smart about filtering out moves.
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
if (dtz > 0) { // winning (or 50-move rule draw)
|
if (dtz > 0) { // winning (or 50-move rule draw)
|
||||||
int best = 0xffff;
|
int best = 0xffff;
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
int v = Search::RootMoves[i].score;
|
int v = rootMoves[i].score;
|
||||||
if (v > 0 && v < best)
|
if (v > 0 && v < best)
|
||||||
best = v;
|
best = v;
|
||||||
}
|
}
|
||||||
@@ -752,33 +752,33 @@ bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
|||||||
// that stay safely within the 50-move budget, if there are any.
|
// that stay safely within the 50-move budget, if there are any.
|
||||||
if (!has_repeated(st.previous) && best + cnt50 <= 99)
|
if (!has_repeated(st.previous) && best + cnt50 <= 99)
|
||||||
max = 99 - cnt50;
|
max = 99 - cnt50;
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
int v = Search::RootMoves[i].score;
|
int v = rootMoves[i].score;
|
||||||
if (v > 0 && v <= max)
|
if (v > 0 && v <= max)
|
||||||
Search::RootMoves[j++] = Search::RootMoves[i];
|
rootMoves[j++] = rootMoves[i];
|
||||||
}
|
}
|
||||||
} else if (dtz < 0) { // losing (or 50-move rule draw)
|
} else if (dtz < 0) { // losing (or 50-move rule draw)
|
||||||
int best = 0;
|
int best = 0;
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
int v = Search::RootMoves[i].score;
|
int v = rootMoves[i].score;
|
||||||
if (v < best)
|
if (v < best)
|
||||||
best = v;
|
best = v;
|
||||||
}
|
}
|
||||||
// Try all moves, unless we approach or have a 50-move rule draw.
|
// Try all moves, unless we approach or have a 50-move rule draw.
|
||||||
if (-best * 2 + cnt50 < 100)
|
if (-best * 2 + cnt50 < 100)
|
||||||
return true;
|
return true;
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
if (Search::RootMoves[i].score == best)
|
if (rootMoves[i].score == best)
|
||||||
Search::RootMoves[j++] = Search::RootMoves[i];
|
rootMoves[j++] = rootMoves[i];
|
||||||
}
|
}
|
||||||
} else { // drawing
|
} else { // drawing
|
||||||
// Try all moves that preserve the draw.
|
// Try all moves that preserve the draw.
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
if (Search::RootMoves[i].score == 0)
|
if (rootMoves[i].score == 0)
|
||||||
Search::RootMoves[j++] = Search::RootMoves[i];
|
rootMoves[j++] = rootMoves[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Search::RootMoves.resize(j, Search::RootMove(MOVE_NONE));
|
rootMoves.resize(j, Search::RootMove(MOVE_NONE));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -788,13 +788,13 @@ bool Tablebases::root_probe(Position& pos, Value& TBScore)
|
|||||||
//
|
//
|
||||||
// A return value false indicates that not all probes were successful and that
|
// A return value false indicates that not all probes were successful and that
|
||||||
// no moves were filtered out.
|
// no moves were filtered out.
|
||||||
bool Tablebases::root_probe_wdl(Position& pos, Value& TBScore)
|
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoveVector& rootMoves, Value& score)
|
||||||
{
|
{
|
||||||
int success;
|
int success;
|
||||||
|
|
||||||
int wdl = Tablebases::probe_wdl(pos, &success);
|
int wdl = Tablebases::probe_wdl(pos, &success);
|
||||||
if (!success) return false;
|
if (!success) return false;
|
||||||
TBScore = wdl_to_Value[wdl + 2];
|
score = wdl_to_Value[wdl + 2];
|
||||||
|
|
||||||
StateInfo st;
|
StateInfo st;
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
@@ -802,23 +802,23 @@ bool Tablebases::root_probe_wdl(Position& pos, Value& TBScore)
|
|||||||
int best = -2;
|
int best = -2;
|
||||||
|
|
||||||
// Probe each move.
|
// Probe each move.
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
Move move = Search::RootMoves[i].pv[0];
|
Move move = rootMoves[i].pv[0];
|
||||||
pos.do_move(move, st, ci, pos.gives_check(move, ci));
|
pos.do_move(move, st, ci, pos.gives_check(move, ci));
|
||||||
int v = -Tablebases::probe_wdl(pos, &success);
|
int v = -Tablebases::probe_wdl(pos, &success);
|
||||||
pos.undo_move(move);
|
pos.undo_move(move);
|
||||||
if (!success) return false;
|
if (!success) return false;
|
||||||
Search::RootMoves[i].score = (Value)v;
|
rootMoves[i].score = (Value)v;
|
||||||
if (v > best)
|
if (v > best)
|
||||||
best = v;
|
best = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
for (size_t i = 0; i < Search::RootMoves.size(); i++) {
|
for (size_t i = 0; i < rootMoves.size(); i++) {
|
||||||
if (Search::RootMoves[i].score == best)
|
if (rootMoves[i].score == best)
|
||||||
Search::RootMoves[j++] = Search::RootMoves[i];
|
rootMoves[j++] = rootMoves[i];
|
||||||
}
|
}
|
||||||
Search::RootMoves.resize(j, Search::RootMove(MOVE_NONE));
|
rootMoves.resize(j, Search::RootMove(MOVE_NONE));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
#ifndef TBPROBE_H
|
#ifndef TBPROBE_H
|
||||||
#define TBPROBE_H
|
#define TBPROBE_H
|
||||||
|
|
||||||
|
#include "../search.h"
|
||||||
|
|
||||||
namespace Tablebases {
|
namespace Tablebases {
|
||||||
|
|
||||||
extern int TBLargest;
|
extern int MaxCardinality;
|
||||||
|
|
||||||
void init(const std::string& path);
|
void init(const std::string& path);
|
||||||
int probe_wdl(Position& pos, int *success);
|
int probe_wdl(Position& pos, int *success);
|
||||||
int probe_dtz(Position& pos, int *success);
|
int probe_dtz(Position& pos, int *success);
|
||||||
bool root_probe(Position& pos, Value& TBScore);
|
bool root_probe(Position& pos, Search::RootMoveVector& rootMoves, Value& score);
|
||||||
bool root_probe_wdl(Position& pos, Value& TBScore);
|
bool root_probe_wdl(Position& pos, Search::RootMoveVector& rootMoves, Value& score);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user