use std::ops::{Sub, Add}; use std::cmp::Ordering; #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] pub enum Square { A1 = 0, B1 = 1, C1 = 2, D1 = 3, E1 = 4, F1 = 5, G1 = 6, H1 = 7, A2 = 8, B2 = 9, C2 = 10, D2 = 11, E2 = 12, F2 = 13, G2 = 14, H2 = 15, A3 = 16, B3 = 17, C3 = 18, D3 = 19, E3 = 20, F3 = 21, G3 = 22, H3 = 23, A4 = 24, B4 = 25, C4 = 26, D4 = 27, E4 = 28, F4 = 29, G4 = 30, H4 = 31, A5 = 32, B5 = 33, C5 = 34, D5 = 35, E5 = 36, F5 = 37, G5 = 38, H5 = 39, A6 = 40, B6 = 41, C6 = 42, D6 = 43, E6 = 44, F6 = 45, G6 = 46, H6 = 47, A7 = 48, B7 = 49, C7 = 50, D7 = 51, E7 = 52, F7 = 53, G7 = 54, H7 = 55, A8 = 56, B8 = 57, C8 = 58, D8 = 59, E8 = 60, F8 = 61, G8 = 62, H8 = 63, } pub const SQUARES: [Square; 64] = [ Square::A1, Square::B1, Square::C1, Square::D1, Square::E1, Square::F1, Square::G1, Square::H1, Square::A2, Square::B2, Square::C2, Square::D2, Square::E2, Square::F2, Square::G2, Square::H2, Square::A3, Square::B3, Square::C3, Square::D3, Square::E3, Square::F3, Square::G3, Square::H3, Square::A4, Square::B4, Square::C4, Square::D4, Square::E4, Square::F4, Square::G4, Square::H4, Square::A5, Square::B5, Square::C5, Square::D5, Square::E5, Square::F5, Square::G5, Square::H5, Square::A6, Square::B6, Square::C6, Square::D6, Square::E6, Square::F6, Square::G6, Square::H6, Square::A7, Square::B7, Square::C7, Square::D7, Square::E7, Square::F7, Square::G7, Square::H7, Square::A8, Square::B8, Square::C8, Square::D8, Square::E8, Square::F8, Square::G8, Square::H8, ]; impl Square { pub fn to_bitboard(&self) -> u64 { 1_u64 << (*self as u8) } } impl TryFrom for Square { type Error = &'static str; fn try_from(value: u8) -> Result { if value <= 63 { Ok(unsafe { std::mem::transmute(value) }) } else { Err("Square index out of bounds") } } } impl Add for Square { type Output = Self; fn add(self, rhs: u8) -> Self::Output { let new_val = (self as u8) + rhs; new_val.try_into().expect("Square addition resulted in an invalid square") } } impl Add for Square { type Output = Self; fn add(self, rhs: i8) -> Self::Output { let new_val = ((self as i8) + rhs) as u8; new_val.try_into().expect("Square addition resulted in an invalid square") } } impl Sub for Square { type Output = Self; fn sub(self, rhs: u8) -> Self::Output { let new_val = (self as u8).checked_sub(rhs) .expect("Square subtraction resulted in an underflow"); new_val.try_into().expect("Square subtraction resulted in an invalid square") } } impl PartialOrd for Square { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } fn lt(&self, other: &Self) -> bool { (*self as u8) < (*other as u8) } fn le(&self, other: &Self) -> bool { (*self as u8) <= (*other as u8) } fn gt(&self, other: &Self) -> bool { (*self as u8) > (*other as u8) } fn ge(&self, other: &Self) -> bool { (*self as u8) >= (*other as u8) } } impl Ord for Square { fn cmp(&self, other: &Self) -> Ordering { (*self as u8).cmp(&(*other as u8)) } }