From 952b4b5ce3802eba743c94f8c2d91584880f1671 Mon Sep 17 00:00:00 2001 From: fabolous005 Date: Sun, 21 Apr 2024 05:50:40 +0200 Subject: [PATCH] add threatened_by function --- Cargo.toml | 5 + src/chess/board.rs | 60 +++++++-- src/chess/mod.rs | 1 + src/chess/moves.rs | 220 +++++++++---------------------- src/chess/piece_moves.rs | 277 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 395 insertions(+), 168 deletions(-) create mode 100644 src/chess/piece_moves.rs diff --git a/Cargo.toml b/Cargo.toml index 003e309..0ec8e51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,8 @@ log = "0.4.21" humantime = "2.1.0" strum = "0.26.2" strum_macros = "0.26.2" + + +[profile.release] +lto = true +opt-level = 3 diff --git a/src/chess/board.rs b/src/chess/board.rs index de3ded9..db18626 100644 --- a/src/chess/board.rs +++ b/src/chess/board.rs @@ -1,9 +1,13 @@ +use std::borrow::Borrow; + use crate::chess::piece::PieceVariant; use crate::chess::{moves::MoveVariant, piece::Piece}; use crate::chess::square::Square; use crate::chess::moves::Move; use log::{debug, trace}; +use strum::IntoEnumIterator; +use super::moves::MoveVariantIter; use super::position::Position; @@ -179,23 +183,45 @@ impl Board { - pub fn ref_rows(&mut self) -> &mut [[Option; 8]; 8] { + pub fn ref_rows(&self) -> &[[Option; 8]; 8] { + &self.rows + } + + pub fn ref_whites_turn(&self) -> &bool { + &self.whites_turn + } + + pub fn ref_castling(&self) -> &[Castling; 2] { + &self.castling + } + + pub fn ref_en_passent(&self) -> &Option { + &self.en_pessant + } + + pub fn ref_position(&self) -> &Position { + &self.position + } + + + + pub fn mut_ref_rows(&mut self) -> &mut [[Option; 8]; 8] { &mut self.rows } - pub fn ref_whites_turn(&mut self) -> &mut bool { + pub fn mut_ref_whites_turn(&mut self) -> &mut bool { &mut self.whites_turn } - pub fn ref_castling(&mut self) -> &mut [Castling; 2] { + pub fn mut_ref_castling(&mut self) -> &mut [Castling; 2] { &mut self.castling } - pub fn ref_en_passent(&mut self) -> &mut Option { + pub fn mut_ref_en_passent(&mut self) -> &mut Option { &mut self.en_pessant } - pub fn ref_position(&mut self) -> &mut Position { + pub fn mut_ref_position(&mut self) -> &mut Position { &mut self.position } } @@ -219,7 +245,7 @@ impl Board { if self.ref_position().ref_check().is_some() { if self.ref_position().ref_check().unwrap() { let king_pos = self.king_pos(self.whites_turn); - self.ref_position().ref_set_moves(MoveVariant::king_move(king_pos)); + self.mut_ref_position().ref_set_moves(MoveVariant::king_move(king_pos)); } else { todo!("take, block or king move"); } @@ -227,11 +253,27 @@ impl Board { todo!("finish"); } - pub fn threatened(&self, square: Square) -> bool { - todo!(); + // INFO: solution 1 => reverse Change + // solution 2 => loops + pub fn rc_threatened(&self, square: Square) -> bool { + let mut changes; + let mut to_move; + for variant in MoveVariant::iter() { + to_move = self.whites_turn; + changes = MoveVariant::variant_move(variant.borrow()); + for change in changes { + if self.ref_rows() + [(square.clone().x() as i8 + change.ref_x()) as usize] + [(square.clone().y() as i8 + change.ref_y()) as usize] == + Some(Piece::new(to_move, variant.as_piece_variant())) { + return true; + } + } + } + false } - pub fn threatened_by(&self, square: Square) -> Square { + pub fn threatened_by(&self, _square: Square) -> Square { todo!(); } } diff --git a/src/chess/mod.rs b/src/chess/mod.rs index e545a7a..b6ad5cc 100644 --- a/src/chess/mod.rs +++ b/src/chess/mod.rs @@ -1,6 +1,7 @@ // TODO: remove this pub later pub mod board; pub mod piece; +mod piece_moves; pub mod moves; mod position; mod square; diff --git a/src/chess/moves.rs b/src/chess/moves.rs index 446bd96..701cb8e 100644 --- a/src/chess/moves.rs +++ b/src/chess/moves.rs @@ -58,6 +58,26 @@ impl Change { } } +impl Change { + pub fn set_x(&mut self, x: i8) -> &mut Self { + self.x = x; + self + } + pub fn set_y(&mut self, y: i8) -> &mut Self { + self.y = y; + self + } +} + +impl Change { + pub fn reverse(&mut self) -> &Self { + let x = *self.ref_x(); + self.set_x(-x); + let y = self.ref_y(); + self.set_y(-y) + } +} + #[derive(strum_macros::EnumIter)] @@ -81,18 +101,7 @@ pub enum MoveVariant { } impl MoveVariant { - pub fn king() -> [Change; 8] { - [ - Change { x: 0, y: 1 }, - Change { x: 0, y: -1 }, - Change { x: 1, y: 0 }, - Change { x: 1, y: 1 }, - Change { x: 1, y: -1 }, - Change { x: -1, y: 0 }, - Change { x: -1, y: 1 }, - Change { x: -1, y: -1 }, - ] - } + pub fn king_move(current: Square) -> Vec { let mut moves = Vec::new(); for change in Self::king().iter() { @@ -107,155 +116,48 @@ impl MoveVariant { } moves } +} - pub fn queen() -> [Change; 8] { - [ - Change { x: 0, y: 1 }, - Change { x: 0, y: -1 }, - Change { x: 1, y: 0 }, - Change { x: 1, y: 1 }, - Change { x: 1, y: -1 }, - Change { x: -1, y: 0 }, - Change { x: -1, y: 1 }, - Change { x: -1, y: -1 }, - ] +impl MoveVariant { + pub fn variant_move(&self) -> Vec { + match self { + Self::King => Self::vec_king(), + Self::KingCastle => todo!(), + Self::Queen => Self::vec_queen(), + Self::Rook => Self::vec_rook(), + Self::Bishop => Self::vec_bishop(), + Self::Knight => Self::vec_knight(), + Self::PawnWhite => Self::vec_pawn_white(), + Self::PawnWhiteDouble => Self::vec_pawn_white_double(), + Self::PawnWhiteEnPassent => Self::vec_pawn_white_en_passent(), + Self::PawnWhiteCaptureLeft => Self::vec_pawn_white_capture_left(), + Self::PawnWhiteCaptureRight => Self::vec_pawn_white_capture_right(), + Self::PawnBlack => Self::vec_pawn_black(), + Self::PawnBlackDouble => Self::vec_pawn_black_double(), + Self::PawnBlackEnPassent => Self::vec_pawn_black_en_passent(), + Self::PawnBlackCaptureLeft => Self::vec_pawn_black_capture_left(), + Self::PawnBlackCaptureRight => Self::vec_pawn_black_capture_right(), + } } - pub fn rook() -> [Change; 4] { - [ - Change { x: 0, y: -1 }, - Change { x: 0, y: 1 }, - Change { x: 1, y: 0 }, - Change { x: -1, y: 0 } - ] - } - - pub fn bishop() -> [Change; 4] { - [ - Change { x: -1, y: -1 }, - Change { x: -1, y: 1 }, - Change { x: 1, y: -1 }, - Change { x: 1, y: 1 } - ] - } - - pub fn knight() -> [Change; 8] { - [ - Change { x: 1, y: 2 }, - Change { x: 2, y: 1 }, - Change { x: 2, y: -1 }, - Change { x: 1, y: -2 }, - Change { x: -1, y: -2 }, - Change { x: -2, y: -1}, - Change { x: -2, y: 1}, - Change { x: -1, y: 2}, - ] - } - - pub fn pawn_white() -> [Change; 1] { - [ Change { x: 0, y: -1 } ] - } - - pub fn pawn_white_double() -> [Change; 1] { - [ Change { x: 0, y: -2 } ] - } - - pub fn pawn_white_en_passent() -> [Change; 2] { - [ - Change { x: -1, y: -1 }, - Change { x: 1, y: -1 }, - ] - } - - pub fn pawn_white_capture_left() -> [Change; 1] { - [ Change { x: -1, y: -1 } ] - } - - pub fn pawn_white_capture_right() -> [Change; 1] { - [ Change { x: 1, y: -1 } ] - } - - pub fn pawn_black() -> [Change; 1] { - [ Change { x: 0, y: 1 } ] - } - - pub fn pawn_black_double() -> [Change; 1] { - [ Change { x: 0, y: 2 } ] - } - - pub fn pawn_black_en_passent() -> [Change; 2] { - [ - Change { x: -1, y: 1 }, - Change { x: 1, y: 1 }, - ] - } - - pub fn pawn_black_capture_left() -> [Change; 1] { - [ Change { x: 1, y: 1 } ] - } - - pub fn pawn_black_capture_right() -> [Change; 1] { - [ Change { x: -1, y: 1 } ] - } - - - pub fn number_king() -> u8 { - 8 - } - - pub fn number_queen() -> u8 { - 8 - } - - pub fn number_rook() -> u8 { - 4 - } - - pub fn number_bishop() -> u8 { - 4 - } - - pub fn number_knight() -> u8 { - 8 - } - - pub fn number_pawn_white() -> u8 { - 1 - } - - pub fn number_pawn_white_double() -> u8 { - 1 - } - - pub fn number_pawn_white_en_passent() -> u8 { - 2 - } - - pub fn number_pawn_white_capture_left() -> u8 { - 1 - } - - pub fn number_pawn_white_capture_right() -> u8 { - 1 - } - - pub fn number_pawn_black() -> u8 { - 1 - } - - pub fn number_pawn_black_double() -> u8 { - 1 - } - - pub fn number_pawn_black_en_passent() -> u8 { - 2 - } - - pub fn number_pawn_black_capture_left() -> u8 { - 1 - } - - pub fn number_pawn_black_capture_right() -> u8 { - 1 + pub fn as_piece_variant(&self) -> PieceVariant { + match self { + Self::King => PieceVariant::King, + Self::KingCastle => PieceVariant::King, + Self::Queen => PieceVariant::Queen, + Self::Rook => PieceVariant::Rook, + Self::Bishop => PieceVariant::Bishop, + Self::Knight => PieceVariant::Knight, + Self::PawnWhite => PieceVariant::Pawn, + Self::PawnWhiteDouble => PieceVariant::Pawn, + Self::PawnWhiteEnPassent => PieceVariant::Pawn, + Self::PawnWhiteCaptureLeft => PieceVariant::Pawn, + Self::PawnWhiteCaptureRight => PieceVariant::Pawn, + Self::PawnBlack => PieceVariant::Pawn, + Self::PawnBlackDouble => PieceVariant::Pawn, + Self::PawnBlackEnPassent => PieceVariant::Pawn, + Self::PawnBlackCaptureLeft => PieceVariant::Pawn, + Self::PawnBlackCaptureRight => PieceVariant::Pawn, + } } } diff --git a/src/chess/piece_moves.rs b/src/chess/piece_moves.rs new file mode 100644 index 0000000..6630c46 --- /dev/null +++ b/src/chess/piece_moves.rs @@ -0,0 +1,277 @@ +use crate::chess::moves; +use crate::chess::moves::{MoveVariant, Change}; + +impl MoveVariant { + pub fn king() -> [Change; 8] { + [ + Change::new(0, 1), + Change::new(0, -1), + Change::new(1, 0), + Change::new(1, 1), + Change::new(1, -1), + Change::new(-1, 0), + Change::new(-1, 1), + Change::new(-1, -1), + ] + } + + + pub fn queen() -> [Change; 8] { + [ + Change::new(0, 1), + Change::new(0, -1), + Change::new(1, 0), + Change::new(1, 1), + Change::new(1, -1), + Change::new(-1, 0), + Change::new(-1, 1), + Change::new(-1, -1), + ] + } + + pub fn rook() -> [Change; 4] { + [ + Change::new(0, -1), + Change::new(0, 1), + Change::new(1, 0), + Change::new(-1, 0) + ] + } + + pub fn bishop() -> [Change; 4] { + [ + Change::new(-1, -1), + Change::new(-1, 1), + Change::new(1, -1), + Change::new(1, 1) + ] + } + + pub fn knight() -> [Change; 8] { + [ + Change::new(1, 2), + Change::new(2, 1), + Change::new(2, -1), + Change::new(1, -2), + Change::new(-1, -2), + Change::new(-2, -1), + Change::new(-2, 1), + Change::new(-1, 2), + ] + } + + pub fn pawn_white() -> [Change; 1] { + [ Change::new(0, -1) ] + } + + pub fn pawn_white_double() -> [Change; 1] { + [ Change::new(0, -2) ] + } + + pub fn pawn_white_en_passent() -> [Change; 2] { + [ + Change::new(-1, -1), + Change::new(1, -1), + ] + } + + pub fn pawn_white_capture_left() -> [Change; 1] { + [ Change::new(-1, -1) ] + } + + pub fn pawn_white_capture_right() -> [Change; 1] { + [ Change::new(1, -1) ] + } + + pub fn pawn_black() -> [Change; 1] { + [ Change::new(0, 1) ] + } + + pub fn pawn_black_double() -> [Change; 1] { + [ Change::new(0, 2) ] + } + + pub fn pawn_black_en_passent() -> [Change; 2] { + [ + Change::new(-1, 1), + Change::new(1, 1), + ] + } + + pub fn pawn_black_capture_left() -> [Change; 1] { + [ Change::new(1, 1) ] + } + + pub fn pawn_black_capture_right() -> [Change; 1] { + [ Change::new(-1, 1) ] + } + + + + pub fn vec_king() -> Vec { + vec![ + Change::new(0, 1), + Change::new(0, -1), + Change::new(1, 0), + Change::new(1, 1), + Change::new(1, -1), + Change::new(-1, 0), + Change::new(-1, 1), + Change::new(-1, -1), + ] + } + + + pub fn vec_queen() -> Vec { + vec![ + Change::new(0, 1), + Change::new(0, -1), + Change::new(1, 0), + Change::new(1, 1), + Change::new(1, -1), + Change::new(-1, 0), + Change::new(-1, 1), + Change::new(-1, -1), + ] + } + + pub fn vec_rook() -> Vec { + vec![ + Change::new(0, -1), + Change::new(0, 1), + Change::new(1, 0), + Change::new(-1, 0) + ] + } + + pub fn vec_bishop() -> Vec { + vec![ + Change::new(-1, -1), + Change::new(-1, 1), + Change::new(1, -1), + Change::new(1, 1) + ] + } + + pub fn vec_knight() -> Vec { + vec![ + Change::new(1, 2), + Change::new(2, 1), + Change::new(2, -1), + Change::new(1, -2), + Change::new(-1, -2), + Change::new(-2, -1), + Change::new(-2, 1), + Change::new(-1, 2), + ] + } + + pub fn vec_pawn_white() -> Vec { + vec![ Change::new(0, -1) ] + } + + pub fn vec_pawn_white_double() -> Vec { + vec![ Change::new(0, -2) ] + } + + pub fn vec_pawn_white_en_passent() -> Vec { + vec![ + Change::new(-1, -1), + Change::new(1, -1), + ] + } + + pub fn vec_pawn_white_capture_left() -> Vec { + vec![ Change::new(-1, -1) ] + } + + pub fn vec_pawn_white_capture_right() -> Vec { + vec![ Change::new(1, -1) ] + } + + pub fn vec_pawn_black() -> Vec { + vec![ Change::new(0, 1) ] + } + + pub fn vec_pawn_black_double() -> Vec { + vec![ Change::new(0, 2) ] + } + + pub fn vec_pawn_black_en_passent() -> Vec { + vec![ + Change::new(-1, 1), + Change::new(1, 1), + ] + } + + pub fn vec_pawn_black_capture_left() -> Vec { + vec![ Change::new(1, 1) ] + } + + pub fn vec_pawn_black_capture_right() -> Vec { + vec![ Change::new(-1, 1) ] + } + + + + pub fn number_king() -> u8 { + 8 + } + + pub fn number_queen() -> u8 { + 8 + } + + pub fn number_rook() -> u8 { + 4 + } + + pub fn number_bishop() -> u8 { + 4 + } + + pub fn number_knight() -> u8 { + 8 + } + + pub fn number_pawn_white() -> u8 { + 1 + } + + pub fn number_pawn_white_double() -> u8 { + 1 + } + + pub fn number_pawn_white_en_passent() -> u8 { + 2 + } + + pub fn number_pawn_white_capture_left() -> u8 { + 1 + } + + pub fn number_pawn_white_capture_right() -> u8 { + 1 + } + + pub fn number_pawn_black() -> u8 { + 1 + } + + pub fn number_pawn_black_double() -> u8 { + 1 + } + + pub fn number_pawn_black_en_passent() -> u8 { + 2 + } + + pub fn number_pawn_black_capture_left() -> u8 { + 1 + } + + pub fn number_pawn_black_capture_right() -> u8 { + 1 + } + +}