Merge branch 'master' of https://github.com/nodchip/Stockfish into sf-nnue-nodchip

This commit is contained in:
joergoster
2020-06-24 17:47:55 +02:00
70 changed files with 12108 additions and 27 deletions

View File

@@ -965,7 +965,7 @@ moves_loop: // When in check, search starts from here
ss->moveCount = ++moveCount;
if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000)
if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000 && !Limits.silent)
sync_cout << "info depth " << depth
<< " currmove " << UCI::move(move, pos.is_chess960())
<< " currmovenumber " << moveCount + thisThread->pvIdx << sync_endl;
@@ -1531,7 +1531,13 @@ moves_loop: // When in check, search starts from here
prefetch(TT.first_entry(pos.key_after(move)));
// Check for legality just before making the move
if (!pos.legal(move))
if (
#if defined(EVAL_LEARN)
// HACK: pos.piece_on(from_sq(m)) sometimes will be NO_PIECE during machine learning.
!pos.pseudo_legal(move) ||
#endif // EVAL_LEARN
!pos.legal(move)
)
{
moveCount--;
continue;
@@ -1927,3 +1933,315 @@ void Tablebases::rank_root_moves(Position& pos, Search::RootMoves& rootMoves) {
m.tbRank = 0;
}
}
// --- <20>w<EFBFBD>K<EFBFBD><4B><EFBFBD>ɗp<C997><70><EFBFBD><EFBFBD><EFBFBD>Adepth<74>Œ<EFBFBD><C592>T<EFBFBD><54><EFBFBD>Ȃǂ̊֐<CC8A><D690><EFBFBD><EFBFBD>O<EFBFBD><4F><EFBFBD>ɑ΂<C991><CE82>Č<EFBFBD><C48C>J
#if defined (EVAL_LEARN)
namespace Learner
{
// <20>w<EFBFBD>K<EFBFBD>p<EFBFBD>ɁA1<41>‚̃X<CC83><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><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
// <20><><EFBFBD>܂ɂ<DC82><C982>Ďv<C48E><76><EFBFBD>΁AApery<72>̂悤<CC82><E682A4>Searcher<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ăX<C483><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>Ƃɒu<C992><75><EFBFBD>\<5C>Ȃǂ<C882><C782>p<EFBFBD>ӂ<EFBFBD><D382><EFBFBD><EFBFBD>ق<EFBFBD><D982><EFBFBD>
// <20>ǂ<EFBFBD><C782><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>m<EFBFBD><6D><EFBFBD>Ȃ<EFBFBD><C882>B
// <20>w<EFBFBD>K<EFBFBD>̂<EFBFBD><CC82>߂̏<DF82><CC8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
// Learner::search(),Learner::qsearch()<29><><EFBFBD><EFBFBD><EFBFBD>Ăяo<D18F><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
void init_for_search(Position& pos, Stack* ss)
{
// RootNode<64><65>ss->ply == 0<><30><EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD>B
// <20>[<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
std::memset(ss - 7, 0, 10 * sizeof(Stack));
// Search::Limits<74>Ɋւ<C98A><D682><EFBFBD>
// <20><><EFBFBD>̃<EFBFBD><CC83><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
{
auto& limits = Search::Limits;
// <20>T<EFBFBD><54><EFBFBD><EFBFBD>"go infinite"<22>R<EFBFBD>}<7D><><EFBFBD>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>B(time management<6E><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƍ<EFBFBD><C68D><EFBFBD><E982BD>)
limits.infinite = true;
// PV<50><56><EFBFBD>\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǝז<C68E><D796>Ȃ̂ŏ<CC82><C58F><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
limits.silent = true;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD>Ɗe<C68A>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68>nodes<65><73><EFBFBD>ώZ<CF8E><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂Ɣ<CC82><C694>r<EFBFBD><72><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD><DC82>B<EFBFBD><EFBFBD>Ɏg<C98E>p<EFBFBD><70><EFBFBD>Ȃ<EFBFBD><C882>B
limits.nodes = 0;
// depth<74><68><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
limits.depth = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>߂̎萔<CC8E>ň<EFBFBD><C588><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̒l<CC92><6C><EFBFBD>Ԃ<EFBFBD><D482>̂<EFBFBD><CC82>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD>߂ɑ<C991>Ȓl<C892>ɂ<EFBFBD><C982>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
//limits.max_game_ply = 1 << 16;
// <20><><EFBFBD>ʃ<EFBFBD><CA83>[<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
//limits.enteringKingRule = EnteringKingRule::EKR_27_POINT;
}
// DrawValue<75>̐ݒ<CC90>
{
// <20>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>Ƃɗp<C997>ӂ<EFBFBD><D382>ĂȂ<C482><C882>̂<EFBFBD>
// <20><><EFBFBD>̃X<CC83><58><EFBFBD>b<EFBFBD>h<EFBFBD>ŏ㏑<C58F><E38F91><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˂Ȃ<CB82><C882>B<EFBFBD>d<EFBFBD><64><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>B
// <20>ǂ<EFBFBD><C782><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>Ȃ<EFBFBD><C882>A0<41>ɂ<EFBFBD><C982>ׂ<EFBFBD><D782><EFBFBD><EFBFBD>Ǝv<C68E><76><EFBFBD>B
//drawValueTable[REPETITION_DRAW][BLACK] = VALUE_ZERO;
//drawValueTable[REPETITION_DRAW][WHITE] = VALUE_ZERO;
}
// this_thread<61>Ɋւ<C98A><D682>āB
{
auto th = pos.this_thread();
th->completedDepth = 0;
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>
th->nodes = 0;
// history<72>ނ<EFBFBD><DE82>S<EFBFBD><53><EFBFBD>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͏<EFBFBD><CD8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԃ<EFBFBD><D482><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>T<EFBFBD><54><EFBFBD>̐<EFBFBD><CC90>x<EFBFBD>͂ނ<CD82><DE82><EFBFBD><EB89BA><EFBFBD><EFBFBD><EFBFBD>̂őP<C591><50><EFBFBD>͂悭<CD82><EFBFBD><ED82A9><EFBFBD>Ȃ<EFBFBD><C882>B
// th->clear();
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
Color us = pos.side_to_move();
// In analysis mode, adjust contempt in accordance with user preference
if (Limits.infinite || Options["UCI_AnalyseMode"])
ct = Options["Analysis Contempt"] == "Off" ? 0
: Options["Analysis Contempt"] == "Both" ? ct
: Options["Analysis Contempt"] == "White" && us == BLACK ? -ct
: Options["Analysis Contempt"] == "Black" && us == WHITE ? -ct
: ct;
// Evaluation score is from the white point of view
th->contempt = (us == WHITE ? make_score(ct, ct / 2)
: -make_score(ct, ct / 2));
for (int i = 7; i > 0; i--)
(ss - i)->continuationHistory = &th->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel
// rootMoves<65>̐ݒ<CC90>
auto& rootMoves = th->rootMoves;
rootMoves.clear();
for (auto m : MoveList<LEGAL>(pos))
rootMoves.push_back(Search::RootMove(m));
assert(!rootMoves.empty());
//#if defined(USE_GLOBAL_OPTIONS)
// <20>T<EFBFBD><54><EFBFBD>X<EFBFBD><58><EFBFBD>b<EFBFBD>h<EFBFBD><68><EFBFBD>Ƃ̒u<CC92><75><EFBFBD>\<5C>̐<EFBFBD><CC90><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǘ<EFBFBD><C797><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>͂<EFBFBD><CD82>Ȃ̂ŁA
// <20>V<EFBFBD>K<EFBFBD>̒T<CC92><54><EFBFBD>ł<EFBFBD><C582><EFBFBD><E982A9><EFBFBD>A<EFBFBD><41><EFBFBD>̃X<CC83><58><EFBFBD>b<EFBFBD>h<EFBFBD>ɑ΂<C991><CE82><EFBFBD><EFBFBD>u<EFBFBD><75><EFBFBD>\<5C>̐<EFBFBD><CC90><EFBFBD><EFBFBD>𑝂₷<F0919D82>B
//TT.new_search(th->thread_id());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>new_search<63><68><EFBFBD>Ăяo<D18F><6F><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD>O<EFBFBD>̒T<CC92><54><EFBFBD><EFBFBD><EFBFBD>ʂ<EFBFBD><CA82>g<EFBFBD><67><EFBFBD>Ȃ<EFBFBD><C882>đ<EFBFBD><C491>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƃ͂<C682><CD82><EFBFBD><EFBFBD>̂ł́c<CD81>B
// <20><><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD>͂<EFBFBD><CD82><EFBFBD>ɁA<C981>Ăяo<D18F><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ǂ<EFBFBD><C782>Ƃ<EFBFBD>TT.new_search(th->thread_id())<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ׂ<EFBFBD><D782>ł́c<CD81>B
// <20><><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
//#endif
}
}
// <20>ǂ݋؂ƕ]<5D><><EFBFBD>l<EFBFBD>̃y<CC83>A<EFBFBD>BLearner::search(),Learner::qsearch()<29><><EFBFBD>Ԃ<EFBFBD><D482>B
typedef std::pair<Value, std::vector<Move> > ValueAndPV;
// <20>Î~<7E>T<EFBFBD><54><EFBFBD>B
//
// <20>O<EFBFBD><4F><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
// <20>@<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
// <20>@<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
//
// <20>l<EFBFBD>܂<EFBFBD><DC82><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD>́APV<50>z<EFBFBD><7A><EFBFBD><EFBFBD>MOVE_RESIGN<47><4E><EFBFBD>Ԃ<EFBFBD><D482>B
//
// <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>
// <20>u<EFBFBD><75><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>
// <20><><EFBFBD><EFBFBD><EFBFBD>e<EFBFBD><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂ŁA<C581><41><EFBFBD>͈̔͂<CD88><CD82>w<EFBFBD><77><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>̂<EFBFBD><CC82><EFBFBD><EFBFBD>߂邱<DF82>Ƃɂ<C682><C982><EFBFBD><EFBFBD>B
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; // <20>Ƃ肠<C682><E882A0><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
if (pos.is_draw(0)) {
// Return draw value if draw.
return { VALUE_DRAW, {} };
}
// <20>l<EFBFBD>܂<EFBFBD><DC82><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>̂<EFBFBD>
if (MoveList<LEGAL>(pos).size() == 0)
{
// Return the mated value if checkmated.
return { mated_in(/*ss->ply*/ 0 + 1), {} };
}
auto bestValue = ::qsearch<PV>(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, 0);
// <20><><EFBFBD><EFBFBD><EFBFBD>ꂽPV<50><56><EFBFBD>Ԃ<EFBFBD><D482>B
std::vector<Move> pvs;
for (Move* p = &ss->pv[0]; is_ok(*p); ++p)
pvs.push_back(*p);
return ValueAndPV(bestValue, pvs);
}
// <20>ʏ<EFBFBD><CA8F>T<EFBFBD><54><EFBFBD>B<EFBFBD>[<5B><>depth(<28><><EFBFBD><EFBFBD><EFBFBD>Ŏw<C58E><77>)<29>B
// 3<><33><EFBFBD>ǂݎ<C782><DD8E>̃X<CC83>R<EFBFBD>A<EFBFBD><41><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>A
// auto v = search(pos,3);
// <20>̂悤<CC82>ɂ<EFBFBD><C982>ׂ<EFBFBD><D782>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<70><76><EFBFBD>L<EFBFBD><4C><EFBFBD>̂Ƃ<CC82><C682>́Apos.this_thread()->rootMoves[N].pv<70>ɂ<EFBFBD><C982><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"]<5D>̒l<CC92>͖<EFBFBD><CD96><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
//
// <20>O<EFBFBD><4F><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
// <20>@<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
// <20>@<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
ValueAndPV search(Position& pos, int depth_, size_t multiPV /* = 1 */, uint64_t nodesLimit /* = 0 */)
{
std::vector<Move> pvs;
Depth depth = depth_;
if (depth < 0)
return std::pair<Value, std::vector<Move>>(Eval::evaluate(pos), std::vector<Move>());
if (depth == 0)
return qsearch(pos);
Stack stack[MAX_PLY + 10], * ss = stack + 7;
Move pv[MAX_PLY + 1];
init_for_search(pos, ss);
ss->pv = pv; // <20>Ƃ肠<C682><E882A0><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
// this_thread<61>Ɋ֘A<D698><41><EFBFBD><EFBFBD><EFBFBD>ϐ<EFBFBD><CF90>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
auto th = pos.this_thread();
auto& rootDepth = th->rootDepth;
auto& pvIdx = th->pvIdx;
auto& pvLast = th->pvLast;
auto& rootMoves = th->rootMoves;
auto& completedDepth = th->completedDepth;
auto& selDepth = th->selDepth;
// bestmove<76>Ƃ<EFBFBD><C682>Ă<EFBFBD><C482><EFBFBD><EFBFBD>̋ǖʂ̏<CA82><CC8F><EFBFBD>N<EFBFBD>‚<EFBFBD><C282>T<EFBFBD><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40>\
//size_t multiPV = Options["MultiPV"];
// <20><><EFBFBD>̋ǖʂł̎w<CC8E><77><EFBFBD><EFBFBD><EFBFBD>̐<EFBFBD><CC90><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă͂<C482><CD82><EFBFBD><EFBFBD>Ȃ<EFBFBD>
multiPV = std::min(multiPV, rootMoves.size());
// <20>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
nodesLimit *= multiPV;
Value alpha = -VALUE_INFINITE;
Value beta = VALUE_INFINITE;
Value delta = -VALUE_INFINITE;
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>
// <20>T<EFBFBD><54><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<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/ && th->nodes.load(std::memory_order_relaxed) >= nodesLimit)
)
{
for (RootMove& rm : rootMoves)
rm.previousScore = rm.score;
size_t pvFirst = 0;
pvLast = 0;
// MultiPV loop. We perform a full root search for each PV line
for (pvIdx = 0; pvIdx < multiPV && !Threads.stop; ++pvIdx)
{
if (pvIdx == pvLast)
{
pvFirst = pvLast;
for (pvLast++; pvLast < rootMoves.size(); pvLast++)
if (rootMoves[pvLast].tbRank != rootMoves[pvFirst].tbRank)
break;
}
// <20><><EFBFBD><EFBFBD><EA82BC><EFBFBD><EFBFBD>depth<74><68>PV line<6E>ɑ΂<C991><CE82><EFBFBD>USI info<66>ŏo<C58F>͂<EFBFBD><CD82><EFBFBD>selDepth
selDepth = 0;
// depth 5<>ȏ<EFBFBD><C88F>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>Ă<EFBFBD>aspiration search<63>ɐ؂<C990><D882>ւ<EFBFBD><D682><EFBFBD><EFBFBD>B
if (rootDepth >= 5 * 1)
{
delta = Value(20);
Value p = rootMoves[pvIdx].previousScore;
alpha = std::max(p - delta, -VALUE_INFINITE);
beta = std::min(p + delta, VALUE_INFINITE);
}
// aspiration search
int failedHighCnt = 0;
while (true)
{
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt * 1);
bestValue = ::search<PV>(pos, ss, alpha, beta, adjustedDepth, false);
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
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>Ŏw<C58E><EFBFBD><E882B3><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>l<EFBFBD>ɂȂ<C982><C882>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>fail low/high<67><68><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD>break<61><6B><EFBFBD><EFBFBD><EFBFBD>B
if (bestValue <= alpha)
{
beta = (alpha + beta) / 2;
alpha = std::max(bestValue - delta, -VALUE_INFINITE);
failedHighCnt = 0;
//if (mainThread)
// mainThread->stopOnPonderhit = false;
}
else if (bestValue >= beta)
{
beta = std::min(bestValue + delta, VALUE_INFINITE);
++failedHighCnt;
}
else
break;
delta += delta / 4 + 5;
assert(-VALUE_INFINITE <= alpha && beta <= VALUE_INFINITE);
// <20>\<5C><><EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N
//assert(th->nodes.load(std::memory_order_relaxed) <= 1000000 );
}
stable_sort(rootMoves.begin(), rootMoves.begin() + pvIdx + 1);
//my_stable_sort(pos.this_thread()->thread_id() , &rootMoves[0] , pvIdx + 1);
} // multi PV
completedDepth = rootDepth;
}
// <20><><EFBFBD><EFBFBD>PV<50>A<EFBFBD>r<EFBFBD><72><EFBFBD><EFBFBD>NULL_MOVE<56>̉”\<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
// <20><><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<49><4E><EFBFBD>˂<EFBFBD><CB82><EFBFBD><EFBFBD>܂<EFBFBD><DC82>Ă<EFBFBD><C482><EFBFBD>Ƃ͂Ȃ<CD82><C882>B(<28><><EFBFBD>܂̂Ƃ<CC82><C682><EFBFBD>)
for (Move move : rootMoves[0].pv)
{
if (!is_ok(move))
break;
pvs.push_back(move);
}
//sync_cout << rootDepth << sync_endl;
// multiPV<50><56><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD>āArootMoves[0]<5D><>score<72><65>bestValue<75>Ƃ<EFBFBD><C682>ĕԂ<C495><D482>B
bestValue = rootMoves[0].score;
return ValueAndPV(bestValue, pvs);
}
}
#endif