use super::Feature;
use super::TriggerEvent;
use crate::nnue::accumulator::{DirtyPiece, IndexList, MAX_ACTIVE_FEATURES, MAX_CHANGED_FEATURES};
use crate::nnue::bona_piece::BonaPiece;
use crate::nnue::bona_piece_halfka::{halfka_index, king_index};
use crate::nnue::constants::HALFKA_DIMENSIONS;
use crate::nnue::piece_list::PieceNumber;
use crate::position::Position;
use crate::types::{Color, Square};
pub struct HalfKA;
impl Feature for HalfKA {
const DIMENSIONS: usize = HALFKA_DIMENSIONS;
const MAX_ACTIVE: usize = 40;
const REFRESH_TRIGGER: TriggerEvent = TriggerEvent::FriendKingMoved;
#[inline]
fn append_active_indices(
pos: &Position,
perspective: Color,
active: &mut IndexList<MAX_ACTIVE_FEATURES>,
) {
let king_sq = pos.king_square(perspective);
let k_index = king_index(king_sq, perspective);
let pieces = if perspective == Color::Black {
pos.piece_list().piece_list_fb()
} else {
pos.piece_list().piece_list_fw()
};
for bp in &pieces[..PieceNumber::NB] {
if *bp != BonaPiece::ZERO {
let _ = active.push(halfka_index(k_index, bp.value() as usize));
}
}
}
#[inline]
fn append_changed_indices(
dirty_piece: &DirtyPiece,
perspective: Color,
king_sq: Square,
removed: &mut IndexList<MAX_CHANGED_FEATURES>,
added: &mut IndexList<MAX_CHANGED_FEATURES>,
) {
let k_index = king_index(king_sq, perspective);
for i in 0..dirty_piece.dirty_num as usize {
let cp = &dirty_piece.changed_piece[i];
let old_bp = if perspective == Color::Black {
cp.old_piece.fb
} else {
cp.old_piece.fw
};
let new_bp = if perspective == Color::Black {
cp.new_piece.fb
} else {
cp.new_piece.fw
};
if old_bp != BonaPiece::ZERO {
let _ = removed.push(halfka_index(k_index, old_bp.value() as usize));
}
if new_bp != BonaPiece::ZERO {
let _ = added.push(halfka_index(k_index, new_bp.value() as usize));
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_halfka_dimensions() {
assert_eq!(HalfKA::DIMENSIONS, 138_510);
}
#[test]
fn test_halfka_max_active() {
assert_eq!(HalfKA::MAX_ACTIVE, 40);
}
#[test]
fn test_halfka_refresh_trigger() {
assert_eq!(HalfKA::REFRESH_TRIGGER, TriggerEvent::FriendKingMoved);
}
}