return IndexType(orient(perspective, s, pos) + pos.variant()->pieceSquareIndex[perspective][pc] + ksq * pos.variant()->nnuePieceIndices);
}
+ // Index of a feature for a given king position and another piece on some square
+ inline IndexType HalfKAv2Variants::make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos) {
+ return IndexType(handCount + pos.variant()->pieceHandIndex[perspective][pc] + ksq * pos.variant()->nnuePieceIndices);
+ }
+
// Get a list of indices for active features
void HalfKAv2Variants::append_active_indices(
const Position& pos,
Square s = pop_lsb(bb);
active.push_back(make_index(perspective, s, pos.piece_on(s), oriented_ksq, pos));
}
+
+ // Indices for pieces in hand
+ if (pos.piece_drops() || pos.seirawan_gating())
+ for (Color c : {WHITE, BLACK})
+ for (PieceType pt : pos.piece_types())
+ for (int i = 0; i < pos.count_in_hand(c, pt); i++)
+ active.push_back(make_index(perspective, i, make_piece(c, pt), oriented_ksq, pos));
+
}
// append_changed_indices() : get a list of indices for recently changed features
Piece pc = dp.piece[i];
if (dp.from[i] != SQ_NONE)
removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq, pos));
+ else if (pos.piece_drops() && dp.dirty_num == 1)
+ removed.push_back(make_index(perspective, dp.handCount[i], dp.handPiece[i], oriented_ksq, pos));
if (dp.to[i] != SQ_NONE)
added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq, pos));
+ else if (pos.captures_to_hand() && i == 1)
+ added.push_back(make_index(perspective, dp.handCount[i] - 1, dp.handPiece[i], oriented_ksq, pos));
}
}
// Index of a feature for a given king position and another piece on some square
static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos);
+ // Index of a feature for a given king position and another piece in hand
+ static IndexType make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos);
+
public:
// Feature name
static constexpr const char* Name = "HalfKAv2(Friend)";
int nnueSquares;
int nnuePieceIndices;
int pieceSquareIndex[COLOR_NB][PIECE_NB];
+ int pieceHandIndex[COLOR_NB][PIECE_NB];
int nnueMaxPieces;
bool endgameEval = false;
: extinctionPieceTypes.find(COMMONER) != extinctionPieceTypes.end() ? COMMONER
: NO_PIECE_TYPE;
nnueSquares = (maxRank + 1) * (maxFile + 1);
- nnuePieceIndices = (2 * pieceTypes.size() - 1) * nnueSquares;
+ int nnuePockets = pieceDrops ? 2 * int(maxFile + 1) : 0;
+ int nnueNonDropPieceIndices = (2 * pieceTypes.size() - 1) * nnueSquares;
+ nnuePieceIndices = nnueNonDropPieceIndices + 2 * (pieceTypes.size() - 1) * nnuePockets;
int i = 0;
for (PieceType pt : pieceTypes)
{
{
pieceSquareIndex[c][make_piece(c, pt)] = 2 * i * nnueSquares;
pieceSquareIndex[c][make_piece(~c, pt)] = (2 * i + (pt != nnueKing)) * nnueSquares;
+ pieceHandIndex[c][make_piece(c, pt)] = 2 * i * nnuePockets + nnueNonDropPieceIndices;
+ pieceHandIndex[c][make_piece(~c, pt)] = (2 * i + 1) * nnuePockets + nnueNonDropPieceIndices;
}
i++;
}