More comment translation

including 11 files in /src
This commit is contained in:
FireFather
2020-06-29 17:31:35 +02:00
committed by nodchip
parent f5cc77bc7c
commit 8f31d74cf6
11 changed files with 293 additions and 293 deletions

View File

@@ -1938,60 +1938,61 @@ void Tablebases::rank_root_moves(Position& pos, Search::RootMoves& rootMoves) {
}
}
// --- <EFBFBD>w<EFBFBD>K<EFBFBD><EFBFBD><EFBFBD>ɗp<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Adepth<EFBFBD>Œ<EFBFBD><EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>Ȃǂ̊֐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>O<EFBFBD><EFBFBD><EFBFBD>ɑ΂<EFBFBD><EFBFBD>Č<EFBFBD><EFBFBD>J
// --- expose the functions such as fixed depth search used for learning to the outside
#if defined (EVAL_LEARN)
namespace Learner
{
// <EFBFBD>w<EFBFBD>K<EFBFBD>p<EFBFBD>ɁA1<EFBFBD>‚̃X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD><EFBFBD>search,qsearch()<29><><EFBFBD>Ăяo<D18F><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȃX<C883>^<5E>u<EFBFBD><75><EFBFBD>p<EFBFBD>ӂ<EFBFBD><D382><EFBFBD><EFBFBD>B
// <EFBFBD><EFBFBD><EFBFBD>܂ɂ<EFBFBD><EFBFBD>Ďv<EFBFBD><EFBFBD><EFBFBD>΁AApery<EFBFBD>̂悤<EFBFBD><EFBFBD>Searcher<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ăX<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>Ƃɒu<EFBFBD><EFBFBD><EFBFBD>\<5C>Ȃǂ<C882><C782>p<EFBFBD>ӂ<EFBFBD><D382><EFBFBD><EFBFBD>ق<EFBFBD><D982><EFBFBD>
// <EFBFBD>ǂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>B
// For learning, prepare a stub that can call search,qsearch() from one thread.
// From now on, it is better to have a Searcher and prepare a substitution table for each thread like Apery.
// It might have been good.
// <EFBFBD>w<EFBFBD>K<EFBFBD>̂<EFBFBD><EFBFBD>߂̏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// Learner::search(),Learner::qsearch()<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// Initialization for learning.
// Called from Learner::search(),Learner::qsearch().
void init_for_search(Position& pos, Stack* ss)
{
// RootNode<EFBFBD><EFBFBD>ss->ply == 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// <EFBFBD>[<5B><><EFBFBD>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>̂ŁAss->ply == 0<>ƂȂ<C682><C882>̂ő<CC82><C591><EFBFBD><EFBFBD>v<EFBFBD>c<EFBFBD>B
// RootNode requires ss->ply == 0.
// Because it clears to zero, ss->ply == 0, so it's okay...
std::memset(ss - 7, 0, 10 * sizeof(Stack));
// Search::Limits<EFBFBD>Ɋւ<EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD>̃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD>[<5B>ϐ<EFBFBD><CF90><EFBFBD>global<61>Ȃ̂ő<CC82><C591>̃X<CC83><58><EFBFBD>b<EFBFBD>h<EFBFBD>ɉe<C989><65><EFBFBD><EFBFBD><EFBFBD>y<EFBFBD>ڂ<EFBFBD><DA82>̂ŋC<C58B><43><EFBFBD>‚<EFBFBD><C282><EFBFBD>ƁB
// About Search::Limits
// Be careful because this member variable is global and affects other threads.
{
auto& limits = Search::Limits;
// <EFBFBD>T<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"go infinite"<22>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>B(time management<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
// Make the search equivalent to the "go infinite" command. (Because it is troublesome if time management is done)
limits.infinite = true;
// PV<EFBFBD><EFBFBD><EFBFBD>\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǝז<C68E><D796>Ȃ̂ŏ<CC82><C58F><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
// Since PV is an obstacle when displayed, erase it.
limits.silent = true;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ɗe<EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD>nodes<EFBFBD><EFBFBD><EFBFBD>ώZ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂Ɣ<EFBFBD><EFBFBD>r<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>B<EFBFBD><EFBFBD>Ɏg<EFBFBD>p<EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>B
// If you use this, it will be compared with the accumulated nodes of each thread. Therefore, do not use it.
limits.nodes = 0;
// depth<EFBFBD><EFBFBD><EFBFBD>ALearner::search()<29>̈<EFBFBD><CC88><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682>ēn<C493><6E><EFBFBD><EFBFBD><EA82BD><EFBFBD>̂ŏ<CC82><C58F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// depth is also processed by the one passed as an argument of Learner::search().
limits.depth = 0;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>߂̎萔<EFBFBD>ň<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̒l<EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><EFBFBD>̂<EFBFBD><EFBFBD>h<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂ɑ<EFBFBD>Ȓl<EFBFBD>ɂ<EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// Set a large value to prevent the draw value from being returned due to the number of moves near the draw.
//limits.max_game_ply = 1 << 16;
// <EFBFBD><EFBFBD><EFBFBD>ʃ<EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>ƈ<EFBFBD><C688><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɂȂ<C982><C882>Č<EFBFBD><C48C><EFBFBD><EFBFBD>‚<EFBFBD><C282>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>B
// If you do not include the ball entry rule, it will be a draw and it will be difficult to settle.
//limits.enteringKingRule = EnteringKingRule::EKR_27_POINT;
}
// DrawValue<EFBFBD>̐ݒ<EFBFBD>
// Set DrawValue
{
// <EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>Ƃɗp<EFBFBD>ӂ<EFBFBD><EFBFBD>ĂȂ<EFBFBD><EFBFBD>̂<EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD>̃X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD>ŏ㏑<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˂Ȃ<EFBFBD><EFBFBD>B<EFBFBD>d<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// <EFBFBD>ǂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>A0<EFBFBD>ɂ<EFBFBD><EFBFBD>ׂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǝv<EFBFBD><EFBFBD><EFBFBD>B
// Because it is not prepared for each thread
// May be overwritten by another thread. There is no help for it.
// If that happens, I think it should be 0.
//drawValueTable[REPETITION_DRAW][BLACK] = VALUE_ZERO;
//drawValueTable[REPETITION_DRAW][WHITE] = VALUE_ZERO;
}
// this_thread<EFBFBD>Ɋւ<EFBFBD><EFBFBD>āB
// Regarding this_thread.
{
auto th = pos.this_thread();
@@ -1999,10 +2000,10 @@ namespace Learner
th->selDepth = 0;
th->rootDepth = 0;
// <20>T<EFBFBD><54><EFBFBD>m<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>̃[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Zero initialization of the number of search nodes
th->nodes = 0;
// history<EFBFBD>ނ<EFBFBD><EFBFBD>S<EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>̐<EFBFBD><EFBFBD>x<EFBFBD>͂ނ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂őP<EFBFBD><EFBFBD><EFBFBD>͂悭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>B
// Clear all history types. This initialization takes a little time, and the accuracy of the search is rather low, so the good and bad are not well understood.
// th->clear();
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
@@ -2023,57 +2024,57 @@ namespace Learner
for (int i = 7; i > 0; i--)
(ss - i)->continuationHistory = &th->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel
// rootMoves<EFBFBD>̐ݒ<EFBFBD>
// set rootMoves
auto& rootMoves = th->rootMoves;
rootMoves.clear();
for (auto m : MoveList<LEGAL>(pos))
for (auto m: MoveList<LEGAL>(pos))
rootMoves.push_back(Search::RootMove(m));
assert(!rootMoves.empty());
//#if defined(USE_GLOBAL_OPTIONS)
// <EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>Ƃ̒u<EFBFBD><EFBFBD><EFBFBD>\<5C>̐<EFBFBD><CC90><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǘ<EFBFBD><C797><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>͂<EFBFBD><CD82>Ȃ̂ŁA
// <EFBFBD>V<EFBFBD>K<EFBFBD>̒T<EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD>̃X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD>ɑ΂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>u<EFBFBD><EFBFBD><EFBFBD>\<5C>̐<EFBFBD><CC90><EFBFBD><EFBFBD>𑝂₷<F0919D82>B
// Since the generation of the substitution table for each search thread should be managed,
// Increase the generation of the substitution table for this thread because it is a new search.
//TT.new_search(th->thread_id());
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>new_search<EFBFBD><EFBFBD><EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>O<EFBFBD>̒T<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʂ<EFBFBD><EFBFBD>g<EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>đ<EFBFBD><EFBFBD>Ƃ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƃ͂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ł́c<EFBFBD>B
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD>͂<EFBFBD><EFBFBD><EFBFBD>ɁA<EFBFBD>Ăяo<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ǂ<EFBFBD><EFBFBD>Ƃ<EFBFBD>TT.new_search(th->thread_id())<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ׂ<EFBFBD><EFBFBD>ł́c<EFBFBD>B
// ↑ If you call new_search here, it may be a loss because you can't use the previous search result.
// Do not do this here, but caller should do TT.new_search(th->thread_id()) for each station ...
// <EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD>̏I<CC8F>ǐ}<7D>Ɏ<EFBFBD><C98E><EFBFBD><EFBFBD>̂<EFBFBD><CC82><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ŁA<C581><41><EFBFBD>t<EFBFBD><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɂ͒u<CD92><75><EFBFBD>\<5C>͑S<CD91>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>ʂŎg<C58E><67><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>B
// →Because we want to avoid reaching the same final diagram, use the substitution table commonly for all threads when generating teachers.
//#endif
}
}
// <EFBFBD>ǂ݋؂ƕ]<5D><><EFBFBD>l<EFBFBD>̃y<CC83>A<EFBFBD>BLearner::search(),Learner::qsearch()<EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><EFBFBD>B
// A pair of reader and evaluation value. Returned by Learner::search(),Learner::qsearch().
typedef std::pair<Value, std::vector<Move> > ValueAndPV;
// <EFBFBD>Î~<7E>T<EFBFBD><54><EFBFBD>B
// Stationary search.
//
// <EFBFBD>O<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) pos.set_this_thread(Threads[thread_id])<EFBFBD>ŒT<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>ݒ肳<EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD>ƁB
// <EFBFBD>@<40>܂<EFBFBD><DC82>AThreads.stop<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƒT<EFBFBD><EFBFBD><EFBFBD>𒆒f<EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>̂ŁA<EFBFBD><EFBFBD><EFBFBD>̂Ƃ<EFBFBD><EFBFBD><EFBFBD>PV<EFBFBD>͐<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><EFBFBD>B
// <EFBFBD>@search()<29><><EFBFBD><EFBFBD><EFBFBD>߂<EFBFBD><DF82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƁAThreads.stop == true<75>Ȃ<EFBFBD><C882>A<EFBFBD><41><EFBFBD>̒T<CC92><54><EFBFBD><EFBFBD><EFBFBD>ʂ<EFBFBD><CA82>p<EFBFBD><70><EFBFBD>Ă͂Ȃ<CD82><C882>Ȃ<EFBFBD><C882>B
// <EFBFBD>@<40><><EFBFBD>ƁA<C681>Ăяo<D18F><6F><EFBFBD>O<EFBFBD>́AThreads.stop == false<73>̏<EFBFBD><CC8F>ԂŌĂяo<D18F><6F><EFBFBD>Ȃ<EFBFBD><C882>ƁA<C681>T<EFBFBD><54><EFBFBD>𒆒f<F0928692><66><EFBFBD>ĕԂ<C495><D482>Ă<EFBFBD><C482>܂<EFBFBD><DC82>̂Œ<CC82><C592>ӁB
// Precondition) Search thread is set by pos.set_this_thread(Threads[thread_id]).
// Also, when Threads.stop arrives, the search is interrupted, so the PV at that time is not correct.
// After returning from search(), if Threads.stop == true, do not use the search result.
// Also, note that before calling, if you do not call it with Threads.stop == false, the search will be interrupted and it will return.
//
// <EFBFBD>l<EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>́APV<EFBFBD>z<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MOVE_RESIGN<EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><EFBFBD>B
// If it is clogged, MOVE_RESIGN is returned in the PV array.
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>alpha,beta<74><61><EFBFBD>w<EFBFBD><77><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EA82AA><EFBFBD>̑<EFBFBD><CC91>ŒT<C592><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682>̌<EFBFBD><CC8C>ʂ<EFBFBD>
// <EFBFBD>u<EFBFBD><EFBFBD><EFBFBD>\<5C>ɏ<EFBFBD><C98F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ނ̂ŁA<C581><41><EFBFBD>̑<EFBFBD><CC91>ɑ΂<C991><CE82>Ď}<7D><><EFBFBD><EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȓl<C892><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82>Ċw<C48A>K<EFBFBD>̂Ƃ<CC82><C682><EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>e<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ŁA<EFBFBD><EFBFBD><EFBFBD>͈̔͂<EFBFBD><EFBFBD>w<EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂邱<EFBFBD>Ƃɂ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
//Although it was possible to specify alpha and beta with arguments, this will show the result when searching in that window
// Because it writes to the substitution table, the value that can be pruned is written to that window when learning
// As it has a bad effect, I decided to stop allowing the window range to be specified.
ValueAndPV qsearch(Position& pos)
{
Stack stack[MAX_PLY + 10], * ss = stack + 7;
Move pv[MAX_PLY + 1];
init_for_search(pos, ss);
ss->pv = pv; // <EFBFBD>Ƃ肠<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>_<EFBFBD>~<7E>[<5B>łǂ<C582><C782><EFBFBD><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Ȃ<EFBFBD><C882>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>B
ss->pv = pv; // For the time being, it must be a dummy and somewhere with a buffer.
if (pos.is_draw(0)) {
// Return draw value if draw.
return { VALUE_DRAW, {} };
}
// <EFBFBD>l<EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD>
// Is it stuck?
if (MoveList<LEGAL>(pos).size() == 0)
{
// Return the mated value if checkmated.
@@ -2082,7 +2083,7 @@ namespace Learner
auto bestValue = ::qsearch<PV>(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, 0);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꂽPV<EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><EFBFBD>B
// Returns the PV obtained.
std::vector<Move> pvs;
for (Move* p = &ss->pv[0]; is_ok(*p); ++p)
pvs.push_back(*p);
@@ -2090,21 +2091,21 @@ namespace Learner
return ValueAndPV(bestValue, pvs);
}
// <EFBFBD>ʏ<EFBFBD><EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>B<EFBFBD>[<5B><>depth(<28><><EFBFBD><EFBFBD><EFBFBD>Ŏw<C58E><77>)<29>B
// 3<EFBFBD><EFBFBD><EFBFBD>ǂݎ<EFBFBD><EFBFBD>̃X<EFBFBD>R<EFBFBD>A<EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>A
// auto v = search(pos,3);
// <EFBFBD>̂悤<EFBFBD>ɂ<EFBFBD><EFBFBD>ׂ<EFBFBD><EFBFBD>B
// v.first<73>ɕ]<5D><><EFBFBD>l<EFBFBD>Av.second<6E><64>PV<50><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// multi pv<EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><EFBFBD><EFBFBD>̂Ƃ<EFBFBD><EFBFBD>́Apos.this_thread()->rootMoves[N].pv<EFBFBD>ɂ<EFBFBD><EFBFBD><EFBFBD>PV(<28>ǂ݋<C782>)<29>̔z<CC94>񂪓<EFBFBD><F182AA93><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// multi pv<70>̎w<CC8E><77><EFBFBD>͂<EFBFBD><CD82>̊֐<CC8A><D690>̈<EFBFBD><CC88><EFBFBD>multiPV<50>ōs<C58D>Ȃ<EFBFBD><C882>B(Options["MultiPV"]<EFBFBD>̒l<EFBFBD>͖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
//
// root<6F>ł̐錾<CC90><E98CBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͂<EFBFBD><CD82>Ȃ<EFBFBD><C882>̂<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʓ|<7C>Ȃ̂<C882>)<29>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>ł͍s<CD8D><73><EFBFBD>Ȃ<EFBFBD><C882>B
// <20>Ăяo<D18F><6F><EFBFBD><EFBFBD><EFBFBD>ŏ<EFBFBD><C58F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƁB
// Normal search. Depth depth (specified as an integer).
// 3 If you want a score for hand reading,
// auto v = search(pos,3);
// Do something like
// Evaluation value is obtained in v.first and PV is obtained in v.second.
// When multi pv is enabled, you can get the PV (reading line) array in pos.this_thread()->rootMoves[N].pv.
// Specify multi pv with the argument multiPV of this function. (The value of Options["MultiPV"] is ignored)
//
// <EFBFBD>O<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>) pos.set_this_thread(Threads[thread_id])<29>ŒT<C592><54><EFBFBD>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>ݒ肳<DD92><E882B3><EFBFBD>Ă<EFBFBD><C482><EFBFBD>ƁB
// <EFBFBD>@<40>܂<EFBFBD><DC82>AThreads.stop<6F><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƒT<C692><54><EFBFBD>𒆒f<F0928692><66><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD><DC82>̂ŁA<C581><41><EFBFBD>̂Ƃ<CC82><C682><EFBFBD>PV<50>͐<EFBFBD><CD90><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>B
// <20>@search()<29><><EFBFBD><EFBFBD><EFBFBD>߂<EFBFBD><DF82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƁAThreads.stop == true<75>Ȃ<EFBFBD><C882>A<EFBFBD><41><EFBFBD>̒T<CC92><54><EFBFBD><EFBFBD><EFBFBD>ʂ<EFBFBD><CA82>p<EFBFBD><70><EFBFBD>Ă͂Ȃ<CD82><C882>Ȃ<EFBFBD><C882>B
// <EFBFBD>@<40><><EFBFBD>ƁA<C681>Ăяo<D18F><6F><EFBFBD>O<EFBFBD>́AThreads.stop == false<73>̏<EFBFBD><CC8F>ԂŌĂяo<D18F><6F><EFBFBD>Ȃ<EFBFBD><C882>ƁA<C681>T<EFBFBD><54><EFBFBD>𒆒f<F0928692><66><EFBFBD>ĕԂ<C495><D482>Ă<EFBFBD><C482>܂<EFBFBD><DC82>̂Œ<CC82><C592>ӁB
// Declaration win judgment is not done as root (because it is troublesome to handle), so it is not done here.
// Handle it by the caller.
//
// Precondition) Search thread is set by pos.set_this_thread(Threads[thread_id]).
// Also, when Threads.stop arrives, the search is interrupted, so the PV at that time is not correct.
// After returning from search(), if Threads.stop == true, do not use the search result.
// Also, note that before calling, if you do not call it with Threads.stop == false, the search will be interrupted and it will return.
ValueAndPV search(Position& pos, int depth_, size_t multiPV /* = 1 */, uint64_t nodesLimit /* = 0 */)
{
@@ -2122,9 +2123,9 @@ namespace Learner
init_for_search(pos, ss);
ss->pv = pv; // <EFBFBD>Ƃ肠<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>_<EFBFBD>~<7E>[<5B>łǂ<C582><C782><EFBFBD><EFBFBD>o<EFBFBD>b<EFBFBD>t<EFBFBD>@<40><><EFBFBD>Ȃ<EFBFBD><C882>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>B
ss->pv = pv; // For the time being, it must be a dummy and somewhere with a buffer.
// this_thread<EFBFBD>Ɋ֘A<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϐ<EFBFBD><EFBFBD>̏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Initialize the variables related to this_thread
auto th = pos.this_thread();
auto& rootDepth = th->rootDepth;
auto& pvIdx = th->pvIdx;
@@ -2133,13 +2134,13 @@ namespace Learner
auto& completedDepth = th->completedDepth;
auto& selDepth = th->selDepth;
// bestmove<EFBFBD>Ƃ<EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̋ǖʂ̏<EFBFBD><EFBFBD><EFBFBD>N<EFBFBD>‚<EFBFBD><EFBFBD>T<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40>\
//size_t multiPV = Options["MultiPV"];
// A function to search the top N of this stage as best move
//size_t multiPV = Options["MultiPV"];
// <EFBFBD><EFBFBD><EFBFBD>̋ǖʂł̎w<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̐<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă͂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD>
// Do not exceed the number of moves in this situation
multiPV = std::min(multiPV, rootMoves.size());
// <EFBFBD>m<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MultiPV<50>̒l<CC92><6C><EFBFBD>|<7C><><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>ƁAdepth<74>Œ<EFBFBD><C592>AMultiPV<50><56><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD>1<EFBFBD>‚̌<C282><CC8C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɓ<EFBFBD><C993><EFBFBD>node<64><65><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƂɂȂ<C982><C882>Ȃ<EFBFBD><C882>B
// If you do not multiply the node limit by the value of MultiPV, you will not be thinking about the same node for one candidate hand when you fix the depth and have MultiPV.
nodesLimit *= multiPV;
Value alpha = -VALUE_INFINITE;
@@ -2148,9 +2149,9 @@ namespace Learner
Value bestValue = -VALUE_INFINITE;
while ((rootDepth += 1) <= depth
// node<64><65><EFBFBD><EFBFBD><EFBFBD>𒴂<EFBFBD><F092B482><EFBFBD><EFBFBD><EFBFBD><EA8D87><EFBFBD><EFBFBD><EFBFBD>̃<EFBFBD><CC83>[<5B>v<EFBFBD>𔲂<EFBFBD><F094B282><EFBFBD>
// <EFBFBD>T<EFBFBD><EFBFBD><EFBFBD>m<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>́A<CD81><41><EFBFBD>̊֐<CC8A><D690>̈<EFBFBD><CC88><EFBFBD><EFBFBD>œn<C593><6E><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
&& !(nodesLimit /*node<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/ && th->nodes.load(std::memory_order_relaxed) >= nodesLimit)
// exit this loop even if the node limit is exceeded
// The number of search nodes is passed in the argument of this function.
&& !(nodesLimit /* limited nodes */ && th->nodes.load(std::memory_order_relaxed) >= nodesLimit)
)
{
for (RootMove& rm : rootMoves)
@@ -2170,10 +2171,10 @@ namespace Learner
break;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>depth<EFBFBD><EFBFBD>PV line<6E>ɑ΂<C991><CE82><EFBFBD>USI info<66>ŏo<C58F>͂<EFBFBD><CD82><EFBFBD>selDepth
// selDepth output with USI info for each depth and PV line
selDepth = 0;
// depth 5<>ȏ<EFBFBD><C88F>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>Ă<EFBFBD>aspiration search<63>ɐ؂<C990><D882>ւ<EFBFBD><D682><EFBFBD><EFBFBD>B
// Switch to aspiration search for depth 5 and above.
if (rootDepth >= 5 * 1)
{
delta = Value(20);
@@ -2194,8 +2195,8 @@ namespace Learner
stable_sort(rootMoves.begin() + pvIdx, rootMoves.end());
//my_stable_sort(pos.this_thread()->thread_id(),&rootMoves[0] + pvIdx, rootMoves.size() - pvIdx);
// fail low/high<67>ɑ΂<C991><CE82><EFBFBD>aspiration window<6F><77><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD>B
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŏw<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD>ɂȂ<EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><EFBFBD><EFBFBD><EFBFBD>fail low/high<67><68><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD>break<61><6B><EFBFBD><EFBFBD><EFBFBD>B
// Expand aspiration window for fail low/high.
// However, if it is the value specified by the argument, it will be treated as fail low/high and break.
if (bestValue <= alpha)
{
beta = (alpha + beta) / 2;
@@ -2217,7 +2218,7 @@ namespace Learner
delta += delta / 4 + 5;
assert(-VALUE_INFINITE <= alpha && beta <= VALUE_INFINITE);
// <EFBFBD>\<5C><><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
// runaway check
//assert(th->nodes.load(std::memory_order_relaxed) <= 1000000 );
}
@@ -2229,9 +2230,9 @@ namespace Learner
completedDepth = rootDepth;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>PV<EFBFBD>A<EFBFBD>r<EFBFBD><EFBFBD><EFBFBD><EFBFBD>NULL_MOVE<EFBFBD>̉”\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E982A9><EFBFBD>m<EFBFBD><6D><EFBFBD>Ȃ<EFBFBD><C882>̂Ŕr<C594><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂<EFBFBD>is_ok()<29><><EFBFBD>ʂ<EFBFBD><CA82>B
// <EFBFBD><EFBFBD><EFBFBD>@PV<50>Ȃ̂<C882>NULL_MOVE<56>͂<EFBFBD><CD82>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>ƂɂȂ<C982><C882>Ă<EFBFBD><C482><EFBFBD><EFBFBD>͂<EFBFBD><CD82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A
// MOVE_WIN<EFBFBD><EFBFBD><EFBFBD>˂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>Ă<EFBFBD><EFBFBD><EFBFBD>Ƃ͂Ȃ<EFBFBD><EFBFBD>B(<28><><EFBFBD>܂̂Ƃ<CC82><C682><EFBFBD>)
// Pass PV_is(ok) to eliminate this PV, there may be NULL_MOVE in the middle.
// → PV should not be NULL_MOVE because it is PV
// MOVE_WIN has never been thrust. (For now)
for (Move move : rootMoves[0].pv)
{
if (!is_ok(move))
@@ -2241,7 +2242,7 @@ namespace Learner
//sync_cout << rootDepth << sync_endl;
// multiPV<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>āArootMoves[0]<5D><>score<72><65>bestValue<75>Ƃ<EFBFBD><C682>ĕԂ<C495><D482>B
// Considering multiPV, the score of rootMoves[0] is returned as bestValue.
bestValue = rootMoves[0].score;
return ValueAndPV(bestValue, pvs);