mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-22 01:56:58 +08:00
Implemented the logic to update Eval List and Dirty Pieces.
This commit is contained in:
131
src/position.cpp
131
src/position.cpp
@@ -243,6 +243,20 @@ 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;
|
||||
|
||||
// evalList<73><74>clear<61>B<EFBFBD><42><EFBFBD><EFBFBD>memset<65>Ń[<5B><><EFBFBD>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682>ɃN<C983><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>邪<EFBFBD>c<EFBFBD>B
|
||||
evalList.clear();
|
||||
|
||||
// PieceList<73><74><EFBFBD>X<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŁA<C581>ǂ̋<CC8B>ǂ<EFBFBD><C782>ɂ<EFBFBD><C982>邩<EFBFBD><E982A9><EFBFBD>ݒ肵<DD92>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>Ȃ<CE82><C882>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>A
|
||||
// <20><><EFBFBD>ꂼ<EFBFBD><EA82BC><EFBFBD>̋<EFBFBD><CC8B><EFBFBD><EFBFBD>ǂ<EFBFBD><C782>܂Ŏg<C58E><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̃J<CC83>E<EFBFBD><45><EFBFBD>^<5E>[
|
||||
PieceNumber piece_no_count[KING] = {
|
||||
PIECE_NUMBER_ZERO,
|
||||
PIECE_NUMBER_PAWN,
|
||||
PIECE_NUMBER_KNIGHT,
|
||||
PIECE_NUMBER_BISHOP,
|
||||
PIECE_NUMBER_ROOK,
|
||||
PIECE_NUMBER_QUEEN
|
||||
};
|
||||
|
||||
ss >> std::noskipws;
|
||||
|
||||
// 1. Piece placement
|
||||
@@ -256,7 +270,15 @@ 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);
|
||||
|
||||
PieceNumber piece_no =
|
||||
(idx == W_KING) ? PIECE_NUMBER_WKING : // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
(idx == B_KING) ? PIECE_NUMBER_BKING : // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
piece_no_count[type_of(Piece(idx))]++; // <20><><EFBFBD><EFBFBD><EFBFBD>ȊO
|
||||
evalList.put_piece(piece_no, sq, pc); // sq<73>̏<EFBFBD><CC8F><EFBFBD>pc<70>̋<EFBFBD><CC8B><EFBFBD><EFBFBD>z<EFBFBD>u<EFBFBD><75><EFBFBD><EFBFBD>
|
||||
|
||||
++sq;
|
||||
}
|
||||
}
|
||||
@@ -319,6 +341,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
|
||||
set_state(st);
|
||||
|
||||
assert(pos_is_ok());
|
||||
assert(evalList.is_valid(*this));
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -739,6 +762,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
++st->rule50;
|
||||
++st->pliesFromNull;
|
||||
|
||||
st->accumulator.computed_accumulation = false;
|
||||
st->accumulator.computed_score = false;
|
||||
|
||||
Color us = sideToMove;
|
||||
Color them = ~us;
|
||||
Square from = from_sq(m);
|
||||
@@ -750,6 +776,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
|
||||
assert(type_of(captured) != KING);
|
||||
|
||||
auto& dp = st->dirtyPiece;
|
||||
dp.dirty_num = 1;
|
||||
|
||||
if (type_of(m) == CASTLING)
|
||||
{
|
||||
assert(pc == make_piece(us, KING));
|
||||
@@ -766,6 +795,8 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
{
|
||||
Square capsq = to;
|
||||
|
||||
PieceNumber piece_no1;
|
||||
|
||||
// If the captured piece is a pawn, update pawn hash key, otherwise
|
||||
// update non-pawn material.
|
||||
if (type_of(captured) == PAWN)
|
||||
@@ -780,14 +811,22 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
assert(piece_on(to) == NO_PIECE);
|
||||
assert(piece_on(capsq) == make_piece(them, PAWN));
|
||||
|
||||
piece_no1 = piece_no_of(capsq);
|
||||
|
||||
board[capsq] = NO_PIECE; // Not done by remove_piece()
|
||||
}
|
||||
else {
|
||||
piece_no1 = piece_no_of(capsq);
|
||||
}
|
||||
|
||||
st->pawnKey ^= Zobrist::psq[captured][capsq];
|
||||
}
|
||||
else
|
||||
else {
|
||||
st->nonPawnMaterial[them] -= PieceValue[MG][captured];
|
||||
|
||||
piece_no1 = piece_no_of(capsq);
|
||||
}
|
||||
|
||||
// Update board and piece lists
|
||||
remove_piece(captured, capsq);
|
||||
|
||||
@@ -798,6 +837,19 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
|
||||
// Reset rule 50 counter
|
||||
st->rule50 = 0;
|
||||
|
||||
dp.dirty_num = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Update hash key
|
||||
@@ -819,8 +871,16 @@ 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(pc, from, to);
|
||||
if (type_of(m) != CASTLING) {
|
||||
PieceNumber piece_no0 = piece_no_of(from);
|
||||
|
||||
move_piece(pc, from, to);
|
||||
|
||||
dp.pieceNo[0] = piece_no0;
|
||||
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
|
||||
evalList.put_piece(piece_no0, to, pc);
|
||||
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
|
||||
}
|
||||
|
||||
// If the moving piece is a pawn do some special extra work
|
||||
if (type_of(pc) == PAWN)
|
||||
@@ -843,6 +903,12 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
remove_piece(pc, to);
|
||||
put_piece(promotion, to);
|
||||
|
||||
PieceNumber piece_no0 = piece_no_of(to);
|
||||
dp.pieceNo[0] = piece_no0;
|
||||
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
|
||||
evalList.put_piece(piece_no0, to, promotion);
|
||||
dp.changed_piece[0].new_piece = evalList.bona_piece(piece_no0);
|
||||
|
||||
// Update hash keys
|
||||
k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
|
||||
st->pawnKey ^= Zobrist::psq[pc][to];
|
||||
@@ -894,6 +960,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
}
|
||||
|
||||
assert(pos_is_ok());
|
||||
assert(evalList.is_valid(*this));
|
||||
}
|
||||
|
||||
|
||||
@@ -923,6 +990,9 @@ void Position::undo_move(Move m) {
|
||||
remove_piece(pc, to);
|
||||
pc = make_piece(us, PAWN);
|
||||
put_piece(pc, to);
|
||||
|
||||
PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0];
|
||||
evalList.put_piece(piece_no0, to, pc);
|
||||
}
|
||||
|
||||
if (type_of(m) == CASTLING)
|
||||
@@ -932,8 +1002,12 @@ void Position::undo_move(Move m) {
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
move_piece(pc, to, from); // Put the piece back at the source square
|
||||
|
||||
PieceNumber piece_no0 = st->dirtyPiece.pieceNo[0];
|
||||
evalList.put_piece(piece_no0, from, pc);
|
||||
|
||||
if (st->capturedPiece)
|
||||
{
|
||||
Square capsq = to;
|
||||
@@ -950,6 +1024,11 @@ void Position::undo_move(Move m) {
|
||||
}
|
||||
|
||||
put_piece(st->capturedPiece, capsq); // Restore the captured piece
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -958,6 +1037,7 @@ void Position::undo_move(Move m) {
|
||||
--gamePly;
|
||||
|
||||
assert(pos_is_ok());
|
||||
assert(evalList.is_valid(*this));
|
||||
}
|
||||
|
||||
|
||||
@@ -965,18 +1045,50 @@ 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) {
|
||||
auto& dp = st->dirtyPiece;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>v<EFBFBD>Z<EFBFBD>̂<EFBFBD><CC82>߂Ɉړ<C988><DA93><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>StateInfo<66>ɋL<C98B>^<5E><><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
|
||||
dp.dirty_num = 2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>
|
||||
|
||||
PieceNumber piece_no0;
|
||||
PieceNumber piece_no1;
|
||||
|
||||
if (Do) {
|
||||
piece_no0 = piece_no_of(from);
|
||||
piece_no1 = piece_no_of(to);
|
||||
}
|
||||
|
||||
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 (!Do) {
|
||||
piece_no0 = piece_no_of(to);
|
||||
piece_no1 = piece_no_of(rto);
|
||||
}
|
||||
|
||||
// Remove both pieces first since squares could overlap in Chess960
|
||||
remove_piece(make_piece(us, KING), Do ? from : to);
|
||||
remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
|
||||
board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
|
||||
put_piece(make_piece(us, KING), Do ? to : from);
|
||||
put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
|
||||
|
||||
if (Do) {
|
||||
dp.pieceNo[0] = piece_no0;
|
||||
dp.changed_piece[0].old_piece = evalList.bona_piece(piece_no0);
|
||||
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.put_piece(piece_no1, rto, make_piece(us, ROOK));
|
||||
dp.changed_piece[1].new_piece = evalList.bona_piece(piece_no1);
|
||||
}
|
||||
else {
|
||||
evalList.put_piece(piece_no0, from, make_piece(us, KING));
|
||||
evalList.put_piece(piece_no1, rfrom, make_piece(us, ROOK));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1313,3 +1425,14 @@ bool Position::pos_is_ok() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PieceNumber Position::piece_no_of(Square sq) const
|
||||
{
|
||||
if (piece_on(sq) == NO_PIECE) {
|
||||
sync_cout << *this << sync_endl;
|
||||
}
|
||||
assert(piece_on(sq) != NO_PIECE);
|
||||
PieceNumber n = evalList.piece_no_of_board(sq);
|
||||
assert(is_ok(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user