mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2025-12-14 01:42:40 +01:00
Update to Stockfish 12
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
|
||||
Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
|
||||
Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
|
||||
Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
|
||||
Copyright (C) 2004-2020 The Stockfish developers (see AUTHORS file)
|
||||
|
||||
Stockfish is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -105,8 +103,7 @@ Key cuckoo[8192];
|
||||
Move cuckooMove[8192];
|
||||
|
||||
|
||||
/// Position::init() initializes at startup the various arrays used to compute
|
||||
/// hash keys.
|
||||
/// Position::init() initializes at startup the various arrays used to compute hash keys
|
||||
|
||||
void Position::init() {
|
||||
|
||||
@@ -120,15 +117,7 @@ void Position::init() {
|
||||
Zobrist::enpassant[f] = rng.rand<Key>();
|
||||
|
||||
for (int cr = NO_CASTLING; cr <= ANY_CASTLING; ++cr)
|
||||
{
|
||||
Zobrist::castling[cr] = 0;
|
||||
Bitboard b = cr;
|
||||
while (b)
|
||||
{
|
||||
Key k = Zobrist::castling[1ULL << pop_lsb(&b)];
|
||||
Zobrist::castling[cr] ^= k ? k : rng.rand<Key>();
|
||||
}
|
||||
}
|
||||
Zobrist::castling[cr] = rng.rand<Key>();
|
||||
|
||||
Zobrist::side = rng.rand<Key>();
|
||||
Zobrist::noPawns = rng.rand<Key>();
|
||||
@@ -187,9 +176,9 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
|
||||
|
||||
4) En passant target square (in algebraic notation). If there's no en passant
|
||||
target square, this is "-". If a pawn has just made a 2-square move, this
|
||||
is the position "behind" the pawn. This is recorded only if there is a pawn
|
||||
in position to make an en passant capture, and if there really is a pawn
|
||||
that might have advanced two squares.
|
||||
is the position "behind" the pawn. Following X-FEN standard, this is recorded only
|
||||
if there is a pawn in position to make an en passant capture, and if there really
|
||||
is a pawn that might have advanced two squares.
|
||||
|
||||
5) Halfmove clock. This is the number of halfmoves since the last pawn advance
|
||||
or capture. This is used to determine if a draw can be claimed under the
|
||||
@@ -220,8 +209,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
|
||||
else if (token == '/')
|
||||
sq += 2 * SOUTH;
|
||||
|
||||
else if ((idx = PieceToChar.find(token)) != string::npos)
|
||||
{
|
||||
else if ((idx = PieceToChar.find(token)) != string::npos) {
|
||||
put_piece(Piece(idx), sq);
|
||||
++sq;
|
||||
}
|
||||
@@ -260,17 +248,25 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
|
||||
set_castling_right(c, rsq);
|
||||
}
|
||||
|
||||
// 4. En passant square. Ignore if no pawn capture is possible
|
||||
// 4. En passant square.
|
||||
// Ignore if square is invalid or not on side to move relative rank 6.
|
||||
bool enpassant = false;
|
||||
|
||||
if ( ((ss >> col) && (col >= 'a' && col <= 'h'))
|
||||
&& ((ss >> row) && (row == '3' || row == '6')))
|
||||
&& ((ss >> row) && (row == (sideToMove == WHITE ? '6' : '3'))))
|
||||
{
|
||||
st->epSquare = make_square(File(col - 'a'), Rank(row - '1'));
|
||||
|
||||
if ( !(attackers_to(st->epSquare) & pieces(sideToMove, PAWN))
|
||||
|| !(pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove))))
|
||||
st->epSquare = SQ_NONE;
|
||||
// En passant square will be considered only if
|
||||
// a) side to move have a pawn threatening epSquare
|
||||
// b) there is an enemy pawn in front of epSquare
|
||||
// c) there is no piece on epSquare or behind epSquare
|
||||
enpassant = pawn_attacks_bb(~sideToMove, st->epSquare) & pieces(sideToMove, PAWN)
|
||||
&& (pieces(~sideToMove, PAWN) & (st->epSquare + pawn_push(~sideToMove)))
|
||||
&& !(pieces() & (st->epSquare | (st->epSquare + pawn_push(sideToMove))));
|
||||
}
|
||||
else
|
||||
|
||||
if (!enpassant)
|
||||
st->epSquare = SQ_NONE;
|
||||
|
||||
// 5-6. Halfmove clock and fullmove number
|
||||
@@ -706,6 +702,12 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
++st->rule50;
|
||||
++st->pliesFromNull;
|
||||
|
||||
// Used by NNUE
|
||||
st->accumulator.computed_accumulation = false;
|
||||
st->accumulator.computed_score = false;
|
||||
auto& dp = st->dirtyPiece;
|
||||
dp.dirty_num = 1;
|
||||
|
||||
Color us = sideToMove;
|
||||
Color them = ~us;
|
||||
Square from = from_sq(m);
|
||||
@@ -753,6 +755,14 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
else
|
||||
st->nonPawnMaterial[them] -= PieceValue[MG][captured];
|
||||
|
||||
if (Eval::useNNUE)
|
||||
{
|
||||
dp.dirty_num = 2; // 1 piece moved, 1 piece captured
|
||||
dp.piece[1] = captured;
|
||||
dp.from[1] = capsq;
|
||||
dp.to[1] = SQ_NONE;
|
||||
}
|
||||
|
||||
// Update board and piece lists
|
||||
remove_piece(capsq);
|
||||
|
||||
@@ -781,14 +791,23 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
// Update castling rights if needed
|
||||
if (st->castlingRights && (castlingRightsMask[from] | castlingRightsMask[to]))
|
||||
{
|
||||
int cr = castlingRightsMask[from] | castlingRightsMask[to];
|
||||
k ^= Zobrist::castling[st->castlingRights & cr];
|
||||
st->castlingRights &= ~cr;
|
||||
k ^= Zobrist::castling[st->castlingRights];
|
||||
st->castlingRights &= ~(castlingRightsMask[from] | castlingRightsMask[to]);
|
||||
k ^= Zobrist::castling[st->castlingRights];
|
||||
}
|
||||
|
||||
// Move the piece. The tricky Chess960 castling is handled earlier
|
||||
if (type_of(m) != CASTLING)
|
||||
{
|
||||
if (Eval::useNNUE)
|
||||
{
|
||||
dp.piece[0] = pc;
|
||||
dp.from[0] = from;
|
||||
dp.to[0] = to;
|
||||
}
|
||||
|
||||
move_piece(from, to);
|
||||
}
|
||||
|
||||
// If the moving piece is a pawn do some special extra work
|
||||
if (type_of(pc) == PAWN)
|
||||
@@ -811,6 +830,16 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
remove_piece(to);
|
||||
put_piece(promotion, to);
|
||||
|
||||
if (Eval::useNNUE)
|
||||
{
|
||||
// Promoting pawn to SQ_NONE, promoted piece from SQ_NONE
|
||||
dp.to[0] = SQ_NONE;
|
||||
dp.piece[dp.dirty_num] = promotion;
|
||||
dp.from[dp.dirty_num] = SQ_NONE;
|
||||
dp.to[dp.dirty_num] = to;
|
||||
dp.dirty_num++;
|
||||
}
|
||||
|
||||
// Update hash keys
|
||||
k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
|
||||
st->pawnKey ^= Zobrist::psq[pc][to];
|
||||
@@ -939,6 +968,18 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
|
||||
rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
|
||||
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
|
||||
|
||||
if (Do && Eval::useNNUE)
|
||||
{
|
||||
auto& dp = st->dirtyPiece;
|
||||
dp.piece[0] = make_piece(us, KING);
|
||||
dp.from[0] = from;
|
||||
dp.to[0] = to;
|
||||
dp.piece[1] = make_piece(us, ROOK);
|
||||
dp.from[1] = rfrom;
|
||||
dp.to[1] = rto;
|
||||
dp.dirty_num = 2;
|
||||
}
|
||||
|
||||
// Remove both pieces first since squares could overlap in Chess960
|
||||
remove_piece(Do ? from : to);
|
||||
remove_piece(Do ? rfrom : rto);
|
||||
@@ -956,7 +997,14 @@ void Position::do_null_move(StateInfo& newSt) {
|
||||
assert(!checkers());
|
||||
assert(&newSt != st);
|
||||
|
||||
std::memcpy(&newSt, st, sizeof(StateInfo));
|
||||
if (Eval::useNNUE)
|
||||
{
|
||||
std::memcpy(&newSt, st, sizeof(StateInfo));
|
||||
st->accumulator.computed_score = false;
|
||||
}
|
||||
else
|
||||
std::memcpy(&newSt, st, offsetof(StateInfo, accumulator));
|
||||
|
||||
newSt.previous = st;
|
||||
st = &newSt;
|
||||
|
||||
@@ -1048,8 +1096,8 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||
|
||||
// Don't allow pinned pieces to attack (except the king) as long as
|
||||
// there are pinners on their original square.
|
||||
if (st->pinners[~stm] & occupied)
|
||||
stmAttackers &= ~st->blockersForKing[stm];
|
||||
if (pinners(~stm) & occupied)
|
||||
stmAttackers &= ~blockers_for_king(stm);
|
||||
|
||||
if (!stmAttackers)
|
||||
break;
|
||||
@@ -1112,6 +1160,7 @@ bool Position::see_ge(Move m, Value threshold) const {
|
||||
return bool(res);
|
||||
}
|
||||
|
||||
|
||||
/// Position::is_draw() tests whether the position is drawn by 50-move rule
|
||||
/// or by repetition. It does not detect stalemates.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user