use super::types::BoardArray;
use super::Position;
use crate::board::bitboard_set::BitboardSet;
use crate::board::state_info::StateStack;
use crate::board::zobrist::ZobristKey;
use crate::types::{Color, EnteringKingRule, Hand, Square};

impl Position {
    /// 新しい空の盤面を作成
    #[must_use]
    pub fn empty() -> Self {
        Self {
            board: BoardArray::empty(),
            bitboards: BitboardSet::new(),
            hands: [Hand::ZERO; Color::COUNT],
            zobrist: ZobristKey::default(),
            board_key: ZobristKey::default(),
            hand_key: ZobristKey::default(),
            side_to_move: Color::BLACK,
            entering_king_rule: EnteringKingRule::None,
            entering_king_point: [0, 0],
            ply: 1,
            st_index: 0,
            state_stack: StateStack::new(),
            king_square: [Square::NONE; Color::COUNT],
        }
    }

    /// スタックを初期化する（探索開始時などに使用）
    pub fn init_stack(&mut self) {
        let this = self as *const Self;
        let board_key = self.board_key;
        let hand_key = self.hand_key;
        let turn = self.turn();
        let hand = self.hand(turn);
        let st_index = {
            let stack = self.state_stack_mut();
            stack.reset_sfen();
            let st_index = stack.current_index();
            let state = stack.current_mut();
            state.board_key = board_key;
            state.hand_key = hand_key;
            // SAFETY: `compute_caches_for_state` は `state_stack` を参照せず、盤面キャッシュのみ読む。
            unsafe {
                (&*this).compute_caches_for_state(state);
            }
            state.hand = hand;
            st_index
        };
        self.st_index = st_index;
    }
}
