Merge branch 'master' of https://github.com/nodchip/Stockfish into sf-nnue-nodchip

This commit is contained in:
joergoster
2020-06-24 17:47:55 +02:00
70 changed files with 12108 additions and 27 deletions
+180 -4
View File
@@ -209,6 +209,15 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
st = si;
#if defined(EVAL_NNUE)
// evalListのclear。上でmemsetでゼロクリアしたときにクリアされているが…。
evalList.clear();
// PieceListを更新する上で、どの駒がどこにあるかを設定しなければならないが、
// それぞれの駒をどこまで使ったかのカウンター
PieceNumber next_piece_number = PIECE_NUMBER_ZERO;
#endif // defined(EVAL_NNUE)
ss >> std::noskipws;
// 1. Piece placement
@@ -222,7 +231,17 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
else if ((idx = PieceToChar.find(token)) != string::npos)
{
put_piece(Piece(idx), sq);
auto pc = Piece(idx);
put_piece(pc, sq);
#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の駒を配置する
#endif // defined(EVAL_NNUE)
++sq;
}
}
@@ -285,6 +304,9 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
set_state(st);
assert(pos_is_ok());
#if defined(EVAL_NNUE)
assert(evalList.is_valid(*this));
#endif // defined(EVAL_NNUE)
return *this;
}
@@ -706,6 +728,11 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
++st->rule50;
++st->pliesFromNull;
#if defined(EVAL_NNUE)
st->accumulator.computed_accumulation = false;
st->accumulator.computed_score = false;
#endif // defined(EVAL_NNUE)
Color us = sideToMove;
Color them = ~us;
Square from = from_sq(m);
@@ -713,10 +740,20 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
Piece pc = piece_on(from);
Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);
#if defined(EVAL_NNUE)
PieceNumber piece_no0 = PIECE_NUMBER_NB;
PieceNumber piece_no1 = PIECE_NUMBER_NB;
#endif // defined(EVAL_NNUE)
assert(color_of(pc) == us);
assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
assert(type_of(captured) != KING);
#if defined(EVAL_NNUE)
auto& dp = st->dirtyPiece;
dp.dirty_num = 1;
#endif // defined(EVAL_NNUE)
if (type_of(m) == CASTLING)
{
assert(pc == make_piece(us, KING));
@@ -746,13 +783,32 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
assert(relative_rank(us, to) == RANK_6);
assert(piece_on(to) == NO_PIECE);
assert(piece_on(capsq) == make_piece(them, PAWN));
#if defined(EVAL_NNUE)
piece_no1 = piece_no_of(capsq);
#endif // defined(EVAL_NNUE)
//board[capsq] = NO_PIECE; // Not done by remove_piece()
#if defined(EVAL_NNUE)
evalList.piece_no_list_board[capsq] = PIECE_NUMBER_NB;
#endif // defined(EVAL_NNUE)
}
else {
#if defined(EVAL_NNUE)
piece_no1 = piece_no_of(capsq);
#endif // defined(EVAL_NNUE)
}
st->pawnKey ^= Zobrist::psq[captured][capsq];
}
else
else {
st->nonPawnMaterial[them] -= PieceValue[MG][captured];
#if defined(EVAL_NNUE)
piece_no1 = piece_no_of(capsq);
#endif // defined(EVAL_NNUE)
}
// Update board and piece lists
remove_piece(capsq);
@@ -766,6 +822,21 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
// Reset rule 50 counter
st->rule50 = 0;
#if defined(EVAL_NNUE)
dp.dirty_num = 2; // 動いた駒は2個
dp.pieceNo[1] = piece_no1;
dp.changed_piece[1].old_piece = evalList.bona_piece(piece_no1);
// Do not use Eval::EvalList::put_piece() because the piece is removed
// from the game, and the corresponding elements of the piece lists
// needs to be Eval::BONA_PIECE_ZERO.
evalList.set_piece_on_board(piece_no1, Eval::BONA_PIECE_ZERO, Eval::BONA_PIECE_ZERO, capsq);
// Set PIECE_NUMBER_NB to piece_no_of_board[capsq] directly because it
// will not be overritten to pc if the move type is enpassant.
evalList.piece_no_list_board[capsq] = PIECE_NUMBER_NB;
dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1);
#endif // defined(EVAL_NNUE)
}
// Update hash key
@@ -787,8 +858,21 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
}
// Move the piece. The tricky Chess960 castling is handled earlier
if (type_of(m) != CASTLING)
move_piece(from, to);
if (type_of(m) != CASTLING) {
#if defined(EVAL_NNUE)
piece_no0 = piece_no_of(from);
#endif // defined(EVAL_NNUE)
move_piece(from, to);
#if defined(EVAL_NNUE)
dp.pieceNo[0] = 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);
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
#endif // defined(EVAL_NNUE)
}
// If the moving piece is a pawn do some special extra work
if (type_of(pc) == PAWN)
@@ -811,6 +895,15 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
remove_piece(to);
put_piece(promotion, to);
#if defined(EVAL_NNUE)
piece_no0 = piece_no_of(to);
//dp.pieceNo[0] = 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);
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
#endif // defined(EVAL_NNUE)
// Update hash keys
k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
st->pawnKey ^= Zobrist::psq[pc][to];
@@ -861,7 +954,12 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
}
}
//std::cout << *this << std::endl;
assert(pos_is_ok());
#if defined(EVAL_NNUE)
assert(evalList.is_valid(*this));
#endif // defined(EVAL_NNUE)
}
@@ -891,6 +989,11 @@ void Position::undo_move(Move m) {
remove_piece(to);
pc = make_piece(us, PAWN);
put_piece(pc, to);
#if defined(EVAL_NNUE)
PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0];
evalList.put_piece(piece_no0, to, pc);
#endif // defined(EVAL_NNUE)
}
if (type_of(m) == CASTLING)
@@ -900,8 +1003,15 @@ void Position::undo_move(Move m) {
}
else
{
move_piece(to, from); // Put the piece back at the source square
#if defined(EVAL_NNUE)
PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0];
evalList.put_piece(piece_no0, from, pc);
evalList.piece_no_list_board[to] = PIECE_NUMBER_NB;
#endif // defined(EVAL_NNUE)
if (st->capturedPiece)
{
Square capsq = to;
@@ -918,6 +1028,13 @@ void Position::undo_move(Move m) {
}
put_piece(st->capturedPiece, capsq); // Restore the captured piece
#if defined(EVAL_NNUE)
PieceNumber piece_no1 = st->dirtyPiece.pieceNo[1];
assert(evalList.bona_piece(piece_no1).fw == Eval::BONA_PIECE_ZERO);
assert(evalList.bona_piece(piece_no1).fb == Eval::BONA_PIECE_ZERO);
evalList.put_piece(piece_no1, capsq, st->capturedPiece);
#endif // defined(EVAL_NNUE)
}
}
@@ -926,6 +1043,9 @@ void Position::undo_move(Move m) {
--gamePly;
assert(pos_is_ok());
#if defined(EVAL_NNUE)
assert(evalList.is_valid(*this));
#endif // defined(EVAL_NNUE)
}
@@ -933,18 +1053,60 @@ void Position::undo_move(Move m) {
/// is a bit tricky in Chess960 where from/to squares can overlap.
template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
#if defined(EVAL_NNUE)
auto& dp = st->dirtyPiece;
// 差分計算のために移動した駒をStateInfoに記録しておく。
dp.dirty_num = 2; // 動いた駒は2個
PieceNumber piece_no0;
PieceNumber piece_no1;
if (Do) {
piece_no0 = piece_no_of(from);
piece_no1 = piece_no_of(to);
}
#endif // defined(EVAL_NNUE)
bool kingSide = to > from;
rfrom = to; // Castling is encoded as "king captures friendly rook"
rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
#if defined(EVAL_NNUE)
if (!Do) {
piece_no0 = piece_no_of(to);
piece_no1 = piece_no_of(rto);
}
#endif // defined(EVAL_NNUE)
// Remove both pieces first since squares could overlap in Chess960
remove_piece(Do ? from : to);
remove_piece(Do ? rfrom : rto);
board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do this for us
put_piece(make_piece(us, KING), Do ? to : from);
put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
#if defined(EVAL_NNUE)
if (Do) {
dp.pieceNo[0] = 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));
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
dp.pieceNo[1] = 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));
dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1);
}
else {
evalList.piece_no_list_board[to] = PIECE_NUMBER_NB;
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));
}
#endif // defined(EVAL_NNUE)
}
@@ -969,6 +1131,10 @@ void Position::do_null_move(StateInfo& newSt) {
st->key ^= Zobrist::side;
prefetch(TT.first_entry(st->key));
#if defined(EVAL_NNUE)
st->accumulator.computed_score = false;
#endif
++st->rule50;
st->pliesFromNull = 0;
@@ -1297,3 +1463,13 @@ bool Position::pos_is_ok() const {
return true;
}
#if defined(EVAL_NNUE)
PieceNumber Position::piece_no_of(Square sq) const
{
assert(piece_on(sq) != NO_PIECE);
PieceNumber n = evalList.piece_no_of_board(sq);
assert(is_ok(n));
return n;
}
#endif // defined(EVAL_NNUE)