Init threat offsets at compile time

Init threat offsets at compile time. Avoid another global init function call.

Passed STC Non-Regression:
https://tests.stockfishchess.org/tests/view/694971a83c8768ca4507275c
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 43296 W: 11284 L: 11077 D: 20935
Ptnml(0-2): 152, 4611, 11924, 4800, 161

closes https://github.com/official-stockfish/Stockfish/pull/6487

No functional change
This commit is contained in:
Disservin
2025-12-23 21:42:45 +01:00
parent 4d4c6ebd02
commit 73b3b18595
6 changed files with 293 additions and 173 deletions
+2 -46
View File
@@ -32,7 +32,6 @@ uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
Bitboard LineBB[SQUARE_NB][SQUARE_NB]; Bitboard LineBB[SQUARE_NB][SQUARE_NB];
Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; Bitboard RayPassBB[SQUARE_NB][SQUARE_NB];
Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
alignas(64) Magic Magics[SQUARE_NB][2]; alignas(64) Magic Magics[SQUARE_NB][2];
@@ -42,13 +41,6 @@ Bitboard RookTable[0x19000]; // To store rook attacks
Bitboard BishopTable[0x1480]; // To store bishop attacks Bitboard BishopTable[0x1480]; // To store bishop attacks
void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]); void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]);
// Returns the bitboard of target square for the given step
// from the given square. If the step is off the board, returns empty bitboard.
Bitboard safe_destination(Square s, int step) {
Square to = Square(s + step);
return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
}
} }
// Returns an ASCII representation of a bitboard suitable // Returns an ASCII representation of a bitboard suitable
@@ -86,18 +78,6 @@ void Bitboards::init() {
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1) for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
{ {
PseudoAttacks[WHITE][s1] = pawn_attacks_bb<WHITE>(square_bb(s1));
PseudoAttacks[BLACK][s1] = pawn_attacks_bb<BLACK>(square_bb(s1));
for (int step : {-9, -8, -7, -1, 1, 7, 8, 9})
PseudoAttacks[KING][s1] |= safe_destination(s1, step);
for (int step : {-17, -15, -10, -6, 6, 10, 15, 17})
PseudoAttacks[KNIGHT][s1] |= safe_destination(s1, step);
PseudoAttacks[QUEEN][s1] = PseudoAttacks[BISHOP][s1] = attacks_bb<BISHOP>(s1, 0);
PseudoAttacks[QUEEN][s1] |= PseudoAttacks[ROOK][s1] = attacks_bb<ROOK>(s1, 0);
for (PieceType pt : {BISHOP, ROOK}) for (PieceType pt : {BISHOP, ROOK})
for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2) for (Square s2 = SQ_A1; s2 <= SQ_H8; ++s2)
{ {
@@ -115,30 +95,6 @@ void Bitboards::init() {
} }
namespace { namespace {
Bitboard sliding_attack(PieceType pt, Square sq, Bitboard occupied) {
Bitboard attacks = 0;
Direction RookDirections[4] = {NORTH, SOUTH, EAST, WEST};
Direction BishopDirections[4] = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
for (Direction d : (pt == ROOK ? RookDirections : BishopDirections))
{
Square s = sq;
while (safe_destination(s, d))
{
attacks |= (s += d);
if (occupied & s)
{
break;
}
}
}
return attacks;
}
// Computes all rook and bishop attacks at startup. Magic // Computes all rook and bishop attacks at startup. Magic
// bitboards are used to look up attacks of sliding pieces. As a reference see // bitboards are used to look up attacks of sliding pieces. As a reference see
// https://www.chessprogramming.org/Magic_Bitboards. In particular, here we use // https://www.chessprogramming.org/Magic_Bitboards. In particular, here we use
@@ -167,7 +123,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) {
// the number of 1s of the mask. Hence we deduce the size of the shift to // the number of 1s of the mask. Hence we deduce the size of the shift to
// apply to the 64 or 32 bits word to get the index. // apply to the 64 or 32 bits word to get the index.
Magic& m = magics[s][pt - BISHOP]; Magic& m = magics[s][pt - BISHOP];
m.mask = sliding_attack(pt, s, 0) & ~edges; m.mask = Bitboards::sliding_attack(pt, s, 0) & ~edges;
#ifndef USE_PEXT #ifndef USE_PEXT
m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask); m.shift = (Is64Bit ? 64 : 32) - popcount(m.mask);
#endif #endif
@@ -184,7 +140,7 @@ void init_magics(PieceType pt, Bitboard table[], Magic magics[][2]) {
#ifndef USE_PEXT #ifndef USE_PEXT
occupancy[size] = b; occupancy[size] = b;
#endif #endif
reference[size] = sliding_attack(pt, s, b); reference[size] = Bitboards::sliding_attack(pt, s, b);
if (HasPext) if (HasPext)
m.attacks[pext(b, m.mask)] = reference[size]; m.attacks[pext(b, m.mask)] = reference[size];
+154 -64
View File
@@ -26,6 +26,8 @@
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
#include <initializer_list>
#include <array>
#include "types.h" #include "types.h"
@@ -62,8 +64,6 @@ extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB];
extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
extern Bitboard RayPassBB[SQUARE_NB][SQUARE_NB]; extern Bitboard RayPassBB[SQUARE_NB][SQUARE_NB];
extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB];
// Magic holds all magic bitboards relevant data for a single square // Magic holds all magic bitboards relevant data for a single square
struct Magic { struct Magic {
@@ -203,69 +203,12 @@ inline int distance<Square>(Square x, Square y) {
inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); } inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
// Returns the pseudo attacks of the given piece type
// assuming an empty board.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) {
assert((Pt != PAWN || c < COLOR_NB) && (is_ok(s))); constexpr int constexpr_popcount(Bitboard b) {
return Pt == PAWN ? PseudoAttacks[c][s] : PseudoAttacks[Pt][s]; b = b - ((b >> 1) & 0x5555555555555555ULL);
} b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
return static_cast<int>((b * 0x0101010101010101ULL) >> 56);
// Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard.
// Sliding piece attacks do not continue passed an occupied square.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occupied) {
assert((Pt != PAWN) && (is_ok(s)));
switch (Pt)
{
case BISHOP :
case ROOK :
return Magics[s][Pt - BISHOP].attacks_bb(occupied);
case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
default :
return PseudoAttacks[Pt][s];
}
}
// Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard.
// Sliding piece attacks do not continue passed an occupied square.
inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
assert((pt != PAWN) && (is_ok(s)));
switch (pt)
{
case BISHOP :
return attacks_bb<BISHOP>(s, occupied);
case ROOK :
return attacks_bb<ROOK>(s, occupied);
case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
default :
return PseudoAttacks[pt][s];
}
}
inline Bitboard attacks_bb(Piece pc, Square s) {
if (type_of(pc) == PAWN)
return PseudoAttacks[color_of(pc)][s];
return PseudoAttacks[type_of(pc)][s];
}
inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) {
if (type_of(pc) == PAWN)
return PseudoAttacks[color_of(pc)][s];
return attacks_bb(type_of(pc), s, occupied);
} }
// Counts the number of non-zero bits in a bitboard. // Counts the number of non-zero bits in a bitboard.
@@ -373,6 +316,153 @@ inline Square pop_lsb(Bitboard& b) {
return s; return s;
} }
namespace Bitboards {
// Returns the bitboard of target square for the given step
// from the given square. If the step is off the board, returns empty bitboard.
constexpr Bitboard safe_destination(Square s, int step) {
constexpr auto abs = [](int v) { return v < 0 ? -v : v; };
Square to = Square(s + step);
return is_ok(to) && abs(file_of(s) - file_of(to)) <= 2 ? square_bb(to) : Bitboard(0);
}
constexpr Bitboard sliding_attack(PieceType pt, Square sq, Bitboard occupied) {
Bitboard attacks = 0;
Direction RookDirections[4] = {NORTH, SOUTH, EAST, WEST};
Direction BishopDirections[4] = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
for (Direction d : (pt == ROOK ? RookDirections : BishopDirections))
{
Square s = sq;
while (safe_destination(s, d))
{
attacks |= (s += d);
if (occupied & s)
{
break;
}
}
}
return attacks;
}
constexpr Bitboard knight_attack(Square sq) {
Bitboard b = {};
for (int step : {-17, -15, -10, -6, 6, 10, 15, 17})
b |= safe_destination(sq, step);
return b;
}
constexpr Bitboard king_attack(Square sq) {
Bitboard b = {};
for (int step : {-9, -8, -7, -1, 1, 7, 8, 9})
b |= safe_destination(sq, step);
return b;
}
constexpr Bitboard pseudo_attacks(PieceType pt, Square sq) {
switch (pt)
{
case PieceType::ROOK :
case PieceType::BISHOP :
return sliding_attack(pt, sq, 0);
case PieceType::QUEEN :
return sliding_attack(PieceType::ROOK, sq, 0) | sliding_attack(PieceType::BISHOP, sq, 0);
case PieceType::KNIGHT :
return knight_attack(sq);
case PieceType::KING :
return king_attack(sq);
default :
assert(false);
return 0;
}
}
}
inline constexpr auto PseudoAttacks = []() constexpr {
std::array<std::array<Bitboard, SQUARE_NB>, PIECE_TYPE_NB> attacks{};
for (Square s1 = SQ_A1; s1 <= SQ_H8; ++s1)
{
attacks[WHITE][s1] = pawn_attacks_bb<WHITE>(square_bb(s1));
attacks[BLACK][s1] = pawn_attacks_bb<BLACK>(square_bb(s1));
attacks[KING][s1] = Bitboards::pseudo_attacks(KING, s1);
attacks[KNIGHT][s1] = Bitboards::pseudo_attacks(KNIGHT, s1);
attacks[QUEEN][s1] = attacks[BISHOP][s1] = Bitboards::pseudo_attacks(BISHOP, s1);
attacks[QUEEN][s1] |= attacks[ROOK][s1] = Bitboards::pseudo_attacks(ROOK, s1);
}
return attacks;
}();
// Returns the pseudo attacks of the given piece type
// assuming an empty board.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Color c = COLOR_NB) {
assert((Pt != PAWN || c < COLOR_NB) && (is_ok(s)));
return Pt == PAWN ? PseudoAttacks[c][s] : PseudoAttacks[Pt][s];
}
// Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard.
// Sliding piece attacks do not continue passed an occupied square.
template<PieceType Pt>
inline Bitboard attacks_bb(Square s, Bitboard occupied) {
assert((Pt != PAWN) && (is_ok(s)));
switch (Pt)
{
case BISHOP :
case ROOK :
return Magics[s][Pt - BISHOP].attacks_bb(occupied);
case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
default :
return PseudoAttacks[Pt][s];
}
}
// Returns the attacks by the given piece
// assuming the board is occupied according to the passed Bitboard.
// Sliding piece attacks do not continue passed an occupied square.
inline Bitboard attacks_bb(PieceType pt, Square s, Bitboard occupied) {
assert((pt != PAWN) && (is_ok(s)));
switch (pt)
{
case BISHOP :
return attacks_bb<BISHOP>(s, occupied);
case ROOK :
return attacks_bb<ROOK>(s, occupied);
case QUEEN :
return attacks_bb<BISHOP>(s, occupied) | attacks_bb<ROOK>(s, occupied);
default :
return PseudoAttacks[pt][s];
}
}
inline Bitboard attacks_bb(Piece pc, Square s) {
if (type_of(pc) == PAWN)
return PseudoAttacks[color_of(pc)][s];
return PseudoAttacks[type_of(pc)][s];
}
inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) {
if (type_of(pc) == PAWN)
return PseudoAttacks[color_of(pc)][s];
return attacks_bb(type_of(pc), s, occupied);
}
} // namespace Stockfish } // namespace Stockfish
#endif // #ifndef BITBOARD_H_INCLUDED #endif // #ifndef BITBOARD_H_INCLUDED
-2
View File
@@ -21,7 +21,6 @@
#include "bitboard.h" #include "bitboard.h"
#include "misc.h" #include "misc.h"
#include "nnue/features/full_threats.h"
#include "position.h" #include "position.h"
#include "tune.h" #include "tune.h"
#include "uci.h" #include "uci.h"
@@ -33,7 +32,6 @@ int main(int argc, char* argv[]) {
Bitboards::init(); Bitboards::init();
Position::init(); Position::init();
Eval::NNUE::Features::init_threat_offsets();
auto uci = std::make_unique<UCIEngine>(argc, argv); auto uci = std::make_unique<UCIEngine>(argc, argv);
+136 -60
View File
@@ -21,7 +21,9 @@
#include "full_threats.h" #include "full_threats.h"
#include <array> #include <array>
#include <cstdint>
#include <initializer_list> #include <initializer_list>
#include <utility>
#include "../../bitboard.h" #include "../../bitboard.h"
#include "../../misc.h" #include "../../misc.h"
@@ -31,26 +33,28 @@
namespace Stockfish::Eval::NNUE::Features { namespace Stockfish::Eval::NNUE::Features {
// Lookup array for indexing threats
IndexType offsets[PIECE_NB][SQUARE_NB];
struct HelperOffsets { struct HelperOffsets {
int cumulativePieceOffset, cumulativeOffset; int cumulativePieceOffset, cumulativeOffset;
}; };
std::array<HelperOffsets, PIECE_NB> helper_offsets;
// Information on a particular pair of pieces and whether they should be excluded // Information on a particular pair of pieces and whether they should be excluded
struct PiecePairData { struct PiecePairData {
// Layout: bits 8..31 are the index contribution of this piece pair, bits 0 and 1 are exclusion info // Layout: bits 8..31 are the index contribution of this piece pair, bits 0 and 1 are exclusion info
uint32_t data; uint32_t data;
PiecePairData() {}
PiecePairData(bool excluded_pair, bool semi_excluded_pair, IndexType feature_index_base) { constexpr PiecePairData() :
data = data(0) {}
excluded_pair << 1 | (semi_excluded_pair && !excluded_pair) | feature_index_base << 8;
} constexpr PiecePairData(bool excluded_pair,
bool semi_excluded_pair,
IndexType feature_index_base) :
data((uint32_t(excluded_pair) << 1) | (uint32_t(semi_excluded_pair && !excluded_pair))
| (uint32_t(feature_index_base) << 8)) {}
// lsb: excluded if from < to; 2nd lsb: always excluded // lsb: excluded if from < to; 2nd lsb: always excluded
uint8_t excluded_pair_info() const { return (uint8_t) data; } constexpr uint8_t excluded_pair_info() const { return static_cast<uint8_t>(data); }
IndexType feature_index_base() const { return data >> 8; }
constexpr IndexType feature_index_base() const { return static_cast<IndexType>(data >> 8); }
}; };
constexpr std::array<Piece, 12> AllPieces = { constexpr std::array<Piece, 12> AllPieces = {
@@ -58,12 +62,119 @@ constexpr std::array<Piece, 12> AllPieces = {
B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING, B_PAWN, B_KNIGHT, B_BISHOP, B_ROOK, B_QUEEN, B_KING,
}; };
// The final index is calculated from summing data found in these two LUTs, as well template<PieceType PT>
// as offsets[attacker][from] constexpr auto make_piece_indices_type() {
PiecePairData index_lut1[PIECE_NB][PIECE_NB]; // [attacker][attacked] static_assert(PT != PieceType::PAWN);
uint8_t index_lut2[PIECE_NB][SQUARE_NB][SQUARE_NB]; // [attacker][from][to]
std::array<std::array<uint8_t, SQUARE_NB>, SQUARE_NB> out{};
for (int from = 0; from < SQUARE_NB; ++from)
{
Bitboard attacks = PseudoAttacks[PT][Square(from)];
for (int to = 0; to < SQUARE_NB; ++to)
{
out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks);
}
}
return out;
}
template<Piece P>
constexpr auto make_piece_indices_piece() {
static_assert(type_of(P) == PieceType::PAWN);
std::array<std::array<uint8_t, SQUARE_NB>, SQUARE_NB> out{};
constexpr Color C = color_of(P);
for (int from = 0; from < SQUARE_NB; ++from)
{
Bitboard attacks = PseudoAttacks[C][from];
for (int to = 0; to < SQUARE_NB; ++to)
{
out[from][to] = constexpr_popcount(((1ULL << to) - 1) & attacks);
}
}
return out;
}
constexpr auto index_lut2_array() {
constexpr auto KNIGHT_ATTACKS = make_piece_indices_type<PieceType::KNIGHT>();
constexpr auto BISHOP_ATTACKS = make_piece_indices_type<PieceType::BISHOP>();
constexpr auto ROOK_ATTACKS = make_piece_indices_type<PieceType::ROOK>();
constexpr auto QUEEN_ATTACKS = make_piece_indices_type<PieceType::QUEEN>();
constexpr auto KING_ATTACKS = make_piece_indices_type<PieceType::KING>();
std::array<std::array<std::array<uint8_t, SQUARE_NB>, SQUARE_NB>, PIECE_NB> indices{};
indices[W_PAWN] = make_piece_indices_piece<W_PAWN>();
indices[B_PAWN] = make_piece_indices_piece<B_PAWN>();
indices[W_KNIGHT] = KNIGHT_ATTACKS;
indices[B_KNIGHT] = KNIGHT_ATTACKS;
indices[W_BISHOP] = BISHOP_ATTACKS;
indices[B_BISHOP] = BISHOP_ATTACKS;
indices[W_ROOK] = ROOK_ATTACKS;
indices[B_ROOK] = ROOK_ATTACKS;
indices[W_QUEEN] = QUEEN_ATTACKS;
indices[B_QUEEN] = QUEEN_ATTACKS;
indices[W_KING] = KING_ATTACKS;
indices[B_KING] = KING_ATTACKS;
return indices;
}
constexpr auto init_threat_offsets() {
std::array<HelperOffsets, PIECE_NB> indices{};
std::array<std::array<IndexType, SQUARE_NB>, PIECE_NB> offsets{};
int cumulativeOffset = 0;
for (Piece piece : AllPieces)
{
int pieceIdx = piece;
int cumulativePieceOffset = 0;
for (Square from = SQ_A1; from <= SQ_H8; ++from)
{
offsets[pieceIdx][from] = cumulativePieceOffset;
if (type_of(piece) != PAWN)
{
Bitboard attacks = PseudoAttacks[type_of(piece)][from];
cumulativePieceOffset += constexpr_popcount(attacks);
}
else if (from >= SQ_A2 && from <= SQ_H7)
{
Bitboard attacks = (pieceIdx < 8) ? pawn_attacks_bb<WHITE>(square_bb(from))
: pawn_attacks_bb<BLACK>(square_bb(from));
cumulativePieceOffset += constexpr_popcount(attacks);
}
}
indices[pieceIdx] = {cumulativePieceOffset, cumulativeOffset};
cumulativeOffset += numValidTargets[pieceIdx] * cumulativePieceOffset;
}
return std::pair{indices, offsets};
}
constexpr auto helper_offsets = init_threat_offsets().first;
// Lookup array for indexing threats
constexpr auto offsets = init_threat_offsets().second;
constexpr auto init_index_luts() {
std::array<std::array<PiecePairData, PIECE_NB>, PIECE_NB> indices{};
static void init_index_luts() {
for (Piece attacker : AllPieces) for (Piece attacker : AllPieces)
{ {
for (Piece attacked : AllPieces) for (Piece attacked : AllPieces)
@@ -78,56 +189,21 @@ static void init_index_luts() {
+ (color_of(attacked) * (numValidTargets[attacker] / 2) + map) + (color_of(attacked) * (numValidTargets[attacker] / 2) + map)
* helper_offsets[attacker].cumulativePieceOffset; * helper_offsets[attacker].cumulativePieceOffset;
bool excluded = map < 0; bool excluded = map < 0;
index_lut1[attacker][attacked] = PiecePairData(excluded, semi_excluded, feature); indices[attacker][attacked] = PiecePairData(excluded, semi_excluded, feature);
} }
} }
for (Piece attacker : AllPieces) return indices;
{
for (int from = 0; from < SQUARE_NB; ++from)
{
for (int to = 0; to < SQUARE_NB; ++to)
{
Bitboard attacks = attacks_bb(attacker, Square(from));
index_lut2[attacker][from][to] = popcount((square_bb(Square(to)) - 1) & attacks);
}
}
}
} }
void init_threat_offsets() { // The final index is calculated from summing data found in these two LUTs, as well
int cumulativeOffset = 0; // as offsets[attacker][from]
for (Piece piece : AllPieces)
{
int pieceIdx = piece;
int cumulativePieceOffset = 0;
for (Square from = SQ_A1; from <= SQ_H8; ++from) // [attacker][attacked]
{ constexpr auto index_lut1 = init_index_luts();
offsets[pieceIdx][from] = cumulativePieceOffset; // [attacker][from][to]
constexpr auto index_lut2 = index_lut2_array();
if (type_of(piece) != PAWN)
{
Bitboard attacks = attacks_bb(piece, from, 0ULL);
cumulativePieceOffset += popcount(attacks);
}
else if (from >= SQ_A2 && from <= SQ_H7)
{
Bitboard attacks = (pieceIdx < 8) ? pawn_attacks_bb<WHITE>(square_bb(from))
: pawn_attacks_bb<BLACK>(square_bb(from));
cumulativePieceOffset += popcount(attacks);
}
}
helper_offsets[pieceIdx] = {cumulativePieceOffset, cumulativeOffset};
cumulativeOffset += numValidTargets[pieceIdx] * cumulativePieceOffset;
}
init_index_luts();
}
// Index of a feature for a given king position and another piece on some square // Index of a feature for a given king position and another piece on some square
inline sf_always_inline IndexType FullThreats::make_index( inline sf_always_inline IndexType FullThreats::make_index(
-1
View File
@@ -32,7 +32,6 @@ namespace Stockfish::Eval::NNUE::Features {
static constexpr int numValidTargets[PIECE_NB] = {0, 6, 12, 10, 10, 12, 8, 0, static constexpr int numValidTargets[PIECE_NB] = {0, 6, 12, 10, 10, 12, 8, 0,
0, 6, 12, 10, 10, 12, 8, 0}; 0, 6, 12, 10, 10, 12, 8, 0};
void init_threat_offsets();
class FullThreats { class FullThreats {
public: public:
+1
View File
@@ -35,6 +35,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <array>
#include "../bitboard.h" #include "../bitboard.h"
#include "../misc.h" #include "../misc.h"