use crate::color::Color;
use crate::error::Error;
use crate::file::File;
use crate::rank::Rank;
use std::fmt;
use std::str::FromStr;
#[derive(PartialEq, Ord, Eq, PartialOrd, Copy, Clone, Debug, Hash)]
pub struct Square(u8);
pub const NUM_SQUARES: usize = 64;
impl Default for Square {
fn default() -> Square {
unsafe { Square::new(0) }
}
}
impl Square {
#[inline]
pub unsafe fn new(sq: u8) -> Square {
Square(sq)
}
#[inline]
pub fn make_square(rank: Rank, file: File) -> Square {
Square((rank.to_index() as u8) << 3 ^ (file.to_index() as u8))
}
#[inline]
pub fn get_rank(&self) -> Rank {
Rank::from_index((self.0 >> 3) as usize)
}
#[inline]
pub fn get_file(&self) -> File {
File::from_index((self.0 & 7) as usize)
}
#[inline]
pub fn up(&self) -> Option<Square> {
if self.get_rank() == Rank::Eighth {
None
} else {
Some(Square::make_square(self.get_rank().up(), self.get_file()))
}
}
#[inline]
pub fn down(&self) -> Option<Square> {
if self.get_rank() == Rank::First {
None
} else {
Some(Square::make_square(self.get_rank().down(), self.get_file()))
}
}
#[inline]
pub fn left(&self) -> Option<Square> {
if self.get_file() == File::A {
None
} else {
Some(Square::make_square(self.get_rank(), self.get_file().left()))
}
}
#[inline]
pub fn right(&self) -> Option<Square> {
if self.get_file() == File::H {
None
} else {
Some(Square::make_square(
self.get_rank(),
self.get_file().right(),
))
}
}
#[inline]
pub fn forward(&self, color: Color) -> Option<Square> {
match color {
Color::White => self.up(),
Color::Black => self.down(),
}
}
#[inline]
pub fn backward(&self, color: Color) -> Option<Square> {
match color {
Color::White => self.down(),
Color::Black => self.up(),
}
}
#[inline]
pub fn uup(&self) -> Square {
Square::make_square(self.get_rank().up(), self.get_file())
}
#[inline]
pub fn udown(&self) -> Square {
Square::make_square(self.get_rank().down(), self.get_file())
}
#[inline]
pub fn uleft(&self) -> Square {
Square::make_square(self.get_rank(), self.get_file().left())
}
#[inline]
pub fn uright(&self) -> Square {
Square::make_square(self.get_rank(), self.get_file().right())
}
#[inline]
pub fn uforward(&self, color: Color) -> Square {
match color {
Color::White => self.uup(),
Color::Black => self.udown(),
}
}
#[inline]
pub fn ubackward(&self, color: Color) -> Square {
match color {
Color::White => self.udown(),
Color::Black => self.uup(),
}
}
#[inline]
pub fn to_int(&self) -> u8 {
self.0
}
#[inline]
pub fn to_index(&self) -> usize {
self.0 as usize
}
#[deprecated(
since = "3.1.0",
note = "please use `Square::from_str(square)?` instead"
)]
pub fn from_string(s: String) -> Option<Square> {
Square::from_str(&s).ok()
}
pub const A1: Square = Square(0);
pub const B1: Square = Square(1);
pub const C1: Square = Square(2);
pub const D1: Square = Square(3);
pub const E1: Square = Square(4);
pub const F1: Square = Square(5);
pub const G1: Square = Square(6);
pub const H1: Square = Square(7);
pub const A2: Square = Square(8);
pub const B2: Square = Square(9);
pub const C2: Square = Square(10);
pub const D2: Square = Square(11);
pub const E2: Square = Square(12);
pub const F2: Square = Square(13);
pub const G2: Square = Square(14);
pub const H2: Square = Square(15);
pub const A3: Square = Square(16);
pub const B3: Square = Square(17);
pub const C3: Square = Square(18);
pub const D3: Square = Square(19);
pub const E3: Square = Square(20);
pub const F3: Square = Square(21);
pub const G3: Square = Square(22);
pub const H3: Square = Square(23);
pub const A4: Square = Square(24);
pub const B4: Square = Square(25);
pub const C4: Square = Square(26);
pub const D4: Square = Square(27);
pub const E4: Square = Square(28);
pub const F4: Square = Square(29);
pub const G4: Square = Square(30);
pub const H4: Square = Square(31);
pub const A5: Square = Square(32);
pub const B5: Square = Square(33);
pub const C5: Square = Square(34);
pub const D5: Square = Square(35);
pub const E5: Square = Square(36);
pub const F5: Square = Square(37);
pub const G5: Square = Square(38);
pub const H5: Square = Square(39);
pub const A6: Square = Square(40);
pub const B6: Square = Square(41);
pub const C6: Square = Square(42);
pub const D6: Square = Square(43);
pub const E6: Square = Square(44);
pub const F6: Square = Square(45);
pub const G6: Square = Square(46);
pub const H6: Square = Square(47);
pub const A7: Square = Square(48);
pub const B7: Square = Square(49);
pub const C7: Square = Square(50);
pub const D7: Square = Square(51);
pub const E7: Square = Square(52);
pub const F7: Square = Square(53);
pub const G7: Square = Square(54);
pub const H7: Square = Square(55);
pub const A8: Square = Square(56);
pub const B8: Square = Square(57);
pub const C8: Square = Square(58);
pub const D8: Square = Square(59);
pub const E8: Square = Square(60);
pub const F8: Square = Square(61);
pub const G8: Square = Square(62);
pub const H8: Square = Square(63);
}
impl fmt::Display for Square {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}{}",
(('a' as u8) + ((self.0 & 7) as u8)) as char,
(('1' as u8) + ((self.0 >> 3) as u8)) as char
)
}
}
impl FromStr for Square {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() < 2 {
return Err(Error::InvalidSquare);
}
let ch: Vec<char> = s.chars().collect();
match ch[0] {
'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' => {}
_ => {
return Err(Error::InvalidSquare);
}
}
match ch[1] {
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' => {}
_ => {
return Err(Error::InvalidSquare);
}
}
Ok(Square::make_square(
Rank::from_index((ch[1] as usize) - ('1' as usize)),
File::from_index((ch[0] as usize) - ('a' as usize)),
))
}
}
pub const ALL_SQUARES: [Square; 64] = [
Square(0),
Square(1),
Square(2),
Square(3),
Square(4),
Square(5),
Square(6),
Square(7),
Square(8),
Square(9),
Square(10),
Square(11),
Square(12),
Square(13),
Square(14),
Square(15),
Square(16),
Square(17),
Square(18),
Square(19),
Square(20),
Square(21),
Square(22),
Square(23),
Square(24),
Square(25),
Square(26),
Square(27),
Square(28),
Square(29),
Square(30),
Square(31),
Square(32),
Square(33),
Square(34),
Square(35),
Square(36),
Square(37),
Square(38),
Square(39),
Square(40),
Square(41),
Square(42),
Square(43),
Square(44),
Square(45),
Square(46),
Square(47),
Square(48),
Square(49),
Square(50),
Square(51),
Square(52),
Square(53),
Square(54),
Square(55),
Square(56),
Square(57),
Square(58),
Square(59),
Square(60),
Square(61),
Square(62),
Square(63),
];