timecat 1.52.0

A NNUE-based chess engine that implements the Negamax algorithm and can be integrated into any project as a library. It features move generation, advanced position evaluation through NNUE, and move searching capabilities.
Documentation
use super::*;

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
pub enum Rank {
    First = 0,
    Second = 1,
    Third = 2,
    Fourth = 3,
    Fifth = 4,
    Sixth = 5,
    Seventh = 6,
    Eighth = 7,
}

impl Rank {
    #[inline]
    pub const unsafe fn from_int(i: u8) -> Self {
        std::mem::transmute(i)
    }

    #[inline]
    pub const unsafe fn from_index(i: usize) -> Self {
        Self::from_int(i as u8)
    }

    #[inline]
    pub fn up(self) -> Option<Self> {
        (self != Self::Eighth).then(|| unsafe { Self::from_int(self.to_int() + 1) })
    }

    #[inline]
    pub fn down(self) -> Option<Self> {
        (self != Self::First).then(|| unsafe { Self::from_int(self.to_int() - 1) })
    }

    #[inline]
    pub fn wrapping_up(self) -> Self {
        self.up().unwrap_or(Self::First)
    }

    #[inline]
    pub fn wrapping_down(self) -> Self {
        self.down().unwrap_or(Self::Eighth)
    }

    #[inline]
    pub const fn to_int(self) -> u8 {
        self as u8
    }

    #[inline]
    pub const fn to_index(self) -> usize {
        self as usize
    }

    #[inline]
    pub const fn to_bitboard(self) -> BitBoard {
        BitBoard::new(0xff << (self.to_int() << 3))
    }

    #[inline]
    pub fn get_upper_board_mask(self, color: Color) -> BitBoard {
        *get_item_unchecked!(UPPER_BOARD_MASK, color.to_index(), self.to_index())
    }

    #[inline]
    pub fn get_lower_board_mask(self, color: Color) -> BitBoard {
        self.get_upper_board_mask(!color)
    }
}

impl fmt::Display for Rank {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.to_int() + 1)
    }
}

impl TryFrom<char> for Rank {
    type Error = TimecatError;

    #[inline]
    fn try_from(c: char) -> Result<Self> {
        match c {
            '1' => Ok(Self::First),
            '2' => Ok(Self::Second),
            '3' => Ok(Self::Third),
            '4' => Ok(Self::Fourth),
            '5' => Ok(Self::Fifth),
            '6' => Ok(Self::Sixth),
            '7' => Ok(Self::Seventh),
            '8' => Ok(Self::Eighth),
            _ => Err(TimecatError::InvalidRankString {
                s: c.to_string().into(),
            }),
        }
    }
}

impl FromStr for Rank {
    type Err = TimecatError;

    #[inline]
    fn from_str(s: &str) -> Result<Self> {
        match s.trim() {
            "1" => Ok(Self::First),
            "2" => Ok(Self::Second),
            "3" => Ok(Self::Third),
            "4" => Ok(Self::Fourth),
            "5" => Ok(Self::Fifth),
            "6" => Ok(Self::Sixth),
            "7" => Ok(Self::Seventh),
            "8" => Ok(Self::Eighth),
            _ => Err(TimecatError::InvalidRankString {
                s: s.to_string().into(),
            }),
        }
    }
}