From 8f31d74cf64a3daa24eac1c3ae659a572f04667d Mon Sep 17 00:00:00 2001 From: FireFather Date: Mon, 29 Jun 2020 17:31:35 +0200 Subject: [PATCH] More comment translation including 11 files in /src --- src/evaluate.cpp | 22 +++---- src/evaluate.h | 112 +++++++++++++++++----------------- src/misc.cpp | 52 ++++++++-------- src/misc.h | 86 +++++++++++++------------- src/position.cpp | 20 +++--- src/position.h | 32 +++++----- src/search.cpp | 151 +++++++++++++++++++++++----------------------- src/types.h | 16 ++--- src/uci.cpp | 62 +++++++++---------- src/uci.h | 11 ++-- src/ucioption.cpp | 22 +++---- 11 files changed, 293 insertions(+), 293 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 83dfaadd..07bed614 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -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 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:; } diff --git a/src/evaluate.h b/src/evaluate.h index a9e6a563..0301f455 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -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 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 × piece type, like the step at 39 points. enum BonaPiece : int32_t { - // f = friend(≒先手)の意味。e = enemy(≒後手)の意味 + // Meaning of f = friend (≒first move). Meaning of e = enemy (≒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(pieceListFw); } BonaPiece* piece_list_fb() const { return const_cast(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,36 +139,36 @@ 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() { - for (auto& p : pieceListFw) + for (auto& p: pieceListFw) p = BONA_PIECE_ZERO; - for (auto& p : pieceListFb) + for (auto& p: pieceListFb) p = BONA_PIECE_ZERO; - for (auto& v : piece_no_list_board) + for (auto& v :piece_no_list_board) 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; }; diff --git a/src/misc.cpp b/src/misc.cpp index 9d14cc1f..1d6bbb4f 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -527,11 +527,11 @@ void bindThisThread(size_t idx) { } // namespace WinProcGroup -// 迴セ蝨ィ譎ょ綾繧呈枚蟄怜怜喧縺励◆繧ゅr霑斐☆縲(隧穂セ。髢「謨ー縺ョ蟄ヲ鄙呈凾縺ェ縺ゥ縺ォ逕ィ縺繧) +// Returns a string that represents the current time. (Used when learning evaluation functions) std::string now_string() { - // std::ctime(), localtime()繧剃スソ縺縺ィ縲`SVC縺ァ繧サ繧ュ繝・繧「縺ァ縺ェ縺縺ィ縺縺隴ヲ蜻翫′蜃コ繧九 - // C++讓呎コ也噪縺ォ縺ッ縺昴s縺ェ縺薙→縺ェ縺縺ッ縺壹↑縺ョ縺縺娯ヲ縲 + // 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)); - // 譛ォ蟆セ縺ォ謾ケ陦後さ繝シ繝峨′蜷ォ縺セ繧後※縺繧九↑繧峨%繧後r髯、蜴サ縺吶k + // 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 ca fs.seekg(0, fstream::end); uint64_t eofPos = (uint64_t)fs.tellg(); - fs.clear(); // 縺薙l繧偵@縺ェ縺縺ィ谺。縺ョ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; - // 繝輔ぃ繧、繝ォ繧オ繧、繧コ縺後o縺九▲縺溘ョ縺ァcallback_func繧貞他縺ウ蜃コ縺励※縺薙ョ蛻縺ョ繝舌ャ繝輔ぃ繧堤「コ菫昴@縺ヲ繧ゅi縺縲 - // 縺昴ョ繝昴う繝ウ繧ソ繝シ繧偵b繧峨≧縲 + // I know the file size, so call callback_func to get a buffer for this, + // Get the pointer. void* ptr = callback_func(file_size); - // 繝舌ャ繝輔ぃ縺檎「コ菫昴〒縺阪↑縺九▲縺溷エ蜷医d縲∵Φ螳壹@縺ヲ縺縺溘ヵ繧。繧、繝ォ繧オ繧、繧コ縺ィ逡ー縺ェ縺」縺溷エ蜷医ッ縲 - // nullptr繧定ソ斐☆縺薙→縺ォ縺ェ縺」縺ヲ縺繧九ゅ%縺ョ縺ィ縺阪∬ェュ縺ソ霎シ縺ソ繧剃クュ譁ュ縺励√お繝ゥ繝シ繝ェ繧ソ繝シ繝ウ縺吶k縲 + // 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 // ---------------------------- -// 繧ォ繝ャ繝ウ繝医ヵ繧ゥ繝ォ繝逶ク蟇セ縺ァ謖螳壹☆繧九よ仙粥縺吶l縺ー0縲∝、ア謨励☆繧後ー髱0縺瑚ソ斐k縲 -// 繝輔か繝ォ繝繧剃ス懈舌☆繧九よ律譛ャ隱槭ッ菴ソ縺」縺ヲ縺縺ェ縺繧ゅョ縺ィ縺吶k縲 -// 縺ゥ縺繧Nsys2迺ー蠅荳九ョ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 // mkdir縺吶k縺ョ縺ォwstring縺梧ャイ縺励>縺ョ縺ァ縺薙l縺悟ソ隕 -#include // wstring_convert縺ォ縺薙l縺悟ソ隕√ +#include // I need this because I want wstring to mkdir +#include // 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縺ォ縺ヲ螳夂セゥ縺輔l繧九b縺ョ縺ィ縺吶k縲 +// 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迺ー蠅縺九←縺縺九r蛻、螳壹☆繧九◆繧√↓縺ッmakefile繧貞縺代↑縺縺ィ縺縺代↑縺上↑縺」縺ヲ縺上k縺ェ.. -// linux縺ァ繝輔か繝ォ繝謗倥k讖溯ス縺ッ縲√→繧翫≠縺医★繝翫す縺ァ縺縺繧..縲りゥ穂セ。髢「謨ー繝輔ぃ繧、繝ォ縺ョ菫晏ュ倥↓縺励°菴ソ縺」縺ヲ縺ェ縺縺冷ヲ縲 +// 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) diff --git a/src/misc.h b/src/misc.h index 72f621a6..0e2e8403 100644 --- a/src/misc.h +++ b/src/misc.h @@ -115,15 +115,14 @@ public: /// Output values only have 1/8th of their bits set on average. template T sparse_rand() { return T(rand64() & rand64() & rand64()); } - - // 0縺九in-1縺セ縺ァ縺ョ荵ア謨ー繧定ソ斐☆縲(荳讒伜蟶縺ァ縺ッ縺ェ縺縺檎樟螳溽噪縺ォ縺ッ縺薙l縺ァ蜊∝) + // 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() % n; } - // 蜀驛ィ縺ァ菴ソ逕ィ縺励※縺繧倶ケア謨ーseed繧定ソ斐☆縲 + // Return the random seed used internally. uint64_t get_seed() const { return s; } }; -// 荵ア謨ー縺ョseed繧定。ィ遉コ縺吶k縲(繝繝舌ャ繧ー逕ィ) +// 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); } - -// 謖螳壹&繧後◆繝溘Μ遘偵□縺壮leep縺吶k縲 +// sleep for the specified number of milliseconds. extern void sleep(int ms); -// 迴セ蝨ィ譎ょ綾繧呈枚蟄怜怜喧縺励◆繧ゅr霑斐☆縲(隧穂セ。髢「謨ー縺ョ蟄ヲ鄙呈凾縺ェ縺ゥ縺ォ繝ュ繧ー蜃コ蜉帙ョ縺溘a縺ォ逕ィ縺繧) +// Returns a string that represents the current time. (Used for log output when learning evaluation function) std::string now_string(); -// 騾比クュ縺ァ縺ョ邨ゆコ蜃ヲ逅縺ョ縺溘a縺ョwrapper +// wrapper for end processing on the way static void my_exit() { - sleep(3000); // 繧ィ繝ゥ繝シ繝。繝繧サ繝シ繧ク縺悟コ蜉帙&繧後k蜑阪↓邨ゆコ縺吶k縺ョ縺ッ縺セ縺壹>縺ョ縺ァwait繧貞・繧後※縺翫¥縲 + sleep(3000); // It is bad to finish before the error message is output, so put wait. exit(EXIT_FAILURE); } -// msys2縲仝indows Subsystem for Linux縺ェ縺ゥ縺ョgcc/clang縺ァ繧ウ繝ウ繝代う繝ォ縺励◆蝣エ蜷医 -// C++縺ョstd::ifstream縺ァ::read()縺ッ縲∽ク逋コ縺ァ2GB莉・荳翫ョ繝輔ぃ繧、繝ォ縺ョ隱ュ縺ソ譖ク縺阪′蜃コ譚・縺ェ縺縺ョ縺ァ縺昴ョ縺溘a縺ョwrapper縺ァ縺ゅk縲 +// 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縺輔l繧九ョ縺ァ縲√ヰ繝繝輔ぃ繧堤「コ菫昴@縺ヲ縲√◎縺ョ蜈磯ュ繝昴う繝ウ繧ソ繧定ソ斐☆髢「謨ー繧呈ク。縺吶→縲√◎縺薙↓隱ュ縺ソ霎シ繧薙〒縺上l繧九 -// 縺薙l繧峨ョ髢「謨ー縺ッ縲√ヵ繧。繧、繝ォ縺瑚ヲ九▽縺九i縺ェ縺縺ィ縺阪↑縺ゥ繧ィ繝ゥ繝シ縺ョ髫帙↓縺ッ髱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. // -// 縺セ縺溘…allback縺輔l縺滄未謨ー縺ョ縺ェ縺九〒繝舌ャ繝輔ぃ縺檎「コ菫昴〒縺阪↑縺九▲縺溷エ蜷医d縲∵Φ螳壹@縺ヲ縺縺溘ヵ繧。繧、繝ォ繧オ繧、繧コ縺ィ逡ー縺ェ縺」縺溷エ蜷医ッ縲 -// nullptr繧定ソ斐○縺ー濶ッ縺縲ゅ%縺ョ縺ィ縺阪〉ead_file_to_memory()縺ッ縲∬ェュ縺ソ霎シ縺ソ繧剃クュ譁ュ縺励√お繝ゥ繝シ繝ェ繧ソ繝シ繝ウ縺吶k縲 +// 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 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] 荵ア謨ー繧剃ク縺、蜿悶j蜃コ縺吶 + // [ASYNC] Extract one random number. template T rand() { std::unique_lock lk(mutex); return prng.rand(); } - // [ASYNC] 0縺九in-1縺セ縺ァ縺ョ荵ア謨ー繧定ソ斐☆縲(荳讒伜蟶縺ァ縺ッ縺ェ縺縺檎樟螳溽噪縺ォ縺ッ縺薙l縺ァ蜊∝) + // [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 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繧定。ィ遉コ縺吶k縲(繝繝舌ャ繧ー逕ィ) +// 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 // -------------------- -// 騾イ陦悟コヲ縺ョ險育ョ励d蟄ヲ鄙偵〒逕ィ縺繧区焚蟄ヲ逧縺ェ髢「謨ー +// Mathematical function used for progress calculation and learning namespace Math { - // 繧キ繧ー繝「繧、繝蛾未謨ー - // = 1.0 / (1.0 + std::exp(-x)) + // Sigmoid function + // = 1.0 / (1.0 + std::exp(-x)) double sigmoid(double x); - // 繧キ繧ー繝「繧、繝蛾未謨ー縺ョ蠕ョ蛻 - // = sigmoid(x) * (1.0 - sigmoid(x)) + // Differentiation of sigmoid function + // = sigmoid(x) * (1.0-sigmoid(x)) double dsigmoid(double x); - // v繧端lo,hi]縺ョ髢薙↓蜿弱∪繧九h縺縺ォ繧ッ繝ェ繝繝励☆繧九 - // 窶サ縲Stockfish縺ァ縺ッ縺薙ョ髢「謨ー縲|itboard.h縺ォ譖ク縺縺ヲ縺ゅk縲 + // Clip v so that it fits between [lo,hi]. + // * In Stockfish, this function is written in bitboard.h. template 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#縺ォ縺ゅkPath繧ッ繝ゥ繧ケ逧縺ェ繧ゅョ縲ゅヵ繧。繧、繝ォ蜷阪ョ謫堺ス懊 -// C#縺ョ繝。繧ス繝繝牙錐縺ォ蜷医o縺帙※縺翫¥縲 +// Something like Path class in C#. File name manipulation. +// Match with the C# method name. struct Path { - // path蜷阪→繝輔ぃ繧、繝ォ蜷阪r邨仙粋縺励※縲√◎繧後r霑斐☆縲 - // folder蜷阪ョ縺サ縺縺ッ遨コ譁蟄怜励〒縺ェ縺縺ィ縺阪↓縲∵忰蟆セ縺ォ'/'縺'\\'縺後↑縺代l縺ー縺昴l繧剃サ倅ク弱☆繧九 + // 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陦ィ迴セ縺九i縲(繝輔か繝ォ繝蜷阪r髯、縺縺)繝輔ぃ繧、繝ォ蜷阪ョ驛ィ蛻繧貞叙蠕励☆繧九 + // Get the file name part (excluding the folder name) from the full path expression. static std::string GetFileName(const std::string& path) { - // "\"縺"/"縺九√←縺。繧峨r菴ソ縺」縺ヲ縺ゅk縺九ッ繧上°繧峨↑縺縲 + // 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縺ョ縺ィ縺阪↓辟。隕悶&繧後kシSTL縺ョ繧ウ繝ウ繝繝翫′繝。繝「繝ェ遒コ菫昴☆繧九→縺阪↓辟。隕悶☆繧九ョ縺ァ縲 -// 縺昴ョ縺溘a縺ォ逕ィ縺繧九き繧ケ繧ソ繝繧「繝ュ繧ア繝シ繧ソ繝シ縲 +// 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 class AlignedAllocator { public: @@ -293,15 +291,15 @@ public: namespace Dependency { - // Linux迺ー蠅縺ァ縺ッgetline()縺励◆縺ィ縺阪↓繝繧ュ繧ケ繝医ヵ繧。繧、繝ォ縺'\r\n'縺縺ィ - // '\r'縺梧忰蟆セ縺ォ谿九k縺ョ縺ァ縺薙ョ'\r'繧帝勁蜴サ縺吶k縺溘a縺ォwrapper繧呈嶌縺上 - // 縺昴ョ縺溘a縲’stream縺ォ蟇セ縺励※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); - // 繝輔か繝ォ繝繧剃ス懈舌☆繧九 - // 繧ォ繝ャ繝ウ繝医ヵ繧ゥ繝ォ繝逶ク蟇セ縺ァ謖螳壹☆繧九Eir_name縺ォ譌・譛ャ隱槭ッ菴ソ縺」縺ヲ縺縺ェ縺繧ゅョ縺ィ縺吶k縲 - // 謌仙粥縺吶l縺ー0縲∝、ア謨励☆繧後ー髱0縺瑚ソ斐k縲 + // 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); } diff --git a/src/position.cpp b/src/position.cpp index a316304b..917d1646 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -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 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; diff --git a/src/position.h b/src/position.h index ec9d3be5..725be527 100644 --- a/src/position.h +++ b/src/position.h @@ -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> 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は含まないので復元できない。そこを設定したいのであれば引数で指定すること。 + // ↑ 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) }; diff --git a/src/search.cpp b/src/search.cpp index bc3cc745..68f97fca 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -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,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の設定 + // set rootMoves auto& rootMoves = th->rootMoves; rootMoves.clear(); - for (auto m : MoveList(pos)) + for (auto m: MoveList(pos)) rootMoves.push_back(Search::RootMove(m)); 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 ... - // → 同一の終局図に至るのを回避したいので、教師生成時には置換表は全スレ共通で使うようにする。 + // 竊達ecause 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 > 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(pos).size() == 0) { // Return the mated value if checkmated. @@ -2082,7 +2083,7 @@ namespace Learner auto bestValue = ::qsearch(pos, ss, -VALUE_INFINITE, VALUE_INFINITE, 0); - // 得られたPVを返す。 + // Returns the PV obtained. std::vector 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手読み時のスコアが欲しいなら、 - // auto v = search(pos,3); - // のようにすべし。 - // v.firstに評価値、v.secondにPVが得られる。 - // multi pvが有効のときは、pos.this_thread()->rootMoves[N].pvにそのPV(読み筋)の配列が得られる。 - // multi pvの指定はこの関数の引数multiPVで行なう。(Options["MultiPV"]の値は無視される) - // - // rootでの宣言勝ち判定はしないので(扱いが面倒なので)、ここでは行わない。 - // 呼び出し側で処理すること。 + // 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) // - // 前提条件) pos.set_this_thread(Threads[thread_id])で探索スレッドが設定されていること。 - //  また、Threads.stopが来ると探索を中断してしまうので、そのときのPVは正しくない。 - //  search()から戻ったあと、Threads.stop == trueなら、その探索結果を用いてはならない。 - //  あと、呼び出し前は、Threads.stop == falseの状態で呼び出さないと、探索を中断して返ってしまうので注意。 + // 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; // とりあえずダミーでどこかバッファがないといけない。 + 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個を探索する機能 - //size_t multiPV = Options["MultiPV"]; + // 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); diff --git a/src/types.h b/src/types.h index a4a9f315..33a35483 100644 --- a/src/types.h +++ b/src/types.h @@ -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° 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) diff --git a/src/uci.cpp b/src/uci.cpp index b7ece34b..13888d1a 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -44,22 +44,22 @@ extern vector 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 > 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 diff --git a/src/uci.h b/src/uci.h index 71e07787..d255db76 100644 --- a/src/uci.h +++ b/src/uci.h @@ -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; diff --git a/src/ucioption.cpp b/src/ucioption.cpp index 999941ed..c24884ce 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -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