pub mod pawn;
pub mod rook;
pub mod sliding;
use std::fmt::Debug;
use crate::bitboard::BitBoard;
use crate::game::position::Position;
use crate::game::Move;
#[allow(dead_code)]
pub const FILE_A: BitBoard =
BitBoard(0b0000000100000001000000010000000100000001000000010000000100000001);
#[allow(dead_code)]
pub const FILE_B: BitBoard = BitBoard(FILE_A.0 << 1);
#[allow(dead_code)]
pub const FILE_C: BitBoard = BitBoard(FILE_A.0 << 2);
#[allow(dead_code)]
pub const FILE_D: BitBoard = BitBoard(FILE_A.0 << 3);
#[allow(dead_code)]
pub const FILE_E: BitBoard = BitBoard(FILE_A.0 << 4);
#[allow(dead_code)]
pub const FILE_F: BitBoard = BitBoard(FILE_A.0 << 5);
#[allow(dead_code)]
pub const FILE_G: BitBoard = BitBoard(FILE_A.0 << 6);
#[allow(dead_code)]
pub const FILE_H: BitBoard = BitBoard(FILE_A.0 << 7);
#[allow(dead_code)]
pub const FILES: [BitBoard; 8] = [
FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H,
];
#[allow(dead_code)]
pub const RANK_1: BitBoard = BitBoard(0b11111111);
#[allow(dead_code)]
pub const RANK_2: BitBoard = BitBoard(RANK_1.0 << 8);
#[allow(dead_code)]
pub const RANK_3: BitBoard = BitBoard(RANK_2.0 << 8);
#[allow(dead_code)]
pub const RANK_4: BitBoard = BitBoard(RANK_3.0 << 8);
#[allow(dead_code)]
pub const RANK_5: BitBoard = BitBoard(RANK_4.0 << 8);
#[allow(dead_code)]
pub const RANK_6: BitBoard = BitBoard(RANK_5.0 << 8);
#[allow(dead_code)]
pub const RANK_7: BitBoard = BitBoard(RANK_6.0 << 8);
#[allow(dead_code)]
pub const RANK_8: BitBoard = BitBoard(RANK_7.0 << 8);
#[allow(dead_code)]
pub const RANKS: [BitBoard; 8] = [
RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8,
];
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Pieces {
Pawn(Color, Position),
Rook(Color, Position),
Knight(Color, Position),
Bishop(Color, Position),
Queen(Color, Position),
King(Color, Position),
}
impl Pieces {
pub fn get_color(&self) -> Color {
match self {
Pieces::Pawn(color, _) => *color,
Pieces::Rook(color, _) => *color,
Pieces::Knight(color, _) => *color,
Pieces::Bishop(color, _) => *color,
Pieces::Queen(color, _) => *color,
Pieces::King(color, _) => *color,
}
}
pub fn get_position(&self) -> Position {
match self {
Pieces::Pawn(_, position) => *position,
Pieces::Rook(_, position) => *position,
Pieces::Knight(_, position) => *position,
Pieces::Bishop(_, position) => *position,
Pieces::Queen(_, position) => *position,
Pieces::King(_, position) => *position,
}
}
pub fn is_pawn(&self) -> bool {
matches!(self, Pieces::Pawn(_, _))
}
pub fn is_rook(&self) -> bool {
matches!(self, Pieces::Rook(_, _))
}
pub fn is_knight(&self) -> bool {
matches!(self, Pieces::Knight(_, _))
}
pub fn is_bishop(&self) -> bool {
matches!(self, Pieces::Bishop(_, _))
}
pub fn is_queen(&self) -> bool {
matches!(self, Pieces::Queen(_, _))
}
pub fn is_king(&self) -> bool {
matches!(self, Pieces::King(_, _))
}
pub fn is_black(&self) -> bool {
matches!(self.get_color(), Color::Black)
}
pub fn is_white(&self) -> bool {
matches!(self.get_color(), Color::White)
}
pub fn to_letter_notation(&self) -> char {
let c = match self {
Pieces::Pawn(_, _) => 'p',
Pieces::Rook(_, _) => 'r',
Pieces::Knight(_, _) => 'n',
Pieces::Bishop(_, _) => 'b',
Pieces::Queen(_, _) => 'q',
Pieces::King(_, _) => 'k',
};
if self.get_color() == Color::Black {
c
} else {
c.to_ascii_uppercase()
}
}
pub fn to_unicode_symbol(&self) -> char {
match self {
Pieces::Pawn(Color::White, _) => '♙',
Pieces::Pawn(Color::Black, _) => '♟',
Pieces::Rook(Color::White, _) => '♖',
Pieces::Rook(Color::Black, _) => '♜',
Pieces::Knight(Color::White, _) => '♘',
Pieces::Knight(Color::Black, _) => '♞',
Pieces::Bishop(Color::White, _) => '♗',
Pieces::Bishop(Color::Black, _) => '♝',
Pieces::Queen(Color::White, _) => '♕',
Pieces::Queen(Color::Black, _) => '♛',
Pieces::King(Color::White, _) => '♔',
Pieces::King(Color::Black, _) => '♚',
}
}
}
pub fn get_castling_rook_move(king_move: &Move) -> Option<Move> {
if *king_move == ("e1", "c1").into() {
Some(("a1", "d1").into())
} else if *king_move == ("e1", "g1").into() {
Some(("h1", "f1").into())
} else if *king_move == ("e8", "c8").into() {
Some(("a8", "d8").into())
} else if *king_move == ("e8", "g8").into() {
Some(("h8", "f8").into())
} else {
None
}
}
pub fn is_pawn_two_step(pawn_move: &Move) -> bool {
let Move(origin, destination, _) = pawn_move;
origin.distance_rank(destination) == 2 && (origin.rank_y == 1 || origin.rank_y == 6)
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Color {
White,
Black,
}
impl Color {
pub fn opposite(&self) -> Self {
match self {
Self::White => Self::Black,
Self::Black => Self::White,
}
}
pub fn is_black(&self) -> bool {
*self == Color::Black
}
pub fn is_white(&self) -> bool {
*self == Color::White
}
}