use crate::engine::bitboard::Bitboard;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Color {
White,
Black,
}
impl Color {
pub fn opposite(&self) -> Self {
match self {
Color::White => Color::Black,
Color::Black => Color::White,
}
}
pub fn iter() -> impl Iterator<Item = Color> {
[Color::White, Color::Black].iter().copied()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Piece {
Pawn,
Knight,
Bishop,
Rook,
Queen,
King,
}
impl Piece {
pub fn iter() -> impl Iterator<Item = Piece> {
[
Piece::Pawn,
Piece::Knight,
Piece::Bishop,
Piece::Rook,
Piece::Queen,
Piece::King,
]
.iter()
.copied()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Promotion {
Knight,
Bishop,
Rook,
Queen,
}
impl Promotion {
pub fn into_piece(self) -> Piece {
match self {
Promotion::Knight => Piece::Knight,
Promotion::Bishop => Piece::Bishop,
Promotion::Rook => Piece::Rook,
Promotion::Queen => Piece::Queen,
}
}
pub fn from_char(c: char) -> Option<Self> {
match c {
'n' => Some(Promotion::Knight),
'b' => Some(Promotion::Bishop),
'r' => Some(Promotion::Rook),
'q' => Some(Promotion::Queen),
_ => None,
}
}
}
impl std::fmt::Display for Promotion {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Promotion::Knight => write!(f, "n"),
Promotion::Bishop => write!(f, "b"),
Promotion::Rook => write!(f, "r"),
Promotion::Queen => write!(f, "q"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChessMan {
pub color: Color,
pub piece: Piece,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum File {
A,
B,
C,
D,
E,
F,
G,
H,
}
impl File {
pub fn from_char(c: char) -> Option<Self> {
match c {
'a' => Some(File::A),
'b' => Some(File::B),
'c' => Some(File::C),
'd' => Some(File::D),
'e' => Some(File::E),
'f' => Some(File::F),
'g' => Some(File::G),
'h' => Some(File::H),
_ => None,
}
}
pub fn index(&self) -> i8 {
*self as i8
}
pub fn from_index(index: i8) -> Self {
match index {
1 => File::A,
2 => File::B,
3 => File::C,
4 => File::D,
5 => File::E,
6 => File::F,
7 => File::G,
8 => File::H,
_ => unreachable!("File does not exists for this index"),
}
}
pub fn iter() -> impl Iterator<Item = Self> {
[
File::A,
File::B,
File::C,
File::D,
File::E,
File::F,
File::G,
File::H,
]
.iter()
.copied()
}
}
impl std::fmt::Display for File {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let c = 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, "{}", c)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Rank {
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
}
impl Rank {
pub fn from_char(c: char) -> Option<Self> {
match c {
'1' => Some(Rank::One),
'2' => Some(Rank::Two),
'3' => Some(Rank::Three),
'4' => Some(Rank::Four),
'5' => Some(Rank::Five),
'6' => Some(Rank::Six),
'7' => Some(Rank::Seven),
'8' => Some(Rank::Eight),
_ => None,
}
}
pub fn index(&self) -> i8 {
*self as i8
}
pub fn from_index(index: i8) -> Self {
match index {
1 => Rank::One,
2 => Rank::Two,
3 => Rank::Three,
4 => Rank::Four,
5 => Rank::Five,
6 => Rank::Six,
7 => Rank::Seven,
8 => Rank::Eight,
_ => unreachable!("Rank does not exists for this index"),
}
}
pub fn iter() -> impl Iterator<Item = Self> {
[
Rank::One,
Rank::Two,
Rank::Three,
Rank::Four,
Rank::Five,
Rank::Six,
Rank::Seven,
Rank::Eight,
]
.iter()
.copied()
}
}
impl std::fmt::Display for Rank {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let n = match self {
Rank::One => 1,
Rank::Two => 2,
Rank::Three => 3,
Rank::Four => 4,
Rank::Five => 5,
Rank::Six => 6,
Rank::Seven => 7,
Rank::Eight => 8,
};
write!(f, "{}", n)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Square {
pub file: File,
pub rank: Rank,
}
impl Square {
pub fn new(file: File, rank: Rank) -> Self {
Self { file, rank }
}
pub fn from_str(s: &str) -> Option<Self> {
let mut chars = s.chars();
let file = File::from_char(chars.next()?)?;
let rank = Rank::from_char(chars.next()?)?;
if chars.next().is_some() {
return None;
}
Some(Self::new(file, rank))
}
pub fn bitboard(&self) -> Bitboard {
(0b1 << self.file.index()) << (8 * self.rank.index())
}
pub fn try_offset(&self, file_offset: i8, rank_offset: i8) -> Option<Self> {
let file = File::iter().nth((self.file.index() + file_offset) as usize)?;
let rank = Rank::iter().nth((self.rank.index() + rank_offset) as usize)?;
Some(Self::new(file, rank))
}
pub fn index(&self) -> i8 {
self.file.index() + 8 * self.rank.index()
}
pub fn iter() -> impl Iterator<Item = Self> {
Rank::iter().flat_map(|rank| File::iter().map(move |file| Self::new(file, rank)))
}
}
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, Clone, Copy, PartialEq, Eq)]
pub struct Move {
pub from: Square,
pub to: Square,
pub promotion: Option<Promotion>,
}
impl Move {
pub fn new(from: Square, to: Square, promotion: Option<Promotion>) -> Self {
Self {
from,
to,
promotion,
}
}
}
impl std::fmt::Display for Move {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if self.promotion.is_some() {
write!(f, "{}{}{}", self.from, self.to, self.promotion.unwrap())
} else {
write!(f, "{}{}", self.from, self.to)
}
}
}