chessframe 0.4.2

A Rust library for working with chess positions, generating psudo-legal moves, and interacting with the UCI protocol.
Documentation
use crate::{
    bitboard::BitBoard, castling_rights::CastlingRights, color::Color, file::File, piece::Piece,
    rank::Rank, square::Square,
};

include!(concat!(env!("OUT_DIR"), "/tables.rs"));
include!(concat!(env!("OUT_DIR"), "/magic_tables.rs"));

#[derive(Debug, Clone, Copy, Default)]
pub struct Magic {
    pub mask: BitBoard,
    pub magic: u64,
    pub shift: u8,
    pub offset: u32,
}

#[inline]
pub fn magic_index(magic: Magic, blockers: BitBoard) -> usize {
    let blockers = blockers & magic.mask;
    let hash = blockers.0.wrapping_mul(magic.magic);
    let index = (hash >> magic.shift) as usize;
    magic.offset as usize + index
}

#[inline]
pub fn get_pawn_moves(square: Square, color: Color) -> BitBoard {
    unsafe {
        *PAWN_MOVES
            .get_unchecked(color.to_index())
            .get_unchecked(square.to_index())
    }
}

#[inline]
pub fn get_pawn_attacks(square: Square, color: Color) -> BitBoard {
    unsafe {
        *PAWN_ATTACKS
            .get_unchecked(color.to_index())
            .get_unchecked(square.to_index())
    }
}

#[inline]
pub fn get_knight_moves(square: Square) -> BitBoard {
    unsafe { *KNIGHT_MOVES.get_unchecked(square.to_index()) }
}

#[inline]
pub fn get_bishop_moves(square: Square, blockers: BitBoard) -> BitBoard {
    unsafe {
        let magic = BISHOP_MAGICS.get_unchecked(square.to_index());
        let moves = BISHOP_MOVES_TABLE.get_unchecked(magic_index(*magic, blockers));
        *moves
    }
}

#[inline]
pub fn get_rook_moves(square: Square, blockers: BitBoard) -> BitBoard {
    unsafe {
        let magic = ROOK_MAGICS.get_unchecked(square.to_index());
        let moves = ROOK_MOVES_TABLE.get_unchecked(magic_index(*magic, blockers));
        *moves
    }
}

#[inline]
pub fn get_king_moves(square: Square) -> BitBoard {
    unsafe { *KING_MOVES.get_unchecked(square.to_index()) }
}

#[inline]
pub fn get_castle_moves() -> BitBoard {
    CASTLE_MOVES
}

#[inline]
pub fn get_file(file: File) -> BitBoard {
    unsafe { *FILES.get_unchecked(file.to_index()) }
}

#[inline]
pub fn get_adjacent_files(file: File) -> BitBoard {
    unsafe { *ADJACENT_FILES.get_unchecked(file.to_index()) }
}

#[inline]
pub fn get_rank(rank: Rank) -> BitBoard {
    unsafe { *RANKS.get_unchecked(rank.to_index()) }
}

#[inline]
pub fn get_between(start: Square, end: Square) -> BitBoard {
    unsafe {
        *BETWEEN
            .get_unchecked(start.to_index())
            .get_unchecked(end.to_index())
    }
}

#[inline]
pub fn get_tangent(start: Square, end: Square) -> BitBoard {
    unsafe {
        *TANGENT
            .get_unchecked(start.to_index())
            .get_unchecked(end.to_index())
    }
}

pub struct Zobrist;

impl Zobrist {
    #[inline]
    pub fn get_side_to_move() -> u64 {
        ZOBRIST_SIDE_TO_MOVE
    }

    #[inline]
    pub fn get_piece(piece: Piece, square: Square, color: Color) -> u64 {
        unsafe {
            *ZOBRIST_PIECES
                .get_unchecked(color.to_index())
                .get_unchecked(piece.to_index())
                .get_unchecked(square.to_index())
        }
    }

    #[inline]
    pub fn get_castle(castling_rights: CastlingRights, color: Color) -> u64 {
        unsafe {
            *ZOBRIST_CASTLE
                .get_unchecked(color.to_index())
                .get_unchecked(castling_rights.color(color).to_index() >> (2 * color.to_index()))
        }
    }

    #[inline]
    pub fn get_en_passant(file: File, color: Color) -> u64 {
        unsafe {
            *ZOBRIST_ENPASSANT
                .get_unchecked(color.to_index())
                .get_unchecked(file.to_index())
        }
    }
}