mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 09:13:08 +00:00
Fixed crash bugs.
This commit is contained in:
parent
24576d77ab
commit
90ef97dcbd
8 changed files with 108 additions and 42 deletions
|
@ -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];
|
||||||
|
|
|
@ -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まで保持しておくが、
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue