1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 09:13:08 +00:00

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

@ -945,7 +945,7 @@ ExtBonaPiece kpp_board_index[PIECE_NB] = {
{ f_king, e_king },
{ BONA_PIECE_ZERO, BONA_PIECE_ZERO },
// 後手から見た場合。fとeが入れ替わる。
// When viewed from behind. f and e are exchanged.
{ BONA_PIECE_ZERO, BONA_PIECE_ZERO },
{ e_pawn, f_pawn },
{ e_knight, f_knight },
@ -953,11 +953,11 @@ ExtBonaPiece kpp_board_index[PIECE_NB] = {
{ e_rook, f_rook },
{ e_queen, f_queen },
{ e_king, f_king },
{ BONA_PIECE_ZERO, BONA_PIECE_ZERO }, // 金の成りはない
{ BONA_PIECE_ZERO, BONA_PIECE_ZERO }, // no money
};
// 内部で保持しているpieceListFw[]が正しいBonaPieceであるかを検査する。
// 注 : デバッグ用。遅い。
// Check whether the pieceListFw[] held internally is a correct BonaPiece.
// Note: For debugging. slow.
bool EvalList::is_valid(const Position& pos)
{
std::set<PieceNumber> piece_numbers;
@ -973,28 +973,28 @@ bool EvalList::is_valid(const Position& pos)
for (int i = 0; i < length(); ++i)
{
BonaPiece fw = pieceListFw[i];
// このfwが本当に存在するかをPositionクラスのほうに調べに行く。
// Go to the Position class to see if this fw really exists.
if (fw == Eval::BONA_PIECE_ZERO) {
continue;
}
// 範囲外
// Out of range
if (!(0 <= fw && fw < fe_end))
return false;
// 盤上の駒なのでこの駒が本当に存在するか調べにいく。
// Since it is a piece on the board, I will check if this piece really exists.
for (Piece pc = NO_PIECE; pc < PIECE_NB; ++pc)
{
auto pt = type_of(pc);
if (pt == NO_PIECE_TYPE || pt == 7) // 存在しない駒
if (pt == NO_PIECE_TYPE || pt == 7) // non-existing piece
continue;
// 駒pcのBonaPieceの開始番号
// BonaPiece start number of piece pc
auto s = BonaPiece(kpp_board_index[pc].fw);
if (s <= fw && fw < s + SQUARE_NB)
{
// 見つかったのでこの駒がsqの地点にあるかを調べる。
// Since it was found, check if this piece is at sq.
Square sq = (Square)(fw - s);
Piece pc2 = pos.piece_on(sq);
@ -1004,7 +1004,7 @@ bool EvalList::is_valid(const Position& pos)
goto Found;
}
}
// 何故か存在しない駒であった..
// It was a piece that did not exist for some reason..
return false;
Found:;
}

View file

@ -38,39 +38,39 @@ void evaluate_with_no_return(const Position& pos);
Value compute_eval(const Position& pos);
#if defined(EVAL_NNUE) || defined(EVAL_LEARN)
// 評価関数ファイルを読み込む。
// これは、"is_ready"コマンドの応答時に1度だけ呼び出される。2度呼び出すことは想定していない。
// (ただし、EvalDir(評価関数フォルダ)が変更になったあと、isreadyが再度送られてきたら読みなおす。)
// Read the evaluation function file.
// This is only called once in response to the "is_ready" command. It is not supposed to be called twice.
// (However, if isready is sent again after EvalDir (evaluation function folder) has been changed, read it again.)
void load_eval();
static uint64_t calc_check_sum() {return 0;}
static void print_softname(uint64_t check_sum) {}
// --- 評価関数で使う定数 KPP(玉と任意2駒)のPに相当するenum
// --- enum corresponding to P of constant KPP (ball and arbitrary 2 pieces) used in evaluation function
// (評価関数の実験のときには、BonaPieceは自由に定義したいのでここでは定義しない。)
// (BonaPiece wants to define freely in experiment of evaluation function, so I don't define it here.)
// BonanzaでKKP/KPPと言うときのP(Piece)を表現する型。
// Σ KPPを求めるときに、39の地点の歩のように、升×駒種に対して一意な番号が必要となる。
// A type that represents P(Piece) when calling KKP/KPP in Bonanza.
// When you ask for ƒ° KPP, you need a unique number for each box <20>~ piece type, like the step at 39 points.
enum BonaPiece : int32_t
{
// f = friend(≒先手)の意味。e = enemy(≒後手)の意味
// Meaning of f = friend (<28>àfirst move). Meaning of e = enemy (<28>àrear)
// 未初期化の時の値
// Value when uninitialized
BONA_PIECE_NOT_INIT = -1,
// 無効な駒。駒落ちのときなどは、不要な駒をここに移動させる。
// Invalid piece. When you drop a piece, move unnecessary pieces here.
BONA_PIECE_ZERO = 0,
fe_hand_end = BONA_PIECE_ZERO + 1,
// Bonanzaのように盤上のありえない升の歩や香の番号を詰めない。
// 理由1) 学習のときに相対PPで1段目に香がいるときがあって、それを逆変換において正しく表示するのが難しい。
// 理由2) 縦型BitboardだとSquareからの変換に困る。
// Don't pack the numbers of unrealistic walks and incense on the board like Bonanza.
// Reason 1) When learning, there are times when the incense is on the first stage in relative PP, and it is difficult to display it correctly in the inverse transformation.
// Reason 2) It is difficult to convert from Square with vertical Bitboard.
// --- 盤上の駒
// --- Pieces on the board
f_pawn = fe_hand_end,
e_pawn = f_pawn + SQUARE_NB,
f_knight = e_pawn + SQUARE_NB,
@ -84,7 +84,7 @@ enum BonaPiece : int32_t
fe_end = e_queen + SQUARE_NB,
f_king = fe_end,
e_king = f_king + SQUARE_NB,
fe_end2 = e_king + SQUARE_NB, // 玉も含めた末尾の番号。
fe_end2 = e_king + SQUARE_NB, // Last number including balls.
};
#define ENABLE_INCR_OPERATORS_ON(T) \
@ -95,8 +95,8 @@ ENABLE_INCR_OPERATORS_ON(BonaPiece)
#undef ENABLE_INCR_OPERATORS_ON
// BonaPieceを後手から見たとき(先手の39の歩を後手から見ると後手の71の歩)の番号とを
// ペアにしたものをExtBonaPiece型と呼ぶことにする。
// The number when you look at BonaPiece from the back (the number of steps from the previous 39 to the number 71 from the back)
// Let's call the paired one the ExtBonaPiece type.
union ExtBonaPiece
{
struct {
@ -109,28 +109,28 @@ union ExtBonaPiece
ExtBonaPiece(BonaPiece fw_, BonaPiece fb_) : fw(fw_), fb(fb_) {}
};
// 駒が今回の指し手によってどこからどこに移動したのかの情報。
// 駒はExtBonaPiece表現であるとする。
// Information about where the piece has moved from where to by this move.
// Assume the piece is an ExtBonaPiece expression.
struct ChangedBonaPiece
{
ExtBonaPiece old_piece;
ExtBonaPiece new_piece;
};
// KPPテーブルの盤上の駒pcに対応するBonaPieceを求めるための配列。
// )
// BonaPiece fb = kpp_board_index[pc].fb + sq; // 先手から見たsqにあるpcに対応するBonaPiece
// BonaPiece fw = kpp_board_index[pc].fw + sq; // 後手から見たsqにあるpcに対応するBonaPiece
// An array for finding the BonaPiece corresponding to the piece pc on the board of the KPP table.
// example)
// BonaPiece fb = kpp_board_index[pc].fb + sq; // BonaPiece corresponding to pc in sq seen from the front
// BonaPiece fw = kpp_board_index[pc].fw + sq; // BonaPiece corresponding to pc in sq seen from behind
extern ExtBonaPiece kpp_board_index[PIECE_NB];
// 評価関数で用いる駒リスト。どの駒(PieceNumber)がどこにあるのか(BonaPiece)を保持している構造体
// List of pieces used in the evaluation function. A structure holding which piece (PieceNumber) is where (BonaPiece)
struct EvalList
{
// 評価関数(FV38型)で用いる駒番号のリスト
// List of frame numbers used in evaluation function (FV38 type)
BonaPiece* piece_list_fw() const { return const_cast<BonaPiece*>(pieceListFw); }
BonaPiece* piece_list_fb() const { return const_cast<BonaPiece*>(pieceListFb); }
// 指定されたpiece_noの駒をExtBonaPiece型に変換して返す。
// Convert the specified piece_no piece to ExtBonaPiece type and return it.
ExtBonaPiece bona_piece(PieceNumber piece_no) const
{
ExtBonaPiece bp;
@ -139,18 +139,18 @@ struct EvalList
return bp;
}
// 盤上のsqの升にpiece_noのpcの駒を配置する
// Place the piece_no pc piece in the sq box on the board
void put_piece(PieceNumber piece_no, Square sq, Piece pc) {
set_piece_on_board(piece_no, BonaPiece(kpp_board_index[pc].fw + sq), BonaPiece(kpp_board_index[pc].fb + Inv(sq)), sq);
}
// 盤上のある升sqに対応するPieceNumberを返す。
// Returns the PieceNumber corresponding to a box on the board.
PieceNumber piece_no_of_board(Square sq) const { return piece_no_list_board[sq]; }
// pieceListを初期化する。
// 駒落ちに対応させる時のために、未使用の駒の値はBONA_PIECE_ZEROにしておく。
// 通常の評価関数を駒落ちの評価関数として流用できる。
// piece_no_listのほうはデバッグが捗るようにPIECE_NUMBER_NBで初期化。
// Initialize the pieceList.
// Set the value of unused pieces to BONA_PIECE_ZERO in case you want to deal with dropped pieces.
// A normal evaluation function can be used as an evaluation function for missing frames.
// piece_no_list is initialized with PIECE_NUMBER_NB to facilitate debugging.
void clear()
{
@ -164,11 +164,11 @@ struct EvalList
v = PIECE_NUMBER_NB;
}
// 内部で保持しているpieceListFw[]が正しいBonaPieceであるかを検査する。
// 注 : デバッグ用。遅い。
// Check whether the pieceListFw[] held internally is a correct BonaPiece.
// Note: For debugging. slow.
bool is_valid(const Position& pos);
// 盤上sqにあるpiece_noの駒のBonaPieceがfb,fwであることを設定する。
// Set that the BonaPiece of the piece_no piece on the board sq is fb,fw.
inline void set_piece_on_board(PieceNumber piece_no, BonaPiece fw, BonaPiece fb, Square sq)
{
assert(is_ok(piece_no));
@ -177,21 +177,21 @@ struct EvalList
piece_no_list_board[sq] = piece_no;
}
// 駒リスト。駒番号(PieceNumber)いくつの駒がどこにあるのか(BonaPiece)を示す。FV38などで用いる。
// Piece list. Piece Number Shows how many pieces are in place (Bona Piece). Used in FV38 etc.
// 駒リストの長さ
// 38固定
// Length of piece list
// 38 fixed
public:
int length() const { return PIECE_NUMBER_KING; }
// VPGATHERDDを使う都合、4の倍数でなければならない。
// また、KPPT型評価関数などは、39,40番目の要素がゼロであることを前提とした
// アクセスをしている箇所があるので注意すること。
// Must be a multiple of 4 to use VPGATHERDD.
// In addition, the KPPT type evaluation function, etc. is based on the assumption that the 39th and 40th elements are zero.
// Please note that there is a part that is accessed.
static const int MAX_LENGTH = 32;
// 盤上の駒に対して、その駒番号(PieceNumber)を保持している配列
// 玉がSQUARE_NBに移動しているとき用に+1まで保持しておくが、
// SQUARE_NBの玉を移動させないので、この値を使うことはないはず。
// An array that holds the piece number (PieceNumber) for the pieces on the board
// Hold up to +1 for when the ball is moving to SQUARE_NB,
// SQUARE_NB balls are not moved, so this value should never be used.
PieceNumber piece_no_list_board[SQUARE_NB_PLUS1];
private:
@ -199,20 +199,20 @@ private:
BonaPiece pieceListFb[MAX_LENGTH];
};
// 評価値の差分計算の管理用
// 前の局面から移動した駒番号を管理するための構造体
// 動く駒は、最大で2個。
// For management of evaluation value difference calculation
// A structure for managing the number of pieces that have moved from the previous stage
// Up to 2 moving pieces.
struct DirtyPiece
{
// その駒番号の駒が何から何に変わったのか
// What changed from the piece with that piece number
Eval::ChangedBonaPiece changed_piece[2];
// dirtyになった駒番号
// The number of dirty pieces
PieceNumber pieceNo[2];
// dirtyになった個数。
// null moveだと0ということもありうる。
// 動く駒と取られる駒とで最大で2つ。
// The number of dirty files.
// It can be 0 for null move.
// Up to 2 moving pieces and taken pieces.
int dirty_num;
};

View file

@ -527,11 +527,11 @@ void bindThisThread(size_t idx) {
} // namespace WinProcGroup
// 現在時刻を文字列化したもを返す。(評価関数の学習時などに用いる)
// Returns a string that represents the current time. (Used when learning evaluation functions)
std::string now_string()
{
// std::ctime(), localtime()を使うと、MSVCでセキュアでないという警告が出る。
// C++標準的にはそんなことないはずなのだが…。
// Using std::ctime(), localtime() gives a warning that MSVC is not secure.
// This shouldn't happen in the C++ standard, but...
#if defined(_MSC_VER)
// C4996 : 'ctime' : This function or variable may be unsafe.Consider using ctime_s instead.
@ -542,7 +542,7 @@ std::string now_string()
auto tp = std::chrono::system_clock::to_time_t(now);
auto result = string(std::ctime(&tp));
// 末尾に改行コードが含まれているならこれを除去する
// remove line endings if they are included at the end
while (*result.rbegin() == '\n' || (*result.rbegin() == '\r'))
result.pop_back();
return result;
@ -572,31 +572,31 @@ int read_file_to_memory(std::string filename, std::function<void* (uint64_t)> ca
fs.seekg(0, fstream::end);
uint64_t eofPos = (uint64_t)fs.tellg();
fs.clear(); // これをしないと次のseekに失敗することがある。
fs.clear(); // Otherwise the next seek may fail.
fs.seekg(0, fstream::beg);
uint64_t begPos = (uint64_t)fs.tellg();
uint64_t file_size = eofPos - begPos;
//std::cout << "filename = " << filename << " , file_size = " << file_size << endl;
// ファイルサイズがわかったのでcallback_funcを呼び出してこの分のバッファを確保してもらい、
// そのポインターをもらう。
// I know the file size, so call callback_func to get a buffer for this,
// Get the pointer.
void* ptr = callback_func(file_size);
// バッファが確保できなかった場合や、想定していたファイルサイズと異なった場合は、
// nullptrを返すことになっている。このとき、読み込みを中断し、エラーリターンする。
// If the buffer could not be secured, or if the file size is different from the expected file size,
// It is supposed to return nullptr. At this time, reading is interrupted and an error is returned.
if (ptr == nullptr)
return 2;
// 細切れに読み込む
// read in pieces
const uint64_t block_size = 1024 * 1024 * 1024; // 1回のreadで読み込む要素の数(1GB)
const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to read in one read (1GB)
for (uint64_t pos = 0; pos < file_size; pos += block_size)
{
// 今回読み込むサイズ
// size to read this time
uint64_t read_size = (pos + block_size < file_size) ? block_size : (file_size - pos);
fs.read((char*)ptr + pos, read_size);
// ファイルの途中で読み込みエラーに至った。
// Read error occurred in the middle of the file.
if (fs.fail())
return 2;
@ -613,10 +613,10 @@ int write_memory_to_file(std::string filename, void* ptr, uint64_t size)
if (fs.fail())
return 1;
const uint64_t block_size = 1024 * 1024 * 1024; // 1回のwriteで書き出す要素の数(1GB)
const uint64_t block_size = 1024 * 1024 * 1024; // number of elements to write in one write (1GB)
for (uint64_t pos = 0; pos < size; pos += block_size)
{
// 今回書き出すメモリサイズ
// Memory size to write this time
uint64_t write_size = (pos + block_size < size) ? block_size : (size - pos);
fs.write((char*)ptr + pos, write_size);
//cout << ".";
@ -629,17 +629,17 @@ int write_memory_to_file(std::string filename, void* ptr, uint64_t size)
// mkdir wrapper
// ----------------------------
// カレントフォルダ相対で指定する。成功すれば0、失敗すれば非0が返る。
// フォルダを作成する。日本語は使っていないものとする。
// どうもmsys2環境下のgccだと_wmkdir()だとフォルダの作成に失敗する。原因不明。
// 仕方ないので_mkdir()を用いる。
// Specify relative to the current folder. Returns 0 on success, non-zero on failure.
// Create a folder. Japanese is not used.
// In case of gcc under msys2 environment, folder creation fails with _wmkdir(). Cause unknown.
// Use _mkdir() because there is no help for it.
#if defined(_WIN32)
// Windows
// for Windows
#if defined(_MSC_VER)
#include <codecvt> // mkdirするのにwstringが欲しいのでこれが必要
#include <locale> // wstring_convertにこれが必要。
#include <codecvt> // I need this because I want wstring to mkdir
#include <locale> // This is required for wstring_convert.
namespace Dependency {
int mkdir(std::string dir_name)
@ -663,9 +663,9 @@ namespace Dependency {
#endif
#elif defined(__linux__)
// linux環境において、この_LINUXというシンボルはmakefileにて定義されるものとする。
// In the linux environment, this symbol _LINUX is defined in the makefile.
// Linux用のmkdir実装。
// mkdir implementation for Linux.
#include "sys/stat.h"
namespace Dependency {
@ -676,8 +676,8 @@ namespace Dependency {
}
#else
// Linux環境かどうかを判定するためにはmakefileを分けないといけなくなってくるな..
// linuxでフォルダ掘る機能は、とりあえずナシでいいや..。評価関数ファイルの保存にしか使ってないし…。
// In order to judge whether it is a Linux environment, we have to divide the makefile..
// The function to dig a folder on linux is good for the time being... Only used to save the evaluation function file...
namespace Dependency {
int mkdir(std::string dir_name)

View file

@ -115,15 +115,14 @@ public:
/// Output values only have 1/8th of their bits set on average.
template<typename T> T sparse_rand()
{ return T(rand64() & rand64() & rand64()); }
// 0からn-1までの乱数を返す。(一様分布ではないが現実的にはこれで十分)
// Returns a random number from 0 to n-1. (Not uniform distribution, but this is enough in reality)
uint64_t rand(uint64_t n) { return rand<uint64_t>() % n; }
// 内部で使用している乱数seedを返す。
// Return the random seed used internally.
uint64_t get_seed() const { return s; }
};
// 乱数のseedを表示する。(デバッグ用)
// Display a random seed. (For debugging)
inline std::ostream& operator<<(std::ostream& os, PRNG& prng)
{
os << "PRNG::seed = " << std::hex << prng.get_seed() << std::dec;
@ -153,54 +152,53 @@ inline uint64_t mul_hi64(uint64_t a, uint64_t b) {
namespace WinProcGroup {
void bindThisThread(size_t idx);
}
// 指定されたミリ秒だけsleepする。
// sleep for the specified number of milliseconds.
extern void sleep(int ms);
// 現在時刻を文字列化したもを返す。(評価関数の学習時などにログ出力のために用いる)
// Returns a string that represents the current time. (Used for log output when learning evaluation function)
std::string now_string();
// 途中での終了処理のためのwrapper
// wrapper for end processing on the way
static void my_exit()
{
sleep(3000); // エラーメッセージが出力される前に終了するのはまずいのでwaitを入れておく。
sleep(3000); // It is bad to finish before the error message is output, so put wait.
exit(EXIT_FAILURE);
}
// msys2、Windows Subsystem for Linuxなどのgcc/clangでコンパイルした場合、
// C++のstd::ifstreamで::read()は、一発で2GB以上のファイルの読み書きが出来ないのでそのためのwrapperである。
// When compiled with gcc/clang such as msys2, Windows Subsystem for Linux,
// In C++ std::ifstream, ::read() is a wrapper for that because it is not possible to read and write files larger than 2GB in one shot.
//
// read_file_to_memory()の引数のcallback_funcは、ファイルがオープン出来た時点でそのファイルサイズを引数として
// callbackされるので、バッファを確保して、その先頭ポインタを返す関数を渡すと、そこに読み込んでくれる。
// これらの関数は、ファイルが見つからないときなどエラーの際には非0を返す。
// callback_func of the argument of read_file_to_memory() uses the file size as an argument when the file can be opened
// It will be called back, so if you allocate a buffer and pass a function that returns the first pointer, it will be read there.
// These functions return non-zero on error, such as when the file cannot be found.
//
// また、callbackされた関数のなかでバッファが確保できなかった場合や、想定していたファイルサイズと異なった場合は、
// nullptrを返せば良い。このとき、read_file_to_memory()は、読み込みを中断し、エラーリターンする。
// Also, if the buffer cannot be allocated in the callback function or if the file size is different from the expected file size,
// Return nullptr. At this time, read_file_to_memory() interrupts reading and returns with an error.
int read_file_to_memory(std::string filename, std::function<void* (uint64_t)> callback_func);
int write_memory_to_file(std::string filename, void* ptr, uint64_t size);
// --------------------
// PRNGのasync版
// async version of PRNG
// --------------------
// PRNGのasync版
// async version of PRNG
struct AsyncPRNG
{
AsyncPRNG(uint64_t seed) : prng(seed) { assert(seed); }
// [ASYNC] 乱数を一つ取り出す。
// [ASYNC] Extract one random number.
template<typename T> T rand() {
std::unique_lock<std::mutex> lk(mutex);
return prng.rand<T>();
}
// [ASYNC] 0からn-1までの乱数を返す。(一様分布ではないが現実的にはこれで十分)
// [ASYNC] Returns a random number from 0 to n-1. (Not uniform distribution, but this is enough in reality)
uint64_t rand(uint64_t n) {
std::unique_lock<std::mutex> lk(mutex);
return prng.rand(n);
}
// 内部で使用している乱数seedを返す。
// Return the random seed used internally.
uint64_t get_seed() const { return prng.get_seed(); }
protected:
@ -208,7 +206,7 @@ protected:
PRNG prng;
};
// 乱数のseedを表示する。(デバッグ用)
// Display a random seed. (For debugging)
inline std::ostream& operator<<(std::ostream& os, AsyncPRNG& prng)
{
os << "AsyncPRNG::seed = " << std::hex << prng.get_seed() << std::dec;
@ -219,18 +217,18 @@ inline std::ostream& operator<<(std::ostream& os, AsyncPRNG& prng)
// Math
// --------------------
// 進行度の計算や学習で用いる数学的な関数
// Mathematical function used for progress calculation and learning
namespace Math {
// シグモイド関数
// Sigmoid function
// = 1.0 / (1.0 + std::exp(-x))
double sigmoid(double x);
// シグモイド関数の微分
// Differentiation of sigmoid function
// = sigmoid(x) * (1.0-sigmoid(x))
double dsigmoid(double x);
// vを[lo,hi]の間に収まるようにクリップする。
//  Stockfishではこの関数、bitboard.hに書いてある。
// Clip v so that it fits between [lo,hi].
// * In Stockfish, this function is written in bitboard.h.
template<class T> constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
return v < lo ? lo : v > hi ? hi : v;
}
@ -241,12 +239,12 @@ namespace Math {
// Path
// --------------------
// C#にあるPathクラス的なもの。ファイル名の操作。
// C#のメソッド名に合わせておく。
// Something like Path class in C#. File name manipulation.
// Match with the C# method name.
struct Path
{
// path名とファイル名を結合して、それを返す。
// folder名のほうは空文字列でないときに、末尾に'/'か'\\'がなければそれを付与する。
// Combine the path name and file name and return it.
// If the folder name is not an empty string, append it if there is no'/' or'\\' at the end.
static std::string Combine(const std::string& folder, const std::string& filename)
{
if (folder.length() >= 1 && *folder.rbegin() != '/' && *folder.rbegin() != '\\')
@ -255,10 +253,10 @@ struct Path
return folder + filename;
}
// full path表現から、(フォルダ名を除いた)ファイル名の部分を取得する。
// Get the file name part (excluding the folder name) from the full path expression.
static std::string GetFileName(const std::string& path)
{
// "\"か"/"か、どちらを使ってあるかはわからない。
// I don't know which "\" or "/" is used.
auto path_index1 = path.find_last_of("\\") + 1;
auto path_index2 = path.find_last_of("/") + 1;
auto path_index = std::max(path_index1, path_index2);
@ -270,8 +268,8 @@ struct Path
extern void* aligned_malloc(size_t size, size_t align);
static void aligned_free(void* ptr) { _mm_free(ptr); }
// alignasを指定しているのにnewのときに無視されるSTLのコンテナがメモリ確保するときに無視するので、
// そのために用いるカスタムアロケーター。
// It is ignored when new even though alignas is specified & because it is ignored when the STL container allocates memory,
// A custom allocator used for that.
template <typename T>
class AlignedAllocator {
public:
@ -293,15 +291,15 @@ public:
namespace Dependency
{
// Linux環境ではgetline()したときにテキストファイルが'\r\n'だと
// '\r'が末尾に残るのでこの'\r'を除去するためにwrapperを書く。
// そのため、fstreamに対してgetline()を呼び出すときは、
// std::getline()ではなく単にgetline()と書いて、この関数を使うべき。
// In the Linux environment, if you getline() the text file is'\r\n'
// Since'\r' remains at the end, write a wrapper to remove this'\r'.
// So when calling getline() on fstream,
// just write getline() instead of std::getline() and use this function.
extern bool getline(std::ifstream& fs, std::string& s);
// フォルダを作成する。
// カレントフォルダ相対で指定する。dir_nameに日本語は使っていないものとする。
// 成功すれば0、失敗すれば非0が返る。
// Create a folder.
// Specify relative to the current folder. Japanese is not used for dir_name.
// Returns 0 on success, non-zero on failure.
extern int mkdir(std::string dir_name);
}

View file

@ -209,11 +209,11 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
st = si;
#if defined(EVAL_NNUE)
// evalListのclear。上でmemsetでゼロクリアしたときにクリアされているが…。
// clear evalList. It is cleared when memset is cleared to zero above...
evalList.clear();
// PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、
// それぞれの駒をどこまで使ったかのカウンター
// In updating the PieceList, we have to set which piece is where,
// A counter of how much each piece has been used
PieceNumber next_piece_number = PIECE_NUMBER_ZERO;
#endif // defined(EVAL_NNUE)
@ -235,10 +235,10 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
#if defined(EVAL_NNUE)
PieceNumber piece_no =
(idx == W_KING) ? PIECE_NUMBER_WKING : // 先手玉
(idx == B_KING) ? PIECE_NUMBER_BKING : // 後手玉
next_piece_number++; // それ以外
evalList.put_piece(piece_no, sq, pc); // sqの升にpcの駒を配置する
(idx == W_KING) ?PIECE_NUMBER_WKING : //
(idx == B_KING) ?PIECE_NUMBER_BKING : // back ball
next_piece_number++; // otherwise
evalList.put_piece(piece_no, sq, pc); // Place the pc piece in the sq box
#endif // defined(EVAL_NNUE)
++sq;
@ -823,7 +823,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
st->rule50 = 0;
#if defined(EVAL_NNUE)
dp.dirty_num = 2; // 動いた駒は2個
dp.dirty_num = 2; // 2 pieces moved
dp.pieceNo[1] = piece_no1;
dp.changed_piece[1].old_piece = evalList.bona_piece(piece_no1);
@ -1054,8 +1054,8 @@ template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
#if defined(EVAL_NNUE)
auto& dp = st->dirtyPiece;
// 差分計算のために移動した駒をStateInfoに記録しておく。
dp.dirty_num = 2; // 動いた駒は2個
// Record the moved pieces in StateInfo for difference calculation.
dp.dirty_num = 2; // 2 pieces moved
PieceNumber piece_no0;
PieceNumber piece_no1;

View file

@ -63,7 +63,7 @@ struct StateInfo {
#if defined(EVAL_NNUE)
Eval::NNUE::Accumulator accumulator;
// 評価値の差分計算の管理用
// For management of evaluation value difference calculation
Eval::DirtyPiece dirtyPiece;
#endif // defined(EVAL_NNUE)
};
@ -82,7 +82,7 @@ typedef std::unique_ptr<std::deque<StateInfo>> StateListPtr;
/// traversing the search tree.
class Thread;
// packされたsfen
// packed sfen
struct PackedSfen { uint8_t data[32]; };
class Position {
@ -181,31 +181,31 @@ public:
#if defined(EVAL_NNUE) || defined(EVAL_LEARN)
// --- StateInfo
// 現在の局面に対応するStateInfoを返す。
// たとえば、state()->capturedPieceであれば、前局面で捕獲された駒が格納されている。
// Returns the StateInfo corresponding to the current situation.
// For example, if state()->capturedPiece, the pieces captured in the previous phase are stored.
StateInfo* state() const { return st; }
// 評価関数で使うための、どの駒番号の駒がどこにあるかなどの情報。
// Information such as where and which piece number is used for the evaluation function.
const Eval::EvalList* eval_list() const { return &evalList; }
#endif // defined(EVAL_NNUE) || defined(EVAL_LEARN)
#if defined(EVAL_LEARN)
// -- sfen化ヘルパ
// --sfenization helper
// packされたsfenを得る。引数に指定したバッファに返す。
// gamePlyはpackに含めない。
// Get the packed sfen. Returns to the buffer specified in the argument.
// Do not include gamePly in pack.
void sfen_pack(PackedSfen& sfen);
// ↑sfenを経由すると遅いので直接packされたsfenをセットする関数を作った。
// pos.set(sfen_unpack(data),si,th); と等価。
// 渡された局面に問題があって、エラーのときは非0を返す。
// PackedSfenにgamePlyは含まないので復元できない。そこを設定したいのであれば引数で指定すること。
// <EFBFBD>ª It is slow to go through sfen, so I made a function to set packed sfen directly.
// Equivalent to pos.set(sfen_unpack(data),si,th);.
// If there is a problem with the passed phase and there is an error, non-zero is returned.
// PackedSfen does not include gamePly so it cannot be restored. If you want to set it, specify it with an argument.
int set_from_packed_sfen(const PackedSfen& sfen, StateInfo* si, Thread* th, bool mirror = false);
// 盤面と手駒、手番を与えて、そのsfenを返す。
// Give the board, hand piece, and turn, and return the sfen.
//static std::string sfen_from_rawdata(Piece board[81], Hand hands[2], Color turn, int gamePly);
// c側の玉の位置を返す。
// Returns the position of the ball on the c side.
Square king_square(Color c) const { return pieceList[make_piece(c, KING)][0]; }
#endif // EVAL_LEARN
@ -223,7 +223,7 @@ private:
void do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto);
#if defined(EVAL_NNUE)
// 盤上のsqの升にある駒のPieceNumberを返す。
// Returns the PieceNumber of the piece in the sq box on the board.
PieceNumber piece_no_of(Square sq) const;
#endif // defined(EVAL_NNUE)
@ -245,7 +245,7 @@ private:
bool chess960;
#if defined(EVAL_NNUE) || defined(EVAL_LEARN)
// 評価関数で用いる駒のリスト
// List of pieces used in the evaluation function
Eval::EvalList evalList;
#endif // defined(EVAL_NNUE) || defined(EVAL_LEARN)
};

View file

@ -1938,60 +1938,61 @@ void Tablebases::rank_root_moves(Position& pos, Search::RootMoves& rootMoves) {
}
}
// --- 学習時に用いる、depth固定探索などの関数を外部に対して公開
// --- expose the functions such as fixed depth search used for learning to the outside
#if defined (EVAL_LEARN)
namespace Learner
{
// 学習用に、1つのスレッドからsearch,qsearch()を呼び出せるようなスタブを用意する。
// いまにして思えば、AperyのようにSearcherを持ってスレッドごとに置換表などを用意するほうが
// 良かったかも知れない。
// 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.
// 学習のための初期化。
// Learner::search(),Learner::qsearch()から呼び出される。
// Initialization for learning.
// Called from Learner::search(),Learner::qsearch().
void init_for_search(Position& pos, Stack* ss)
{
// RootNodeはss->ply == 0がその条件。
// ゼロクリアするので、ss->ply == 0となるので大丈夫…。
// 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に関して
// このメンバー変数はglobalなので他のスレッドに影響を及ぼすので気をつけること。
// About Search::Limits
// Be careful because this member variable is global and affects other threads.
{
auto& limits = Search::Limits;
// 探索を"go infinite"コマンド相当にする。(time managementされると困るため)
// Make the search equivalent to the "go infinite" command. (Because it is troublesome if time management is done)
limits.infinite = true;
// PVを表示されると邪魔なので消しておく。
// Since PV is an obstacle when displayed, erase it.
limits.silent = true;
// これを用いると各スレッドのnodesを積算したものと比較されてしまう。ゆえに使用しない。
// If you use this, it will be compared with the accumulated nodes of each thread. Therefore, do not use it.
limits.nodes = 0;
// depthも、Learner::search()の引数として渡されたもので処理する。
// depth is also processed by the one passed as an argument of Learner::search().
limits.depth = 0;
// 引き分け付近の手数で引き分けの値が返るのを防ぐために大きな値にしておく。
// 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;
// 入玉ルールも入れておかないと引き分けになって決着つきにくい。
// 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の設定
// Set DrawValue
{
// スレッドごとに用意してないので
// 他のスレッドで上書きされかねない。仕方がないが。
// どうせそうなるなら、0にすべきだと思う。
// 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に関して。
// Regarding this_thread.
{
auto th = pos.this_thread();
@ -1999,10 +2000,10 @@ namespace Learner
th->selDepth = 0;
th->rootDepth = 0;
// 探索ノード数のゼロ初期化
// Zero initialization of the number of search nodes
th->nodes = 0;
// history類を全部クリアする。この初期化は少し時間がかかるし、探索の精度はむしろ下がるので善悪はよくわからない。
// 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,7 +2024,7 @@ namespace Learner
for (int i = 7; i > 0; i--)
(ss - i)->continuationHistory = &th->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel
// rootMovesの設定
// set rootMoves
auto& rootMoves = th->rootMoves;
rootMoves.clear();
@ -2033,47 +2034,47 @@ namespace Learner
assert(!rootMoves.empty());
//#if defined(USE_GLOBAL_OPTIONS)
// 探索スレッドごとの置換表の世代を管理しているはずなので、
// 新規の探索であるから、このスレッドに対する置換表の世代を増やす。
// 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());
// ↑ここでnew_searchを呼び出すと1手前の探索結果が使えなくて損ということはあるのでは…。
// ここでこれはやらずに、呼び出し側で1局ごとにTT.new_search(th->thread_id())をやるべきでは…。
// ↑ 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 ...
// → 同一の終局図に至るのを回避したいので、教師生成時には置換表は全スレ共通で使うようにする。
// →Because we want to avoid reaching the same final diagram, use the substitution table commonly for all threads when generating teachers.
//#endif
}
}
// 読み筋と評価値のペア。Learner::search(),Learner::qsearch()が返す。
// A pair of reader and evaluation value. Returned by Learner::search(),Learner::qsearch().
typedef std::pair<Value, std::vector<Move> > ValueAndPV;
// 静止探索。
// Stationary search.
//
// 前提条件) pos.set_this_thread(Threads[thread_id])で探索スレッドが設定されていること。
//  また、Threads.stopが来ると探索を中断してしまうので、そのときのPVは正しくない。
//  search()から戻ったあと、Threads.stop == trueなら、その探索結果を用いてはならない。
//  あと、呼び出し前は、Threads.stop == falseの状態で呼び出さないと、探索を中断して返ってしまうので注意。
// 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.
//
// 詰まされている場合は、PV配列にMOVE_RESIGNが返る。
// If it is clogged, MOVE_RESIGN is returned in the PV array.
//
// 引数でalpha,betaを指定できるようにしていたが、これがその窓で探索したときの結果を
// 置換表に書き込むので、その窓に対して枝刈りが出来るような値が書き込まれて学習のときに
// 悪い影響があるので、窓の範囲を指定できるようにするのをやめることにした。
//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; // とりあえずダミーでどこかバッファがないといけない。
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, {} };
}
// 詰まされているのか
// 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);
// 得られたPVを返す。
// 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);
}
// 通常探索。深さdepth(整数で指定)。
// 3手読み時のスコアが欲しいなら、
// Normal search. Depth depth (specified as an integer).
// 3 If you want a score for hand reading,
// auto v = search(pos,3);
// のようにすべし。
// v.firstに評価値、v.secondにPVが得られる。
// multi pvが有効のときは、pos.this_thread()->rootMoves[N].pvにそのPV(読み筋)の配列が得られる。
// multi pvの指定はこの関数の引数multiPVで行なう。(Options["MultiPV"]の値は無視される)
// 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)
//
// rootでの宣言勝ち判定はしないので(扱いが面倒なので)、ここでは行わない。
// 呼び出し側で処理すること。
// 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.
//
// 前提条件) pos.set_this_thread(Threads[thread_id])で探索スレッドが設定されていること。
//  また、Threads.stopが来ると探索を中断してしまうので、そのときのPVは正しくない。
//  search()から戻ったあと、Threads.stop == trueなら、その探索結果を用いてはならない。
//  あと、呼び出し前は、Threads.stop == falseの状態で呼び出さないと、探索を中断して返ってしまうので注意。
// 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; // とりあえずダミーでどこかバッファがないといけない。
ss->pv = pv; // For the time being, it must be a dummy and somewhere with a buffer.
// this_threadに関連する変数の初期化
// 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としてしこの局面の上位N個を探索する機能
// A function to search the top N of this stage as best move
//size_t multiPV = Options["MultiPV"];
// この局面での指し手の数を上回ってはいけない
// Do not exceed the number of moves in this situation
multiPV = std::min(multiPV, rootMoves.size());
// ード制限にMultiPVの値を掛けておかないと、depth固定、MultiPVありにしたときに1つの候補手に同じnodeだけ思考したことにならない。
// 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制限を超えた場合もこのループを抜ける
// 探索ノード数は、この関数の引数で渡されている。
&& !(nodesLimit /*node制限あり*/ && 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;
}
// それぞれのdepthとPV lineに対するUSI infoで出力するselDepth
// selDepth output with USI info for each depth and PV line
selDepth = 0;
// depth 5以上においてはaspiration searchに切り替える。
// 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に対してaspiration windowを広げる。
// ただし、引数で指定されていた値になっていたら、もうfail low/high扱いとしてbreakする。
// 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);
// 暴走チェック
// runaway check
//assert(th->nodes.load(std::memory_order_relaxed) <= 1000000 );
}
@ -2229,9 +2230,9 @@ namespace Learner
completedDepth = rootDepth;
}
// このPV、途中でNULL_MOVEの可能性があるかも知れないので排除するためにis_ok()を通す。
// → PVなのでNULL_MOVEはしないことになっているはずだし、
// MOVE_WINも突っ込まれていることはない。(いまのところ)
// 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時を考慮して、rootMoves[0]のscoreをbestValueとして返す。
// Considering multiPV, the score of rootMoves[0] is returned as bestValue.
bestValue = rootMoves[0].score;
return ValueAndPV(bestValue, pvs);

View file

@ -192,7 +192,7 @@ enum Value : int {
MidgameLimit = 15258, EndgameLimit = 3915,
// 評価関数の返す値の最大値(2**14ぐらいに収まっていて欲しいところだが..)
// Maximum value returned by the evaluation function (I want it to be around 2**14..)
VALUE_MAX_EVAL = 27000,
};
@ -239,7 +239,7 @@ enum Square : int {
SQ_NONE,
SQUARE_ZERO = 0, SQUARE_NB = 64,
SQUARE_NB_PLUS1 = SQUARE_NB + 1, // 玉がいない場合、SQUARE_NBに移動したものとして扱うため、配列をSQUARE_NB+1で確保しないといけないときがあるのでこの定数を用いる。
SQUARE_NB_PLUS1 = SQUARE_NB + 1, // If there are no balls, it is treated as having moved to SQUARE_NB, so it may be necessary to secure the array with SQUARE_NB+1, so this constant is used.
};
enum Direction : int {
@ -463,18 +463,18 @@ constexpr bool is_ok(Move m) {
return from_sq(m) != to_sq(m); // Catch MOVE_NULL and MOVE_NONE
}
// 盤面を180°回したときの升目を返す
// Return squares when turning the board 180<38>
constexpr Square Inv(Square sq) { return (Square)((SQUARE_NB - 1) - sq); }
// 盤面をミラーしたときの升目を返す
// Return squares when mirroring the board
constexpr Square Mir(Square sq) { return make_square(File(7 - (int)file_of(sq)), rank_of(sq)); }
#if defined(EVAL_NNUE) || defined(EVAL_LEARN)
// --------------------
// 駒箱
// piece box
// --------------------
// Positionクラスで用いる、駒リスト(どの駒がどこにあるのか)を管理するときの番号。
// A number used to manage the piece list (which piece is where) used in the Position class.
enum PieceNumber : uint8_t
{
PIECE_NUMBER_PAWN = 0,
@ -484,7 +484,7 @@ enum PieceNumber : uint8_t
PIECE_NUMBER_QUEEN = 28,
PIECE_NUMBER_KING = 30,
PIECE_NUMBER_WKING = 30,
PIECE_NUMBER_BKING = 31, // 先手、後手の玉の番号が必要な場合はこっちを用いる
PIECE_NUMBER_BKING = 31, // Use this if you need the numbers of the first and second balls
PIECE_NUMBER_ZERO = 0,
PIECE_NUMBER_NB = 32,
};
@ -497,7 +497,7 @@ inline PieceNumber operator++(PieceNumber& d, int) {
}
inline PieceNumber& operator--(PieceNumber& d) { return d = PieceNumber(int8_t(d) - 1); }
// PieceNumberの整合性の検査。assert用。
// Piece Number integrity check. for assert.
constexpr bool is_ok(PieceNumber pn) { return pn < PIECE_NUMBER_NB; }
#endif // defined(EVAL_NNUE) || defined(EVAL_LEARN)

View file

@ -44,22 +44,22 @@ extern vector<string> setup_bench(const Position&, istream&);
// FEN string of the initial position, normal chess
const char* StartFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
// 棋譜を自動生成するコマンド
// Command to automatically generate a game record
#if defined (EVAL_LEARN)
namespace Learner
{
// 教師局面の自動生成
// Automatic generation of teacher position
void gen_sfen(Position& pos, istringstream& is);
// 生成した棋譜からの学習
// Learning from the generated game record
void learn(Position& pos, istringstream& is);
#if defined(GENSFEN2019)
// 開発中の教師局面の自動生成コマンド
// Automatic generation command of teacher phase under development
void gen_sfen2019(Position& pos, istringstream& is);
#endif
// 読み筋と評価値のペア。Learner::search(),Learner::qsearch()が返す。
// A pair of reader and evaluation value. Returned by Learner::search(),Learner::qsearch().
typedef std::pair<Value, std::vector<Move> > ValueAndPV;
ValueAndPV qsearch(Position& pos);
@ -71,7 +71,7 @@ namespace Learner
#if defined(EVAL_NNUE) && defined(ENABLE_TEST_CMD)
void test_cmd(Position& pos, istringstream& is)
{
// 探索をするかも知れないので初期化しておく。
// Initialize as it may be searched.
is_ready();
std::string param;
@ -221,21 +221,21 @@ namespace {
<< "\nNodes/second : " << 1000 * nodes / elapsed << endl;
}
// check sumを計算したとき、それを保存しておいてあとで次回以降、整合性のチェックを行なう。
// When you calculate check sum, save it and check the consistency later.
uint64_t eval_sum;
} // namespace
// is_ready_cmd()を外部から呼び出せるようにしておく。(benchコマンドなどから呼び出したいため)
// 局面は初期化されないので注意。
// Make is_ready_cmd() callable from outside. (Because I want to call it from the bench command etc.)
// Note that the phase is not initialized.
void is_ready(bool skipCorruptCheck)
{
#if defined(EVAL_NNUE)
// "isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。(keep alive的な処理)
// USI2.0の仕様より。
// -"isready"のあとのtime out時間は、30秒程度とする。これを超えて、評価関数の初期化、hashテーブルの確保をしたい場合、
// 思考エンジン側から定期的に何らかのメッセージ(改行可)を送るべきである。
// -ShogiGUIではすでにそうなっているので、MyShogiもそれに追随する。
// -また、やねうら王のエンジン側は、"isready"を受け取ったあと、"readyok"を返すまで5秒ごとに改行を送るように修正する。
// After receiving "isready", modify so that a line feed is sent every 5 seconds until "readyok" is returned. (keep alive processing)
// From USI 2.0 specifications.
// -The time out time after "is ready" is about 30 seconds. Beyond this, if you want to initialize the evaluation function and secure the hash table,
// You should send some kind of message (breakable) from the thinking engine side.
// -Shogi GUI already does so, so MyShogi will follow along.
//-Also, the engine side of Yaneura King modifies it so that after "isready" is received, a line feed is sent every 5 seconds until "readyok" is returned.
auto ended = false;
auto th = std::thread([&ended] {
@ -243,25 +243,25 @@ void is_ready(bool skipCorruptCheck)
while (!ended)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (++count >= 50 /* 5 */)
if (++count >= 50 /* 5 seconds */)
{
count = 0;
sync_cout << sync_endl; // 改行を送信する。
sync_cout << sync_endl; // Send a line break.
}
}
});
// 評価関数の読み込みなど時間のかかるであろう処理はこのタイミングで行なう。
// 起動時に時間のかかる処理をしてしまうと将棋所がタイムアウト判定をして、思考エンジンとしての認識をリタイアしてしまう。
// Perform processing that may take time, such as reading the evaluation function, at this timing.
// If you do a time-consuming process at startup, Shogi place will make a timeout judgment and retire the recognition as a thinking engine.
if (!UCI::load_eval_finished)
{
// 評価関数の読み込み
// Read evaluation function
Eval::load_eval();
// チェックサムの計算と保存(その後のメモリ破損のチェックのため)
// Calculate and save checksum (to check for subsequent memory corruption)
eval_sum = Eval::calc_check_sum();
// ソフト名の表示
// display soft name
Eval::print_softname(eval_sum);
UCI::load_eval_finished = true;
@ -269,14 +269,14 @@ void is_ready(bool skipCorruptCheck)
}
else
{
// メモリが破壊されていないかを調べるためにチェックサムを毎回調べる。
// 時間が少しもったいない気もするが.. 0.1秒ぐらいのことなので良しとする。
// Check the checksum every time to see if the memory has been corrupted.
// It seems that the time is a little wasteful, but it is good because it is about 0.1 seconds.
if (!skipCorruptCheck && eval_sum != Eval::calc_check_sum())
sync_cout << "Error! : EVAL memory is corrupted" << sync_endl;
}
// isreadyに対してはreadyokを返すまで次のコマンドが来ないことは約束されているので
// このタイミングで各種変数の初期化もしておく。
// For isready, it is promised that the next command will not come until it returns readyok.
// Initialize various variables at this timing.
TT.resize(Options["Hash"]);
Search::clear();
@ -284,7 +284,7 @@ void is_ready(bool skipCorruptCheck)
Threads.stop = false;
// keep aliveを送信するために生成したスレッドを終了させ、待機する。
// Terminate the thread created to send keep alive and wait.
ended = true;
th.join();
#endif // defined(EVAL_NNUE)
@ -294,7 +294,7 @@ void is_ready(bool skipCorruptCheck)
// --------------------
// テスト用にqsearch(),search()を直接呼ぶ
// Call qsearch(),search() directly for testing
// --------------------
#if defined(EVAL_LEARN)
@ -391,10 +391,10 @@ void UCI::loop(int argc, char* argv[]) {
else if (token == "learn") Learner::learn(pos, is);
#if defined (GENSFEN2019)
// 開発中の教師局面生成コマンド
// Command to generate teacher phase under development
else if (token == "gensfen2019") Learner::gen_sfen2019(pos, is);
#endif
// テスト用にqsearch(),search()を直接呼ぶコマンド
// Command to call qsearch(),search() directly for testing
else if (token == "qsearch") qsearch_cmd(pos);
else if (token == "search") search_cmd(pos, is);
@ -405,7 +405,7 @@ void UCI::loop(int argc, char* argv[]) {
#endif
#if defined(EVAL_NNUE) && defined(ENABLE_TEST_CMD)
// テストコマンド
// test command
else if (token == "test") test_cmd(pos, is);
#endif
else

View file

@ -75,16 +75,17 @@ std::string move(Move m, bool chess960);
std::string pv(const Position& pos, Depth depth, Value alpha, Value beta);
Move to_move(const Position& pos, std::string& str);
// 評価関数を読み込んだかのフラグ。これはevaldirの変更にともなってfalseにする。
// Flag that read the evaluation function. This is set to false when evaldir is changed.
extern bool load_eval_finished; // = false;
} // namespace UCI
extern UCI::OptionsMap Options;
// USIの"isready"コマンドが呼び出されたときの処理。このときに評価関数の読み込みなどを行なう。
// benchmarkコマンドのハンドラなどで"isready"が来ていないときに評価関数を読み込ませたいときに用いる。
// skipCorruptCheck == trueのときは評価関数の2度目の読み込みのときのcheck sumによるメモリ破損チェックを省略する。
// ※ この関数は、Stockfishにはないがないと不便なので追加しておく。
// Processing when USI "isready" command is called. At this time, the evaluation function is read.
// Used when you want to load the evaluation function when "isready" does not come in handler of benchmark command etc.
// If skipCorruptCheck == true, skip memory corruption check by check sum when reading the evaluation function a second time.
// * This function is inconvenient if it is not available in Stockfish, so add it.
void is_ready(bool skipCorruptCheck = false);
extern const char* StartFEN;

View file

@ -79,21 +79,21 @@ void init(OptionsMap& o) {
o["SyzygyProbeDepth"] << Option(1, 1, 100);
o["Syzygy50MoveRule"] << Option(true);
o["SyzygyProbeLimit"] << Option(7, 0, 7);
// 評価関数フォルダ。これを変更したとき、評価関数を次のisreadyタイミングで読み直す必要がある。
// Evaluation function folder. When this is changed, it is necessary to reread the evaluation function at the next isready timing.
o["EvalDir"] << Option("eval", on_eval_dir);
// isreadyタイミングで評価関数を読み込まれると、新しい評価関数の変換のために
// test evalconvertコマンドを叩きたいのに、その新しい評価関数がないがために
// このコマンドの実行前に異常終了してしまう。
// そこでこの隠しオプションでisready時の評価関数の読み込みを抑制して、
// test evalconvertコマンドを叩く。
// When the evaluation function is loaded at the isready timing, it is necessary to convert the new evaluation function.
// I want to hit the test eval convert command, but there is no new evaluation function
// It ends abnormally before executing this command.
// Therefore, with this hidden option, you can suppress the loading of the evaluation function when isready,
// Hit the test eval convert command.
o["SkipLoadingEval"] << Option(false);
// 定跡の指し手を何手目まで用いるか
// how many moves to use a fixed move
o["BookMoves"] << Option(16, 0, 10000);
#if defined(EVAL_LEARN)
// 評価関数の学習を行なうときは、評価関数の保存先のフォルダを変更できる。
// デフォルトではevalsave。このフォルダは事前に用意されているものとする。
// このフォルダ配下にフォルダを"0/","1/",…のように自動的に掘り、そこに評価関数ファイルを保存する。
// When learning the evaluation function, you can change the folder to save the evaluation function.
// Evalsave by default. This folder shall be prepared in advance.
// Automatically dig a folder under this folder like "0/", "1/", ... and save the evaluation function file there.
o["EvalSaveDir"] << Option("evalsave");
#endif
}
@ -204,6 +204,6 @@ Option& Option::operator=(const string& v) {
return *this;
}
// 評価関数を読み込んだかのフラグ。これはevaldirの変更にともなってfalseにする。
// Flag that read the evaluation function. This is set to false when evaldir is changed.
bool load_eval_finished = false;
} // namespace UCI