mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-21 09:37:16 +08:00
Remove piece lists
This patch removes the incrementally updated piece lists from the Position object.
This has been tried before but always failed. My reasons for trying again are:
* 32-bit systems (including phones) are now much less important than they were some years ago (and are absent from fishtest);
* NNUE may have made SF less finely tuned to the order in which moves were generated.
STC:
LLR: 2.94 (-2.94,2.94) {-1.25,0.25}
Total: 55272 W: 5260 L: 5216 D: 44796
Ptnml(0-2): 208, 4147, 18898, 4159, 224
https://tests.stockfishchess.org/tests/view/5fc2986a42a050a89f02c926
LTC:
LLR: 2.96 (-2.94,2.94) {-0.75,0.25}
Total: 16600 W: 673 L: 608 D: 15319
Ptnml(0-2): 14, 533, 7138, 604, 11
https://tests.stockfishchess.org/tests/view/5fc2f98342a050a89f02c95c
closes https://github.com/official-stockfish/Stockfish/pull/3247
Bench: 3940967
This commit is contained in:
committed by
Joost VandeVondele
parent
2bc4ae172a
commit
045728a7da
@@ -553,8 +553,8 @@ ScaleFactor Endgame<KRPPKRP>::operator()(const Position& pos) const {
|
|||||||
assert(verify_material(pos, strongSide, RookValueMg, 2));
|
assert(verify_material(pos, strongSide, RookValueMg, 2));
|
||||||
assert(verify_material(pos, weakSide, RookValueMg, 1));
|
assert(verify_material(pos, weakSide, RookValueMg, 1));
|
||||||
|
|
||||||
Square strongPawn1 = pos.squares<PAWN>(strongSide)[0];
|
Square strongPawn1 = lsb(pos.pieces(strongSide, PAWN));
|
||||||
Square strongPawn2 = pos.squares<PAWN>(strongSide)[1];
|
Square strongPawn2 = msb(pos.pieces(strongSide, PAWN));
|
||||||
Square weakKing = pos.square<KING>(weakSide);
|
Square weakKing = pos.square<KING>(weakSide);
|
||||||
|
|
||||||
// Does the stronger side have a passed pawn?
|
// Does the stronger side have a passed pawn?
|
||||||
@@ -638,8 +638,8 @@ ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
|
|||||||
return SCALE_FACTOR_NONE;
|
return SCALE_FACTOR_NONE;
|
||||||
|
|
||||||
Square weakKing = pos.square<KING>(weakSide);
|
Square weakKing = pos.square<KING>(weakSide);
|
||||||
Square strongPawn1 = pos.squares<PAWN>(strongSide)[0];
|
Square strongPawn1 = lsb(pos.pieces(strongSide, PAWN));
|
||||||
Square strongPawn2 = pos.squares<PAWN>(strongSide)[1];
|
Square strongPawn2 = msb(pos.pieces(strongSide, PAWN));
|
||||||
Square blockSq1, blockSq2;
|
Square blockSq1, blockSq2;
|
||||||
|
|
||||||
if (relative_rank(strongSide, strongPawn1) > relative_rank(strongSide, strongPawn2))
|
if (relative_rank(strongSide, strongPawn1) > relative_rank(strongSide, strongPawn2))
|
||||||
|
|||||||
@@ -387,15 +387,15 @@ namespace {
|
|||||||
constexpr Direction Down = -pawn_push(Us);
|
constexpr Direction Down = -pawn_push(Us);
|
||||||
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
||||||
: Rank5BB | Rank4BB | Rank3BB);
|
: Rank5BB | Rank4BB | Rank3BB);
|
||||||
const Square* pl = pos.squares<Pt>(Us);
|
Bitboard b1 = pos.pieces(Us, Pt);
|
||||||
|
|
||||||
Bitboard b, bb;
|
Bitboard b, bb;
|
||||||
Score score = SCORE_ZERO;
|
Score score = SCORE_ZERO;
|
||||||
|
|
||||||
attackedBy[Us][Pt] = 0;
|
attackedBy[Us][Pt] = 0;
|
||||||
|
|
||||||
for (Square s = *pl; s != SQ_NONE; s = *++pl)
|
while (b1) {
|
||||||
{
|
Square s = pop_lsb(&b1);
|
||||||
|
|
||||||
// Find attacked squares, including x-ray attacks for bishops and rooks
|
// Find attacked squares, including x-ray attacks for bishops and rooks
|
||||||
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
|
b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
|
||||||
: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
|
: Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
|
||||||
|
|||||||
@@ -180,10 +180,11 @@ namespace {
|
|||||||
|
|
||||||
static_assert(Pt != KING && Pt != PAWN, "Unsupported piece type in generate_moves()");
|
static_assert(Pt != KING && Pt != PAWN, "Unsupported piece type in generate_moves()");
|
||||||
|
|
||||||
const Square* pl = pos.squares<Pt>(Us);
|
Bitboard bb = pos.pieces(Us, Pt);
|
||||||
|
|
||||||
|
while (bb) {
|
||||||
|
Square from = pop_lsb(&bb);
|
||||||
|
|
||||||
for (Square from = *pl; from != SQ_NONE; from = *++pl)
|
|
||||||
{
|
|
||||||
if (Checks)
|
if (Checks)
|
||||||
{
|
{
|
||||||
if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN)
|
if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN)
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace {
|
|||||||
Square s;
|
Square s;
|
||||||
bool backward, passed, doubled;
|
bool backward, passed, doubled;
|
||||||
Score score = SCORE_ZERO;
|
Score score = SCORE_ZERO;
|
||||||
const Square* pl = pos.squares<PAWN>(Us);
|
Bitboard b = pos.pieces(Us, PAWN);
|
||||||
|
|
||||||
Bitboard ourPawns = pos.pieces( Us, PAWN);
|
Bitboard ourPawns = pos.pieces( Us, PAWN);
|
||||||
Bitboard theirPawns = pos.pieces(Them, PAWN);
|
Bitboard theirPawns = pos.pieces(Them, PAWN);
|
||||||
@@ -104,8 +104,9 @@ namespace {
|
|||||||
e->blockedCount += popcount(shift<Up>(ourPawns) & (theirPawns | doubleAttackThem));
|
e->blockedCount += popcount(shift<Up>(ourPawns) & (theirPawns | doubleAttackThem));
|
||||||
|
|
||||||
// Loop through all pawns of the current color and score each pawn
|
// Loop through all pawns of the current color and score each pawn
|
||||||
while ((s = *pl++) != SQ_NONE)
|
while (b) {
|
||||||
{
|
s = pop_lsb(&b);
|
||||||
|
|
||||||
assert(pos.piece_on(s) == make_piece(Us, PAWN));
|
assert(pos.piece_on(s) == make_piece(Us, PAWN));
|
||||||
|
|
||||||
Rank r = relative_rank(Us, s);
|
Rank r = relative_rank(Us, s);
|
||||||
|
|||||||
@@ -197,7 +197,6 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
ss >> std::noskipws;
|
ss >> std::noskipws;
|
||||||
@@ -1327,16 +1326,10 @@ bool Position::pos_is_ok() const {
|
|||||||
assert(0 && "pos_is_ok: State");
|
assert(0 && "pos_is_ok: State");
|
||||||
|
|
||||||
for (Piece pc : Pieces)
|
for (Piece pc : Pieces)
|
||||||
{
|
|
||||||
if ( pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
|
if ( pieceCount[pc] != popcount(pieces(color_of(pc), type_of(pc)))
|
||||||
|| pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
|
|| pieceCount[pc] != std::count(board, board + SQUARE_NB, pc))
|
||||||
assert(0 && "pos_is_ok: Pieces");
|
assert(0 && "pos_is_ok: Pieces");
|
||||||
|
|
||||||
for (int i = 0; i < pieceCount[pc]; ++i)
|
|
||||||
if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
|
|
||||||
assert(0 && "pos_is_ok: Index");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Color c : { WHITE, BLACK })
|
for (Color c : { WHITE, BLACK })
|
||||||
for (CastlingRights cr : {c & KING_SIDE, c & QUEEN_SIDE})
|
for (CastlingRights cr : {c & KING_SIDE, c & QUEEN_SIDE})
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ public:
|
|||||||
bool empty(Square s) const;
|
bool empty(Square s) const;
|
||||||
template<PieceType Pt> int count(Color c) const;
|
template<PieceType Pt> int count(Color c) const;
|
||||||
template<PieceType Pt> int count() const;
|
template<PieceType Pt> int count() const;
|
||||||
template<PieceType Pt> const Square* squares(Color c) const;
|
|
||||||
template<PieceType Pt> Square square(Color c) const;
|
template<PieceType Pt> Square square(Color c) const;
|
||||||
bool is_on_semiopen_file(Color c, Square s) const;
|
bool is_on_semiopen_file(Color c, Square s) const;
|
||||||
|
|
||||||
@@ -190,8 +189,6 @@ private:
|
|||||||
Bitboard byTypeBB[PIECE_TYPE_NB];
|
Bitboard byTypeBB[PIECE_TYPE_NB];
|
||||||
Bitboard byColorBB[COLOR_NB];
|
Bitboard byColorBB[COLOR_NB];
|
||||||
int pieceCount[PIECE_NB];
|
int pieceCount[PIECE_NB];
|
||||||
Square pieceList[PIECE_NB][16];
|
|
||||||
int index[SQUARE_NB];
|
|
||||||
int castlingRightsMask[SQUARE_NB];
|
int castlingRightsMask[SQUARE_NB];
|
||||||
Square castlingRookSquare[CASTLING_RIGHT_NB];
|
Square castlingRookSquare[CASTLING_RIGHT_NB];
|
||||||
Bitboard castlingPath[CASTLING_RIGHT_NB];
|
Bitboard castlingPath[CASTLING_RIGHT_NB];
|
||||||
@@ -254,13 +251,9 @@ template<PieceType Pt> inline int Position::count() const {
|
|||||||
return count<Pt>(WHITE) + count<Pt>(BLACK);
|
return count<Pt>(WHITE) + count<Pt>(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<PieceType Pt> inline const Square* Position::squares(Color c) const {
|
|
||||||
return pieceList[make_piece(c, Pt)];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<PieceType Pt> inline Square Position::square(Color c) const {
|
template<PieceType Pt> inline Square Position::square(Color c) const {
|
||||||
assert(pieceCount[make_piece(c, Pt)] == 1);
|
assert(count<Pt>(c) == 1);
|
||||||
return squares<Pt>(c)[0];
|
return lsb(pieces(c, Pt));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Square Position::ep_square() const {
|
inline Square Position::ep_square() const {
|
||||||
@@ -394,35 +387,25 @@ inline void Position::put_piece(Piece pc, Square s) {
|
|||||||
board[s] = pc;
|
board[s] = pc;
|
||||||
byTypeBB[ALL_PIECES] |= byTypeBB[type_of(pc)] |= s;
|
byTypeBB[ALL_PIECES] |= byTypeBB[type_of(pc)] |= s;
|
||||||
byColorBB[color_of(pc)] |= s;
|
byColorBB[color_of(pc)] |= s;
|
||||||
index[s] = pieceCount[pc]++;
|
pieceCount[pc]++;
|
||||||
pieceList[pc][index[s]] = s;
|
|
||||||
pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
|
pieceCount[make_piece(color_of(pc), ALL_PIECES)]++;
|
||||||
psq += PSQT::psq[pc][s];
|
psq += PSQT::psq[pc][s];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Position::remove_piece(Square s) {
|
inline void Position::remove_piece(Square s) {
|
||||||
|
|
||||||
// WARNING: This is not a reversible operation. If we remove a piece in
|
|
||||||
// do_move() and then replace it in undo_move() we will put it at the end of
|
|
||||||
// the list and not in its original place, it means index[] and pieceList[]
|
|
||||||
// are not invariant to a do_move() + undo_move() sequence.
|
|
||||||
Piece pc = board[s];
|
Piece pc = board[s];
|
||||||
byTypeBB[ALL_PIECES] ^= s;
|
byTypeBB[ALL_PIECES] ^= s;
|
||||||
byTypeBB[type_of(pc)] ^= s;
|
byTypeBB[type_of(pc)] ^= s;
|
||||||
byColorBB[color_of(pc)] ^= s;
|
byColorBB[color_of(pc)] ^= s;
|
||||||
/* board[s] = NO_PIECE; Not needed, overwritten by the capturing one */
|
/* board[s] = NO_PIECE; Not needed, overwritten by the capturing one */
|
||||||
Square lastSquare = pieceList[pc][--pieceCount[pc]];
|
pieceCount[pc]--;
|
||||||
index[lastSquare] = index[s];
|
|
||||||
pieceList[pc][index[lastSquare]] = lastSquare;
|
|
||||||
pieceList[pc][pieceCount[pc]] = SQ_NONE;
|
|
||||||
pieceCount[make_piece(color_of(pc), ALL_PIECES)]--;
|
pieceCount[make_piece(color_of(pc), ALL_PIECES)]--;
|
||||||
psq -= PSQT::psq[pc][s];
|
psq -= PSQT::psq[pc][s];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Position::move_piece(Square from, Square to) {
|
inline void Position::move_piece(Square from, Square to) {
|
||||||
|
|
||||||
// index[from] is not updated and becomes stale. This works as long as index[]
|
|
||||||
// is accessed just by known occupied squares.
|
|
||||||
Piece pc = board[from];
|
Piece pc = board[from];
|
||||||
Bitboard fromTo = from | to;
|
Bitboard fromTo = from | to;
|
||||||
byTypeBB[ALL_PIECES] ^= fromTo;
|
byTypeBB[ALL_PIECES] ^= fromTo;
|
||||||
@@ -430,8 +413,6 @@ inline void Position::move_piece(Square from, Square to) {
|
|||||||
byColorBB[color_of(pc)] ^= fromTo;
|
byColorBB[color_of(pc)] ^= fromTo;
|
||||||
board[from] = NO_PIECE;
|
board[from] = NO_PIECE;
|
||||||
board[to] = pc;
|
board[to] = pc;
|
||||||
index[to] = index[from];
|
|
||||||
pieceList[pc][index[to]] = to;
|
|
||||||
psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
|
psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user