Skip to content

Commit

Permalink
- 定跡にhitした時の最後のPV出力で、評価値が0になっていたのを定跡の評価値を出力するように修正した。
Browse files Browse the repository at this point in the history
  - 定跡DBの評価値はcpで、そこからValue型に逆変換したあと、再度cpに変換して出力するので変換誤差が出て1違うことがあるが、まあ気にしないで…。
- 定跡にhitしたときのmultipvでの出力、"pv ..."のところ、スペースが2つになっていたのを修正。
  • Loading branch information
yaneurao committed Dec 16, 2023
1 parent aaccad5 commit fdd95f9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
32 changes: 23 additions & 9 deletions source/book/book.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,8 @@ namespace Book

// さらに指し手を進める
Move16 bestMove16, ponderMove16;
if (probe_impl(pos, true, bestMove16, ponderMove16 , true /* 強制的にhitさせる */))
Value value;
if (probe_impl(pos, true, bestMove16, ponderMove16, value, true /* 強制的にhitさせる */))
{
// hitした

Expand Down Expand Up @@ -1122,7 +1123,7 @@ namespace Book
}

// probe()の下請け
bool BookMoveSelector::probe_impl(Position& rootPos, bool silent , Move16& bestMove , Move16& ponderMove , bool forceHit)
bool BookMoveSelector::probe_impl(Position& rootPos, bool silent , Move16& bestMove , Move16& ponderMove , Value& value, bool forceHit)
{
if (!forceHit)
{
Expand Down Expand Up @@ -1212,7 +1213,7 @@ namespace Book
<< " multipv " << (i + 1)
#endif
<< " score cp " << it.value << " depth " << it.depth
<< " pv " << pv_builder(rootPos, it.move, pv_moves)
<< " pv" << pv_builder(rootPos, it.move, pv_moves)
<< " (" << fixed << std::setprecision(2) << (100 * it.move_count / double(move_count_total)) << "%" << ")" // 採択確率
<< sync_endl;

Expand Down Expand Up @@ -1336,6 +1337,7 @@ namespace Book

bestMove = bestBookMove.move;
ponderMove = bestBookMove.ponder;
value = Value(bestBookMove.value);

// ponderが登録されていなければ、bestMoveで一手進めてそこの局面のbestを拾ってくる。
if (!is_ok((Move)ponderMove.to_u16()))
Expand Down Expand Up @@ -1367,7 +1369,8 @@ namespace Book
{
const bool silent = true;
Move16 bestMove16, ponderMove16;
if (!probe_impl(pos, silent, bestMove16, ponderMove16))
Value value;
if (!probe_impl(pos, silent, bestMove16, ponderMove16, value))
return MOVE_NONE;

Move bestMove = pos.to_move(bestMove16);
Expand All @@ -1386,8 +1389,9 @@ namespace Book
return false;

Move16 bestMove16, ponderMove16;
Value value;
auto& pos = th.rootPos;
if (probe_impl(pos , Limits.silent, bestMove16, ponderMove16))
if (probe_impl(pos , Limits.silent, bestMove16, ponderMove16, value))
{
auto & rootMoves = th.rootMoves;

Expand All @@ -1409,7 +1413,17 @@ namespace Book
// この意味では、
// MultiPVでの探索の時は定跡の上位の指し手をrootMoves[0..N-1]に反映させたほうが良いかも?

std::swap(rootMoves[0], *it_move);
auto& r = rootMoves[0];
std::swap(r, *it_move);

// 定跡の評価値はcp(centi-pawn)のはずだから、
// この逆変換をしたものを設定してやる。そうすると出力するときにcpに変換されてちょうど良くなる。
// ⇨ 出力する逆変換の時の誤差あるの少し気持ち悪いか…。まあ仕方ないな…。定跡ファイルがcp単位になってるからな…。
// これは次のaspiration searchで少し探索効率が良くなるから、設定はしたいが…。

value = std::clamp(value , VALUE_MATED_IN_MAX_PLY , VALUE_MATE_IN_MAX_PLY);
r.previousScore = r.usiScore = r.score = USI::cp_to_value(value);
// ⇨ 定跡の評価値0になってる方が、嬉しい意味もあるか…。

// 2手目の指し手も与えないとponder出来ない。
// 定跡ファイルに2手目が書いてあったなら、それをponder用に出力する。
Expand All @@ -1418,13 +1432,13 @@ namespace Book
// 普通の指し手でなければならない。これは、is_ok(Move)で判定できる。)
if (is_ok((Move)ponderMove16.to_u16()))
{
if (rootMoves[0].pv.size() <= 1)
rootMoves[0].pv.push_back(MOVE_NONE);
if (r.pv.size() <= 1)
r.pv.push_back(MOVE_NONE);

// これ32bit Moveに変換してあげるほうが親切なのか…。
StateInfo si;
pos.do_move(bestMove,si);
rootMoves[0].pv[1] = pos.to_move(ponderMove16);
r.pv[1] = pos.to_move(ponderMove16);
pos.undo_move(bestMove);
}
// この指し手を指す
Expand Down
7 changes: 6 additions & 1 deletion source/book/book.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,12 @@ namespace Book
// bestMoveが合法手であることは保証される。
// GenerateAllLegalMovesがfalseの時、歩の不成の指し手を返さないことも保証する。
// 但し、ponderMoveが合法手であることは保証しない。
bool probe_impl(Position& rootPos, bool silent, Move16& bestMove, Move16& ponderMove , bool forceHit = false);
//
// 以下の3つの変数は、この関数がtrueを返した時のみ有効。
// bestMove : 今回選択された指し手
// ponderMove : bestMoveの次の定跡の指し手
// value : bestMoveの評価値。
bool probe_impl(Position& rootPos, bool silent, Move16& bestMove, Move16& ponderMove , Value& value , bool forceHit = false);

// 定跡のpv文字列を生成して返す。
// m : 局面posをこの指し手で進める
Expand Down
7 changes: 7 additions & 0 deletions source/usi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,12 @@ int USI::to_cp(Value v) {
return 100 * v / USI::NormalizeToPawnValue;
}

// cpからValueへ。⇑の逆変換。
Value USI::cp_to_value(int v)
{
return Value((abs(v) < VALUE_MATE_IN_MAX_PLY) ? (USI::NormalizeToPawnValue * v / 100) : v);
}

// スコアを歩の価値を100として正規化して出力する。
// USE_PIECE_VALUEが定義されていない時は正規化しようがないのでこの関数は呼び出せない。
std::string USI::value(Value v)
Expand All @@ -1183,6 +1189,7 @@ std::string USI::value(Value v)

return ss.str();
}

#endif

// Square型をUSI文字列に変換する
Expand Down
4 changes: 4 additions & 0 deletions source/usi.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,15 @@ namespace USI
// Valueをcp(centi-pawn)に変換する。
int to_cp(Value v);

// cpからValueへ。⇑の逆変換。
Value cp_to_value(int v);

// USIプロトコルの形式でValue型を出力する。
// 歩が100になるように正規化するので、operator <<(Value)をこういう仕様にすると
// 実際の値と異なる表示になりデバッグがしにくくなるから、そうはしていない。
// USE_PIECE_VALUEが定義されていない時は正規化しようがないのでこの関数は呼び出せない。
std::string value(Value v);

#endif

// Square型をUSI文字列に変換する
Expand Down

0 comments on commit fdd95f9

Please sign in to comment.