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:
syzygy1
2020-11-29 12:05:26 +01:00
committed by Joost VandeVondele
parent 2bc4ae172a
commit 045728a7da
6 changed files with 20 additions and 44 deletions

View File

@@ -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))

View File

@@ -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))

View File

@@ -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)

View File

@@ -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);

View File

@@ -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})
{ {

View File

@@ -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];
} }