diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9bded2b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,227 @@ +use std::collections::HashSet; + +const WHITE_PAWN: char = '♙'; +const WHITE_KNIGHT: char = '♘'; +const WHITE_BISHOP: char = '♗'; +const WHITE_ROOK: char = '♖'; +const WHITE_QUEEN: char = '♕'; +const WHITE_KING: char = '♔'; +const BLACK_PAWN: char = '♟'; +const BLACK_KNIGHT: char = '♞'; +const BLACK_BISHOP: char = '♝'; +const BLACK_ROOK: char = '♜'; +const BLACK_QUEEN: char = '♛'; +const BLACK_KING: char = '♚'; + +#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] +#[rustfmt::skip] +enum BoardPosition { + A1, A2, A3, A4, A5, A6, A7, A8, + B1, B2, B3, B4, B5, B6, B7, B8, + C1, C2, C3, C4, C5, C6, C7, C8, + D1, D2, D3, D4, D5, D6, D7, D8, + E1, E2, E3, E4, E5, E6, E7, E8, + F1, F2, F3, F4, F5, F6, F7, F8, + G1, G2, G3, G4, G5, G6, G7, G8, + H1, H2, H3, H4, H5, H6, H7, H8, +} + +impl From for usize { + fn from(square: BoardPosition) -> Self { + use BoardPosition::*; + + match square { + A1 => 0, + A2 => 1, + A3 => 2, + A4 => 3, + A5 => 4, + A6 => 5, + A7 => 6, + A8 => 7, + B1 => 8, + B2 => 9, + B3 => 10, + B4 => 11, + B5 => 12, + B6 => 13, + B7 => 14, + B8 => 15, + C1 => 16, + C2 => 17, + C3 => 18, + C4 => 19, + C5 => 20, + C6 => 21, + C7 => 22, + C8 => 23, + D1 => 24, + D2 => 25, + D3 => 26, + D4 => 27, + D5 => 28, + D6 => 29, + D7 => 30, + D8 => 31, + E1 => 32, + E2 => 33, + E3 => 34, + E4 => 35, + E5 => 36, + E6 => 37, + E7 => 38, + E8 => 39, + F1 => 40, + F2 => 41, + F3 => 42, + F4 => 43, + F5 => 44, + F6 => 45, + F7 => 46, + F8 => 47, + G1 => 48, + G2 => 49, + G3 => 50, + G4 => 51, + G5 => 52, + G6 => 53, + G7 => 54, + G8 => 55, + H1 => 56, + H2 => 57, + H3 => 58, + H4 => 59, + H5 => 60, + H6 => 61, + H7 => 62, + H8 => 63, + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)] +pub enum MoveAmount { + One, + Two, + Many +} + +#[derive(Debug, Clone, PartialEq, Hash, Eq)] +pub enum MoveType { + Vertical(MoveAmount), + Horizontal(MoveAmount), + Diagonal(MoveAmount), + Knight, + KingSideCastle, + QueenSideCastle, + EnPassant, + Promoted(PieceType), +} + + + +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum PieceColor { + Black, + White, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +/// Which set of squares can this bishop use? +pub enum BishopType { + /// Only dark/black squares + Dark, + + /// Only light/red squares + Light, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum PieceType { + Pawn(Option>), + Rook, + Knight, + King, + Queen, + Bishop(BishopType), +} + +#[derive(Debug, PartialEq)] +pub struct Piece { + kind: PieceType, + color: PieceColor, + symbol: char, +} + +impl<'a> Piece { + pub fn new(color: PieceColor, kind: PieceType) -> Self { + Self { + kind: kind.clone(), + color, + symbol: Self::get_symbol(color, kind), + } + } + + pub fn get_symbol(color: PieceColor, kind: PieceType) -> char { + use PieceColor::*; + use PieceType::*; + + match (color, kind) { + // Treat promoted pawns as their promoted type + (c, Pawn(Some(k))) => Self::get_symbol(c, *k), + + (White, Pawn(None)) => WHITE_PAWN, + (White, Knight) => WHITE_KNIGHT, + (White, Bishop(_)) => WHITE_BISHOP, + (White, Rook) => WHITE_ROOK, + (White, Queen) => WHITE_QUEEN, + (White, King) => WHITE_KING, + (Black, Pawn(None)) => BLACK_PAWN, + (Black, Knight) => BLACK_KNIGHT, + (Black, Bishop(_)) => BLACK_BISHOP, + (Black, Rook) => BLACK_ROOK, + (Black, Queen) => BLACK_QUEEN, + (Black, King) => BLACK_KING, + } + } + + pub fn valid_move_types(kind: PieceType) -> HashSet { + use MoveAmount::*; + use PieceType::*; + + match kind { + Pawn(Some(k)) => Self::valid_move_types(*k), + Pawn(None) => HashSet::from([MoveType::Diagonal(One), MoveType::Vertical(One), MoveType::Vertical(Two), MoveType::EnPassant]), + Knight => HashSet::from([MoveType::Knight]), + Bishop(_) => HashSet::from([MoveType::Diagonal(Many)]), + Rook => HashSet::from([MoveType::Horizontal(Many), MoveType::Vertical(Many), MoveType::KingSideCastle, MoveType::QueenSideCastle]), + Queen => HashSet::from([MoveType::Horizontal(Many), MoveType::Vertical(Many), MoveType::Diagonal(Many)]), + King => HashSet::from([MoveType::Horizontal(One), MoveType::Vertical(One), MoveType::Diagonal(One), MoveType::KingSideCastle, MoveType::QueenSideCastle]) + } + } +} + +mod test { + use super::*; + + #[test] + fn test_make_black_rook() { + let piece = Piece::new(PieceColor::Black, PieceType::Rook); + assert_eq!(piece.symbol, BLACK_ROOK); + assert_eq!(piece.kind, PieceType::Rook); + assert_eq!(piece.color, PieceColor::Black); + } + + #[test] + fn test_get_white_knight_char() { + assert_eq!(Piece::get_symbol(PieceColor::White, PieceType::Knight), WHITE_KNIGHT); + } + + #[test] + fn test_get_promoted_white_pawn_queen() { + assert_eq!( + Piece::get_symbol(PieceColor::White, PieceType::Pawn(Some(Box::new(PieceType::Queen)))), + WHITE_QUEEN + ); + } +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 80d2c6c..0000000 --- a/src/main.rs +++ /dev/null @@ -1,80 +0,0 @@ -mod piece; - -enum MoveType { - VerticalOne, - VerticalTwo, - VerticalMany, - HorizontalMany, -} - -#[derive(Debug, Copy, Clone, PartialEq)] -enum BoardPosition { - A1, - A2, - A3, - A4, - A5, - A6, - A7, - A8, - B1, - B2, - B3, - B4, - B5, - B6, - B7, - B8, - C1, - C2, - C3, - C4, - C5, - C6, - C7, - C8, - D1, - D2, - D3, - D4, - D5, - D6, - D7, - D8, - E1, - E2, - E3, - E4, - E5, - E6, - E7, - E8, - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - G1, - G2, - G3, - G4, - G5, - G6, - G7, - G8, - H1, - H2, - H3, - H4, - H5, - H6, - H7, - H8, -} - -fn main() { - println!("Hello, world!"); -} diff --git a/src/piece.rs b/src/piece.rs deleted file mode 100644 index f838e11..0000000 --- a/src/piece.rs +++ /dev/null @@ -1,75 +0,0 @@ -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum PieceColor { - Black, - White, -} - -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum BishopType { - Dark, - Light, -} - -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum PieceType { - Pawn { promoted: bool }, - Rook, - Knight, - King, - Queen, - Bishop { kind: BishopType }, -} - -#[derive(Debug, PartialEq)] -pub struct Piece { - kind: PieceType, - color: PieceColor, - symbol: char, -} - -impl Piece { - pub fn new(color: PieceColor, kind: PieceType) -> Self { - Self { - kind, - color, - symbol: Self::get_symbol(color, kind), - } - } - - fn get_symbol(color: PieceColor, kind: PieceType) -> char { - use PieceColor::*; - use PieceType::*; - - match (color, kind) { - (White, Pawn { promoted: _ }) => '♙', - (White, Knight) => '♘', - (White, Bishop { kind: _ }) => '♗', - (White, Rook) => '♖', - (White, Queen) => '♕', - (White, King) => '♔', - (Black, Pawn { promoted: _ }) => '♟', - (Black, Knight) => '♞', - (Black, Bishop { kind: _ }) => '♝', - (Black, Rook) => '♜', - (Black, Queen) => '♛', - (Black, King) => '♚', - } - } -} - -mod test { - use super::*; - - #[test] - fn test_make_black_rook() { - let piece = Piece::new(PieceColor::Black, PieceType::Rook); - assert_eq!(piece.symbol, '♜'); - assert_eq!(piece.kind, PieceType::Rook); - assert_eq!(piece.color, PieceColor::Black); - } - - #[test] - fn test_get_white_knight() { - assert_eq!(Piece::get_symbol(PieceColor::White, PieceType::Knight), '♘'); - } -} \ No newline at end of file