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

Fixed crash bugs.

This commit is contained in:
Hisayori Noda 2019-06-20 00:25:40 +09:00
parent 24576d77ab
commit 90ef97dcbd
8 changed files with 108 additions and 42 deletions

View file

@ -22,6 +22,7 @@
#include <cassert> #include <cassert>
#include <cstring> // For std::memset #include <cstring> // For std::memset
#include <iomanip> #include <iomanip>
#include <set>
#include <sstream> #include <sstream>
#include "bitboard.h" #include "bitboard.h"
@ -938,6 +939,16 @@ ExtBonaPiece kpp_board_index[PIECE_NB] = {
// 注 : デバッグ用。遅い。 // 注 : デバッグ用。遅い。
bool EvalList::is_valid(const Position& pos) bool EvalList::is_valid(const Position& pos)
{ {
std::set<PieceNumber> piece_numbers;
for (Square sq = SQ_A1; sq != SQUARE_NB; ++sq) {
auto piece_number = piece_no_of_board(sq);
if (piece_number == PIECE_NUMBER_NB) {
continue;
}
assert(!piece_numbers.count(piece_number));
piece_numbers.insert(piece_number);
}
for (int i = 0; i < length(); ++i) for (int i = 0; i < length(); ++i)
{ {
BonaPiece fw = pieceListFw[i]; BonaPiece fw = pieceListFw[i];

View file

@ -187,7 +187,7 @@ public:
// VPGATHERDDを使う都合、4の倍数でなければならない。 // VPGATHERDDを使う都合、4の倍数でなければならない。
// また、KPPT型評価関数などは、39,40番目の要素がゼロであることを前提とした // また、KPPT型評価関数などは、39,40番目の要素がゼロであることを前提とした
// アクセスをしている箇所があるので注意すること。 // アクセスをしている箇所があるので注意すること。
static const int MAX_LENGTH = 40; static const int MAX_LENGTH = 32;
// 盤上の駒に対して、その駒番号(PieceNumber)を保持している配列 // 盤上の駒に対して、その駒番号(PieceNumber)を保持している配列
// 玉がSQUARE_NBに移動しているとき用に+1まで保持しておくが、 // 玉がSQUARE_NBに移動しているとき用に+1まで保持しておくが、

View file

@ -126,11 +126,12 @@ struct HuffmanedPiece
HuffmanedPiece huffman_table[] = HuffmanedPiece huffman_table[] =
{ {
{0b000,1}, // NO_PIECE {0b0000,1}, // NO_PIECE
{0b001,3}, // PAWN {0b0001,4}, // PAWN
{0b011,3}, // KNIGHT {0b0011,4}, // KNIGHT
{0b101,3}, // BISHOP {0b0101,4}, // BISHOP
{0b111,3}, // ROOK {0b0111,4}, // ROOK
{0b1001,4}, // QUEEN
}; };
// sfenを圧縮/解凍するためのクラス // sfenを圧縮/解凍するためのクラス
@ -269,6 +270,7 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
std::memset(this, 0, sizeof(Position)); std::memset(this, 0, sizeof(Position));
std::memset(si, 0, sizeof(StateInfo)); std::memset(si, 0, sizeof(StateInfo));
std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
st = si; st = si;
// Active color // Active color
@ -279,13 +281,7 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
// PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、 // PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、
// それぞれの駒をどこまで使ったかのカウンター // それぞれの駒をどこまで使ったかのカウンター
PieceNumber piece_no_count[KING] = { PieceNumber next_piece_number = PIECE_NUMBER_ZERO;
PIECE_NUMBER_ZERO,
PIECE_NUMBER_PAWN,
PIECE_NUMBER_KNIGHT,
PIECE_NUMBER_BISHOP,
PIECE_NUMBER_ROOK,
};
pieceList[W_KING][0] = SQUARE_NB; pieceList[W_KING][0] = SQUARE_NB;
pieceList[B_KING][0] = SQUARE_NB; pieceList[B_KING][0] = SQUARE_NB;
@ -294,12 +290,12 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
if (mirror) if (mirror)
{ {
for (auto c : Colors) for (auto c : Colors)
board[Mir((Square)stream.read_n_bit(7))] = make_piece(c, KING); board[Mir((Square)stream.read_n_bit(6))] = make_piece(c, KING);
} }
else else
{ {
for (auto c : Colors) for (auto c : Colors)
board[stream.read_n_bit(7)] = make_piece(c, KING); board[stream.read_n_bit(6)] = make_piece(c, KING);
} }
// Piece placement // Piece placement
@ -335,7 +331,7 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
PieceNumber piece_no = PieceNumber piece_no =
(pc == B_KING) ? PIECE_NUMBER_BKING : // 先手玉 (pc == B_KING) ? PIECE_NUMBER_BKING : // 先手玉
(pc == W_KING) ? PIECE_NUMBER_WKING : // 後手玉 (pc == W_KING) ? PIECE_NUMBER_WKING : // 後手玉
piece_no_count[type_of(pc)]++; // それ以外 next_piece_number++; // それ以外
evalList.put_piece(piece_no, sq, pc); // sqの升にpcの駒を配置する evalList.put_piece(piece_no, sq, pc); // sqの升にpcの駒を配置する
@ -363,12 +359,12 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
} }
if (stream.read_one_bit()) { if (stream.read_one_bit()) {
Square rsq; Square rsq;
for (rsq = relative_square(BLACK, SQ_H1); piece_on(rsq) != W_ROOK; --rsq) {} for (rsq = relative_square(BLACK, SQ_H1); piece_on(rsq) != B_ROOK; --rsq) {}
set_castling_right(BLACK, rsq); set_castling_right(BLACK, rsq);
} }
if (stream.read_one_bit()) { if (stream.read_one_bit()) {
Square rsq; Square rsq;
for (rsq = relative_square(BLACK, SQ_A1); piece_on(rsq) != W_ROOK; ++rsq) {} for (rsq = relative_square(BLACK, SQ_A1); piece_on(rsq) != B_ROOK; ++rsq) {}
set_castling_right(BLACK, rsq); set_castling_right(BLACK, rsq);
} }
@ -381,6 +377,9 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
|| !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))) || !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))))
st->epSquare = SQ_NONE; st->epSquare = SQ_NONE;
} }
else {
st->epSquare = SQ_NONE;
}
// Halfmove clock // Halfmove clock
st->rule50 = static_cast<Square>(stream.read_n_bit(6)); st->rule50 = static_cast<Square>(stream.read_n_bit(6));
@ -397,6 +396,8 @@ int Position::set_from_packed_sfen(const PackedSfen& sfen , StateInfo * si, Thre
thisThread = th; thisThread = th;
set_state(st); set_state(st);
//std::cout << *this << std::endl;
assert(pos_is_ok()); assert(pos_is_ok());
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
assert(evalList.is_valid(*this)); assert(evalList.is_valid(*this));

View file

@ -392,6 +392,16 @@ void MultiThinkGenSfen::thread_worker(size_t thread_id)
auto& pos = th->rootPos; auto& pos = th->rootPos;
pos.set(StartFEN, false, &si, th); pos.set(StartFEN, false, &si, th);
// Test cod for Packed SFEN.
//{
// PackedSfen packed_sfen;
// pos.sfen_pack(packed_sfen);
// std::cout << pos << std::endl;
// pos.set_from_packed_sfen(packed_sfen, &si, th);
// std::string actual = pos.fen();
// assert(actual == StartFEN);
//}
// 探索部で定義されているBookMoveSelectorのメンバを参照する。 // 探索部で定義されているBookMoveSelectorのメンバを参照する。
//auto& book = ::book; //auto& book = ::book;

View file

@ -249,14 +249,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
// PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、 // PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、
// それぞれの駒をどこまで使ったかのカウンター // それぞれの駒をどこまで使ったかのカウンター
PieceNumber piece_no_count[KING] = { PieceNumber next_piece_number = PIECE_NUMBER_ZERO;
PIECE_NUMBER_ZERO,
PIECE_NUMBER_PAWN,
PIECE_NUMBER_KNIGHT,
PIECE_NUMBER_BISHOP,
PIECE_NUMBER_ROOK,
PIECE_NUMBER_QUEEN
};
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
ss >> std::noskipws; ss >> std::noskipws;
@ -279,7 +272,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
PieceNumber piece_no = PieceNumber piece_no =
(idx == W_KING) ? PIECE_NUMBER_WKING : // 先手玉 (idx == W_KING) ? PIECE_NUMBER_WKING : // 先手玉
(idx == B_KING) ? PIECE_NUMBER_BKING : // 後手玉 (idx == B_KING) ? PIECE_NUMBER_BKING : // 後手玉
piece_no_count[type_of(Piece(idx))]++; // ‚»‚êˆÈŠO next_piece_number++; // »ę<E2809A>ČŠO
evalList.put_piece(piece_no, sq, pc); // sqの升にpcの駒を配置する evalList.put_piece(piece_no, sq, pc); // sqの升にpcの駒を配置する
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
@ -780,6 +773,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
Piece pc = piece_on(from); Piece pc = piece_on(from);
Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to); Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
PieceNumber piece_no0 = PIECE_NUMBER_NB;
PieceNumber piece_no1 = PIECE_NUMBER_NB;
assert(color_of(pc) == us); assert(color_of(pc) == us);
assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us)); assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
assert(type_of(captured) != KING); assert(type_of(captured) != KING);
@ -805,10 +801,6 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
{ {
Square capsq = to; Square capsq = to;
#if defined(EVAL_NNUE)
PieceNumber piece_no1;
#endif // defined(EVAL_NNUE)
// If the captured piece is a pawn, update pawn hash key, otherwise // If the captured piece is a pawn, update pawn hash key, otherwise
// update non-pawn material. // update non-pawn material.
if (type_of(captured) == PAWN) if (type_of(captured) == PAWN)
@ -828,6 +820,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
board[capsq] = NO_PIECE; // Not done by remove_piece() board[capsq] = NO_PIECE; // Not done by remove_piece()
evalList.piece_no_list_board[capsq] = PIECE_NUMBER_NB;
} }
else { else {
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
@ -893,7 +886,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// Move the piece. The tricky Chess960 castling is handled earlier // Move the piece. The tricky Chess960 castling is handled earlier
if (type_of(m) != CASTLING) { if (type_of(m) != CASTLING) {
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
PieceNumber piece_no0 = piece_no_of(from); piece_no0 = piece_no_of(from);
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
move_piece(pc, from, to); move_piece(pc, from, to);
@ -901,6 +894,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
dp.pieceNo[0] = piece_no0; dp.pieceNo[0] = piece_no0;
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
evalList.piece_no_list_board[from] = PIECE_NUMBER_NB;
evalList.put_piece(piece_no0, to, pc); evalList.put_piece(piece_no0, to, pc);
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
@ -928,9 +922,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
put_piece(promotion, to); put_piece(promotion, to);
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
PieceNumber piece_no0 = piece_no_of(to); piece_no0 = piece_no_of(to);
dp.pieceNo[0] = piece_no0; dp.pieceNo[0] = piece_no0;
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
assert(evalList.piece_no_list_board[from] == PIECE_NUMBER_NB);
evalList.put_piece(piece_no0, to, promotion); evalList.put_piece(piece_no0, to, promotion);
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
@ -985,6 +980,8 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
} }
} }
//std::cout << *this << std::endl;
assert(pos_is_ok()); assert(pos_is_ok());
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
assert(evalList.is_valid(*this)); assert(evalList.is_valid(*this));
@ -1038,6 +1035,7 @@ void Position::undo_move(Move m) {
#if defined(EVAL_NNUE) #if defined(EVAL_NNUE)
PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0]; PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0];
evalList.put_piece(piece_no0, from, pc); evalList.put_piece(piece_no0, from, pc);
evalList.piece_no_list_board[to] = PIECE_NUMBER_NB;
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)
if (st->capturedPiece) if (st->capturedPiece)
@ -1118,16 +1116,20 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
if (Do) { if (Do) {
dp.pieceNo[0] = piece_no0; dp.pieceNo[0] = piece_no0;
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
evalList.piece_no_list_board[from] = PIECE_NUMBER_NB;
evalList.put_piece(piece_no0, to, make_piece(us, KING)); evalList.put_piece(piece_no0, to, make_piece(us, KING));
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0); dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
dp.pieceNo[1] = piece_no1; dp.pieceNo[1] = piece_no1;
dp.changed_piece[1].old_piece = evalList.bona_piece(piece_no1); dp.changed_piece[1].old_piece = evalList.bona_piece(piece_no1);
evalList.piece_no_list_board[rfrom] = PIECE_NUMBER_NB;
evalList.put_piece(piece_no1, rto, make_piece(us, ROOK)); evalList.put_piece(piece_no1, rto, make_piece(us, ROOK));
dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1); dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1);
} }
else { else {
evalList.piece_no_list_board[to] = PIECE_NUMBER_NB;
evalList.put_piece(piece_no0, from, make_piece(us, KING)); evalList.put_piece(piece_no0, from, make_piece(us, KING));
evalList.piece_no_list_board[rto] = PIECE_NUMBER_NB;
evalList.put_piece(piece_no1, rfrom, make_piece(us, ROOK)); evalList.put_piece(piece_no1, rfrom, make_piece(us, ROOK));
} }
#endif // defined(EVAL_NNUE) #endif // defined(EVAL_NNUE)

