+// unique number for each piece type on each square
+enum PieceSquare : uint32_t {
+ PS_NONE = 0,
+ PS_W_PAWN = 1,
+ PS_B_PAWN = 1 * SQUARE_NB + 1,
+ PS_W_KNIGHT = 2 * SQUARE_NB + 1,
+ PS_B_KNIGHT = 3 * SQUARE_NB + 1,
+ PS_W_BISHOP = 4 * SQUARE_NB + 1,
+ PS_B_BISHOP = 5 * SQUARE_NB + 1,
+ PS_W_ROOK = 6 * SQUARE_NB + 1,
+ PS_B_ROOK = 7 * SQUARE_NB + 1,
+ PS_W_QUEEN = 8 * SQUARE_NB + 1,
+ PS_B_QUEEN = 9 * SQUARE_NB + 1,
+ PS_W_KING = 10 * SQUARE_NB + 1,
+ PS_END = PS_W_KING, // pieces without kings (pawns included)
+ PS_B_KING = 11 * SQUARE_NB + 1,
+ PS_END2 = 12 * SQUARE_NB + 1
+};
+
+struct ExtPieceSquare {
+ PieceSquare from[COLOR_NB];
+};
+
+// Array for finding the PieceSquare corresponding to the piece on the board
+extern ExtPieceSquare kpp_board_index[PIECE_NB];
+
+constexpr bool is_ok(PieceId pid);
+constexpr Square rotate180(Square sq);
+
+// Structure holding which tracked piece (PieceId) is where (PieceSquare)
+class EvalList {
+
+public:
+ // Max. number of pieces without kings is 30 but must be a multiple of 4 in AVX2
+ static const int MAX_LENGTH = 32;
+
+ // Array that holds the piece id for the pieces on the board
+ PieceId piece_id_list[SQUARE_NB];
+
+ // List of pieces, separate from White and Black POV
+ PieceSquare* piece_list_fw() const { return const_cast<PieceSquare*>(pieceListFw); }
+ PieceSquare* piece_list_fb() const { return const_cast<PieceSquare*>(pieceListFb); }
+
+ // Place the piece pc with piece_id on the square sq on the board
+ void put_piece(PieceId piece_id, Square sq, Piece pc)
+ {
+ assert(is_ok(piece_id));
+ if (pc != NO_PIECE)
+ {
+ pieceListFw[piece_id] = PieceSquare(kpp_board_index[pc].from[WHITE] + sq);
+ pieceListFb[piece_id] = PieceSquare(kpp_board_index[pc].from[BLACK] + rotate180(sq));
+ piece_id_list[sq] = piece_id;
+ }
+ else
+ {
+ pieceListFw[piece_id] = PS_NONE;
+ pieceListFb[piece_id] = PS_NONE;
+ piece_id_list[sq] = piece_id;
+ }
+ }
+
+ // Convert the specified piece_id piece to ExtPieceSquare type and return it
+ ExtPieceSquare piece_with_id(PieceId piece_id) const
+ {
+ ExtPieceSquare eps;
+ eps.from[WHITE] = pieceListFw[piece_id];
+ eps.from[BLACK] = pieceListFb[piece_id];
+ return eps;
+ }
+
+private:
+ PieceSquare pieceListFw[MAX_LENGTH];
+ PieceSquare pieceListFb[MAX_LENGTH];
+};
+
+// For differential evaluation of pieces that changed since last turn
+struct DirtyPiece {
+
+ // Number of changed pieces
+ int dirty_num;
+
+ // The ids of changed pieces, max. 2 pieces can change in one move
+ PieceId pieceId[2];