use std::mem::transmute;
use strum_macros::EnumIter;
use crate::Bitboard;
#[derive(Debug, EnumIter, Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
pub enum Rank {
Rank1,
Rank2,
Rank3,
Rank4,
Rank5,
Rank6,
Rank7,
Rank8,
}
impl std::fmt::Display for Rank {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let number = match &self {
Rank::Rank1 => "1",
Rank::Rank2 => "2",
Rank::Rank3 => "3",
Rank::Rank4 => "4",
Rank::Rank5 => "5",
Rank::Rank6 => "6",
Rank::Rank7 => "7",
Rank::Rank8 => "8",
};
write!(f, "{number}")
}
}
impl Rank {
#[inline]
pub fn from_index(i: usize) -> Rank {
unsafe { transmute((i as u8) & 7) }
}
}
#[derive(Debug, EnumIter, Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
pub enum File {
A,
B,
C,
D,
E,
F,
G,
H,
}
impl std::fmt::Display for File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let letter = match &self {
File::A => "a",
File::B => "b",
File::C => "c",
File::D => "d",
File::E => "e",
File::F => "f",
File::G => "g",
File::H => "h",
};
write!(f, "{letter}")
}
}
impl File {
#[inline]
pub fn from_index(i: usize) -> File {
unsafe { transmute((i as u8) & 7) }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Square(pub u8);
impl Square {
pub fn from_file_and_rank(file: File, rank: Rank) -> Self {
Self((rank as u8 * 8) + file as u8)
}
pub fn file(&self) -> File {
File::from_index((self.0 & 7) as usize)
}
pub fn rank(&self) -> Rank {
Rank::from_index((self.0 >> 3) as usize)
}
}
impl Into<Bitboard> for Square {
fn into(self) -> Bitboard {
Bitboard::from_square_number(self.0)
}
}
impl std::fmt::Display for Square {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.file(), self.rank())
}
}
#[derive(Debug)]
pub struct SquareParseError;
impl std::str::FromStr for Square {
type Err = SquareParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() < 2 {
return Err(SquareParseError);
}
let ch: Vec<char> = s.chars().collect();
match ch[0] {
'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' => {}
_ => {
return Err(SquareParseError);
}
}
match ch[1] {
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' => {}
_ => {
return Err(SquareParseError);
}
}
Ok(Square::from_file_and_rank(
File::from_index((ch[0] as usize) - ('a' as usize)),
Rank::from_index((ch[1] as usize) - ('1' as usize)),
))
}
}