View file

@ -871,7 +871,7 @@ moves_loop: // When in check, search starts from here
ss->moveCount = ++moveCount; ss->moveCount = ++moveCount;
if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000) if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000 && !Limits.silent)
sync_cout << "info depth " << depth / ONE_PLY sync_cout << "info depth " << depth / ONE_PLY
<< " currmove " << UCI::move(move, pos.is_chess960()) << " currmove " << UCI::move(move, pos.is_chess960())
<< " currmovenumber " << moveCount + thisThread->pvIdx << sync_endl; << " currmovenumber " << moveCount + thisThread->pvIdx << sync_endl;
@ -1382,7 +1382,9 @@ moves_loop: // When in check, search starts from here
ss->continuationHistory = &thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)]; ss->continuationHistory = &thisThread->continuationHistory[pos.moved_piece(move)][to_sq(move)];
// Make and search the move // Make and search the move
//std::cout << pos << std::endl;
pos.do_move(move, st, givesCheck); pos.do_move(move, st, givesCheck);
//std::cout << pos << std::endl;
value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth - ONE_PLY); value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth - ONE_PLY);
pos.undo_move(move); pos.undo_move(move);
@ -1740,7 +1742,7 @@ namespace Learner
// RootNodeはss->ply == 0がその条件。 // RootNodeはss->ply == 0がその条件。
// ゼロクリアするので、ss->ply == 0となるので大丈夫…。 // ゼロクリアするので、ss->ply == 0となるので大丈夫…。
memset(ss - 4, 0, 7 * sizeof(Stack)); std::memset(ss - 7, 0, 10 * sizeof(Stack));
// Search::Limitsに関して // Search::Limitsに関して
// このメンバー変数はglobalなので他のスレッドに影響を及ぼすので気をつけること。 // このメンバー変数はglobalなので他のスレッドに影響を及ぼすので気をつけること。
@ -1751,7 +1753,7 @@ namespace Learner
limits.infinite = true; limits.infinite = true;
// PVを表示されると邪魔なので消しておく。 // PVを表示されると邪魔なので消しておく。
//limits.silent = true; limits.silent = true;
// これを用いると各スレッドのnodesを積算したものと比較されてしまう。ゆえに使用しない。 // これを用いると各スレッドのnodesを積算したものと比較されてしまう。ゆえに使用しない。
limits.nodes = 0; limits.nodes = 0;
@ -1789,8 +1791,23 @@ namespace Learner
// history類を全部クリアする。この初期化は少し時間がかかるし、探索の精度はむしろ下がるので善悪はよくわからない。 // history類を全部クリアする。この初期化は少し時間がかかるし、探索の精度はむしろ下がるので善悪はよくわからない。
// th->clear(); // th->clear();
for (int i = 4; i > 0; i--) int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
(ss - i)->continuationHistory = &th->continuationHistory[SQUARE_ZERO][NO_PIECE]; Color us = pos.side_to_move();
// In analysis mode, adjust contempt in accordance with user preference
if (Limits.infinite || Options["UCI_AnalyseMode"])
ct = Options["Analysis Contempt"] == "Off" ? 0
: Options["Analysis Contempt"] == "Both" ? ct
: Options["Analysis Contempt"] == "White" && us == BLACK ? -ct
: Options["Analysis Contempt"] == "Black" && us == WHITE ? -ct
: ct;
// Evaluation score is from the white point of view
th->contempt = (us == WHITE ? make_score(ct, ct / 2)
: -make_score(ct, ct / 2));
for (int i = 7; i > 0; i--)
(ss - i)->continuationHistory = &th->continuationHistory[NO_PIECE][0]; // Use as sentinel
// rootMovesの設定 // rootMovesの設定
auto& rootMoves = th->rootMoves; auto& rootMoves = th->rootMoves;
@ -1831,7 +1848,7 @@ namespace Learner
// 悪い影響があるので、窓の範囲を指定できるようにするのをやめることにした。 // 悪い影響があるので、窓の範囲を指定できるようにするのをやめることにした。
ValueAndPV qsearch(Position& pos) ValueAndPV qsearch(Position& pos)
{ {
Stack stack[MAX_PLY + 7], * ss = stack + 4; Stack stack[MAX_PLY + 10], * ss = stack + 7;
Move pv[MAX_PLY + 1]; Move pv[MAX_PLY + 1];
std::vector<Move> pvs; std::vector<Move> pvs;
@ -1881,7 +1898,7 @@ namespace Learner
if (depth == DEPTH_ZERO) if (depth == DEPTH_ZERO)
return qsearch(pos); return qsearch(pos);
Stack stack[MAX_PLY + 7], * ss = stack + 4; Stack stack[MAX_PLY + 10], * ss = stack + 7;
Move pv[MAX_PLY + 1]; Move pv[MAX_PLY + 1];
init_for_search(pos, ss); init_for_search(pos, ss);
@ -1892,6 +1909,7 @@ namespace Learner
auto th = pos.this_thread(); auto th = pos.this_thread();
auto& rootDepth = th->rootDepth; auto& rootDepth = th->rootDepth;
auto& pvIdx = th->pvIdx; auto& pvIdx = th->pvIdx;
auto& pvLast = th->pvLast;
auto& rootMoves = th->rootMoves; auto& rootMoves = th->rootMoves;
auto& completedDepth = th->completedDepth; auto& completedDepth = th->completedDepth;
auto& selDepth = th->selDepth; auto& selDepth = th->selDepth;
@ -1919,9 +1937,20 @@ namespace Learner
for (RootMove& rm : rootMoves) for (RootMove& rm : rootMoves)
rm.previousScore = rm.score; rm.previousScore = rm.score;
// MultiPV size_t pvFirst = 0;
pvLast = 0;
// MultiPV loop. We perform a full root search for each PV line
for (pvIdx = 0; pvIdx < multiPV && !Threads.stop; ++pvIdx) for (pvIdx = 0; pvIdx < multiPV && !Threads.stop; ++pvIdx)
{ {
if (pvIdx == pvLast)
{
pvFirst = pvLast;
for (pvLast++; pvLast < rootMoves.size(); pvLast++)
if (rootMoves[pvLast].tbRank != rootMoves[pvFirst].tbRank)
break;
}
// それぞれのdepthとPV lineに対するUSI infoで出力するselDepth // それぞれのdepthとPV lineに対するUSI infoで出力するselDepth
selDepth = 0; selDepth = 0;

View file

@ -86,6 +86,7 @@ struct LimitsType {
time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] = npmsec = movetime = TimePoint(0); time[WHITE] = time[BLACK] = inc[WHITE] = inc[BLACK] = npmsec = movetime = TimePoint(0);
movestogo = depth = mate = perft = infinite = 0; movestogo = depth = mate = perft = infinite = 0;
nodes = 0; nodes = 0;
silent = false;
} }
bool use_time_management() const { bool use_time_management() const {
@ -96,6 +97,9 @@ struct LimitsType {
TimePoint time[COLOR_NB], inc[COLOR_NB], npmsec, movetime, startTime; TimePoint time[COLOR_NB], inc[COLOR_NB], npmsec, movetime, startTime;
int movestogo, depth, mate, perft, infinite; int movestogo, depth, mate, perft, infinite;
int64_t nodes; int64_t nodes;
// 画面に出力しないサイレントモード(プロセス内での連続自己対戦のとき用)
// このときPVを出力しない。
bool silent;
}; };
extern LimitsType Limits; extern LimitsType Limits;

View file

@ -87,6 +87,15 @@ void init(OptionsMap& o) {
// そこでこの隠しオプションでisready時の評価関数の読み込みを抑制して、 // そこでこの隠しオプションでisready時の評価関数の読み込みを抑制して、
// test evalconvertコマンドを叩く。 // test evalconvertコマンドを叩く。
o["SkipLoadingEval"] << Option(false); o["SkipLoadingEval"] << Option(false);
// 定跡の指し手を何手目まで用いるか
o["BookMoves"] << Option(16, 0, 10000);
#if defined(EVAL_LEARN)
// 評価関数の学習を行なうときは、評価関数の保存先のフォルダを変更できる。
// デフォルトではevalsave。このフォルダは事前に用意されているものとする。
// このフォルダ配下にフォルダを"0/","1/",…のように自動的に掘り、そこに評価関数ファイルを保存する。
o["EvalSaveDir"] << Option("evalsave");
#endif
} }