Skip to content

Commit

Permalink
- RootMoveにscoreLowerboundとscoreUpperboundを追加。RootMove::score→usiScor…
Browse files Browse the repository at this point in the history
…eに追加。

- USI::pv()の引数のalpha,beta削除。
  • Loading branch information
yaneurao committed Oct 13, 2023
1 parent 551e22c commit 6647eda
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 14 deletions.
39 changes: 32 additions & 7 deletions source/engine/yaneuraou-engine/yaneuraou-search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ void MainThread::search()
rootMoves[0].score = mated_in(0);

if (!Limits.silent)
sync_cout << USI::pv(rootPos, 1 , -VALUE_INFINITE, VALUE_INFINITE) << sync_endl;
sync_cout << USI::pv(rootPos, 1) << sync_endl;

goto SKIP_SEARCH;
}
Expand Down Expand Up @@ -544,7 +544,7 @@ void MainThread::search()

// rootで宣言勝ちのときにもそのPVを出力したほうが良い。
if (!Limits.silent)
sync_cout << USI::pv(rootPos, 1 , -VALUE_INFINITE, VALUE_INFINITE) << sync_endl;
sync_cout << USI::pv(rootPos, 1) << sync_endl;

goto SKIP_SEARCH;
}
Expand Down Expand Up @@ -637,7 +637,7 @@ SKIP_SEARCH:;
// → いずれにせよ、mateを見つけた時に最終的なPVを出力していないと、詰みではないscoreのPVが最終的な読み筋としてGUI上に
// 残ることになるからよろしくない。PV自体は必ず出力すべきなのでは。
if (/*bestThread != this &&*/ !Limits.silent && !Limits.consideration_mode)
sync_cout << USI::pv(bestThread->rootPos, bestThread->completedDepth, -VALUE_INFINITE, VALUE_INFINITE) << sync_endl;
sync_cout << USI::pv(bestThread->rootPos, bestThread->completedDepth) << sync_endl;

output_final_pv_done = true;
}
Expand Down Expand Up @@ -1000,10 +1000,20 @@ void Thread::search()

while (true)
{
// Adjust the effective depth searched, but ensure at least one effective increment for every
// four searchAgain steps (see issue #2717).

// fail highするごとにdepthを下げていく処理
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt - searchAgainCounter);
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt - 3 * (searchAgainCounter + 1) / 4);
bestValue = ::search<Root>(rootPos, ss, alpha, beta, adjustedDepth, false);

// Bring the best move to the front. It is critical that sorting
// is done with a stable algorithm because all the values but the
// first and eventually the new best one is set to -VALUE_INFINITE
// and we want to keep the same order for all the moves except the
// new PV that goes to the front. Note that in the case of MultiPV
// search the already searched PV lines are preserved.

// それぞれの指し手に対するスコアリングが終わったので並べ替えおく。
// 一つ目の指し手以外は-VALUE_INFINITEが返る仕様なので並べ替えのために安定ソートを
// 用いないと前回の反復深化の結果によって得た並び順を変えてしまうことになるのでまずい。
Expand All @@ -1022,6 +1032,8 @@ void Thread::search()
// fail low/highしたときの読み筋は役に立たないであろうという考え。
&& multiPV == 1
&& (bestValue <= alpha || bestValue >= beta)

// 以下、やねうら王独自拡張。
&& Time.elapsed() > 3000
// 将棋所のコンソールが詰まるのを予防するために出力を少し抑制する。
// また、go infiniteのときは、検討モードから使用しているわけで、PVは必ず出力する。
Expand All @@ -1034,7 +1046,7 @@ void Thread::search()
{
// 最後に出力した時刻を記録しておく。
mainThread->lastPvInfoTime = Time.elapsed();
sync_cout << USI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
sync_cout << USI::pv(rootPos, rootDepth) << sync_endl;
}

// aspiration窓の範囲外
Expand Down Expand Up @@ -1102,7 +1114,7 @@ void Thread::search()
&& (rootDepth < 3 || mainThread->lastPvInfoTime + Limits.pv_interval <= Time.elapsed())))
{
mainThread->lastPvInfoTime = Time.elapsed();
sync_cout << USI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
sync_cout << USI::pv(rootPos, rootDepth) << sync_endl;
}
}

Expand Down Expand Up @@ -2698,8 +2710,21 @@ namespace {
// root nodeにおいてPVの指し手または、α値を更新した場合、スコアをセットしておく。
// (iterationの終わりでsortするのでそのときに指し手が入れ替わる。)

rm.score = value;
rm.score = rm.usiScore = value;
rm.selDepth = thisThread->selDepth;
rm.scoreLowerbound = rm.scoreUpperbound = false;

if (value >= beta)
{
rm.scoreLowerbound = true;
rm.usiScore = beta;
}
else if (value <= alpha)
{
rm.scoreUpperbound = true;
rm.usiScore = alpha;
}

rm.pv.resize(1);
// PVは変化するはずなのでいったんリセット

Expand Down
14 changes: 13 additions & 1 deletion source/search.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef _SEARCH_H_INCLUDED_
#define _SEARCH_H_INCLUDED_

#include <cstdint>
#include <vector>

#include "config.h"
#include "misc.h"
#include "movepick.h"
Expand Down Expand Up @@ -70,6 +73,15 @@ namespace Search {
// aspiration searchの時に用いる。previousScoreの移動平均。
Value averageScore = -VALUE_INFINITE;

// USIに出力する用のscore
Value usiScore = -VALUE_INFINITE;

// usiScoreはlowerboundになっているのか。
bool scoreLowerbound = false;

// usiScoreはupperboundになっているのか。
bool scoreUpperbound = false;

// このスレッドがrootから最大、何手目まで探索したか(選択深さの最大)
int selDepth = 0;

Expand All @@ -81,7 +93,7 @@ namespace Search {
std::vector<Move> pv;
};

typedef std::vector<RootMove> RootMoves;
using RootMoves = std::vector<RootMove>;

// goコマンドでの探索時に用いる、持ち時間設定などが入った構造体
// "ponder"のフラグはここに含まれず、Threads.ponderにあるので注意。
Expand Down
10 changes: 5 additions & 5 deletions source/usi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ namespace USI
// --------------------

// depth : iteration深さ
std::string pv(const Position& pos, Depth depth, Value alpha, Value beta)
std::string pv(const Position& pos, Depth depth)
{
#if defined(YANEURAOU_ENGINE_DEEP)
// ふかうら王では、この関数呼び出さないからまるっと要らない。
Expand All @@ -171,7 +171,7 @@ namespace USI
#endif
const auto& rootMoves = pos.this_thread()->rootMoves;
size_t pvIdx = pos.this_thread()->pvIdx;
size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size());
size_t multiPV = std::min(size_t(Options["MultiPV"]), rootMoves.size());

uint64_t nodes_searched = Threads.nodes_searched();

Expand All @@ -186,7 +186,7 @@ namespace USI

// 1より小さな探索depthで出力しない。
Depth d = updated ? depth : std::max(1, depth - 1);
Value v = updated ? rootMoves[i].score : rootMoves[i].previousScore;
Value v = updated ? rootMoves[i].usiScore : rootMoves[i].previousScore;

// multi pv時、例えば3個目の候補手までしか評価が終わっていなくて(PVIdx==2)、このとき、
// 3,4,5個目にあるのは前回のiterationまでずっと評価されていなかった指し手であるような場合に、
Expand All @@ -210,8 +210,8 @@ namespace USI
;

// これが現在探索中の指し手であるなら、それがlowerboundかupperboundかは表示させる
if (i == pvIdx)
ss << (v >= beta ? " lowerbound" : v <= alpha ? " upperbound" : "");
if (i == pvIdx && /*!tb &&*/ updated) // tablebase- and previous-scores are exact
ss << (rootMoves[i].scoreLowerbound ? " lowerbound" : (rootMoves[i].scoreUpperbound ? " upperbound" : ""));

// 将棋所はmultipvに対応していないが、とりあえず出力はしておく。
if (multiPV > 1)
Expand Down
2 changes: 1 addition & 1 deletion source/usi.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ namespace USI

// pv(読み筋)をUSIプロトコルに基いて出力する。
// depth : 反復深化のiteration深さ。
std::string pv(const Position& pos, Depth depth, Value alpha, Value beta);
std::string pv(const Position& pos, Depth depth);

// 局面posとUSIプロトコルによる指し手を与えて
// もし可能なら等価で合法な指し手を返す。
Expand Down

0 comments on commit 6647eda

Please sign in to comment.