diff --git a/src/chess/board.rs b/src/chess/board.rs index 282a7d2..b949dd9 100644 --- a/src/chess/board.rs +++ b/src/chess/board.rs @@ -4,7 +4,7 @@ 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 log::{debug, info, trace}; use strum::IntoEnumIterator; use super::moves::MoveVariantIter; @@ -289,23 +289,42 @@ impl Board { } fn valid_moves_init(&mut self) -> Vec { + // trace!("{:?}", &self.mut_ref_position().ref_moves()); let mut moves: Vec = vec![]; if self.ref_position().ref_check().is_some() { if self.ref_position().ref_check().unwrap() { let king_pos = self.king_pos(self.whites_turn); - moves.append(&mut MoveVariant::king_move(king_pos)); - for i in 0..moves.len() { - if self.used(moves[i].to()) || self.threatened(moves[i].to()) { - moves.remove(i); + + + + // moves.append(&mut MoveVariant::king_move(king_pos)); + // // trace!("{:?}", moves); + // for i in 0..moves.len() { + // trace!("{:?}", moves[i]); + // if self.used(moves[i].to()) || self.threatened(moves[i].to()) { + // moves.remove(i); + // } + // } + + for _move in MoveVariant::king_move(king_pos) { + trace!("{:?}", _move); + trace!("used: {:?}", !self.used(_move.to())); + trace!("threatened: {:?}", !self.threatened(_move.to())); + // TODO: used only if NOT same color + if !self.used(_move.to()) && !self.threatened(_move.to()) { + trace!("pushing move: {:?}", _move); + moves.push(_move); } } } else { todo!("take, block or king move"); } + } else { + todo!("Any other move") } if moves.is_empty() { - todo!("Any other move") + info!("Checkmate"); } moves } @@ -314,7 +333,17 @@ impl Board { impl Board { pub fn used(&self, square: Square) -> bool { - self.ref_rows()[square.x() as usize][square.y() as usize].is_some() + // self.ref_rows()[square.x() as usize][square.y() as usize].is_some() + self.ref_rows()[square.y() as usize][square.x() as usize].is_some() + } + + pub fn used_by(&self, square: Square) -> Option { + let piece = &self.ref_rows()[square.y() as usize][square.x() as usize]; + if piece.is_some() { + Some(Piece::new(!self.ref_whites_turn(), piece.clone().unwrap().as_piece_variant())) + } else { + None + } } pub fn threatened(&self, square: Square) -> bool { @@ -337,46 +366,102 @@ impl Board { } } } + + + let mut changes; + let to_move = self.whites_turn; + for variant in MoveVariant::iter() { + // TODO: generate the MoveVariants from current available pieces + changes = MoveVariant::variant_move(variant.borrow()); + for mut change in changes { + change = change.reverse(); + let mut multiplier = 1; + while multiplier < 8 { + if square.x() as i8 + change.ref_x() * multiplier < 0 || square.x() as i8 + change.ref_x() * multiplier > 7 || + square.y() as i8 + change.ref_y() * multiplier < 0 || square.y() as i8 + change.ref_y() * multiplier > 7 + // TODO: this should check for pieces in the scope of others + { + break; + }; + if self.ref_rows() + [(square.y() as i8 + change.ref_y() * multiplier) as usize] + [(square.x() as i8 + change.ref_x() * multiplier) as usize] == + Some(Piece::new(!to_move, variant.as_piece_variant())) { + return true; + } + if !variant.iterable() { + break; + } + multiplier += 1; + } + } + } false } - // TODO: fix this + + // HACK: make this stable pub fn threatened_by(&self, square: Square) -> Vec { let mut changes; let to_move = self.whites_turn; let mut attacker = vec![]; for variant in MoveVariant::iter() { + // TODO: generate the MoveVariants from current available pieces changes = MoveVariant::variant_move(variant.borrow()); for mut change in changes { change = change.reverse(); let mut multiplier = 1; - - loop { + while multiplier < 8 { if square.x() as i8 + change.ref_x() * multiplier < 0 || square.x() as i8 + change.ref_x() * multiplier > 7 || - square.y() as i8 + change.ref_y() * multiplier < 0 || square.y() as i8 + change.ref_y() * multiplier > 7 || - { - multiplier >= 2 && - !self.used(Square::new((square.x() as i8 + change.ref_x() * multiplier) as u8, (square.y() as i8 + change.ref_y() * multiplier) as u8)) - } + square.y() as i8 + change.ref_y() * multiplier < 0 || square.y() as i8 + change.ref_y() * multiplier > 7 + // TODO: this should check for pieces in the scope of others + // || { + // if multiplier >= 2 { + // trace!("comparing {:?} with {:?}", Piece::new(!to_move, variant.as_piece_variant()), self.used_by(Square::new( + // (square.x() as i8 + change.ref_x() * multiplier) as u8, + // (square.y() as i8 + change.ref_y() * multiplier) as u8 + // ))); + // self.used_by(Square::new( + // (square.x() as i8 + change.ref_x() * multiplier) as u8, + // (square.y() as i8 + change.ref_y() * multiplier) as u8 + // )) != Some(Piece::new(!to_move, variant.as_piece_variant())) + // } else { + // false + // } + // } { - trace!( - "{:?}:{:?}x{:?} => {:?}", + "{:?}x{:?} \t{:?}\tbreak\t{:?}", {square.x() as i8 + change.ref_x() * multiplier}, {square.y() as i8 + change.ref_y() * multiplier}, multiplier, variant.as_piece_variant() ); break; + } else { + trace!( + "{:?}x{:?} \t{:?}\telse\t{:?}", + {square.x() as i8 + change.ref_x() * multiplier}, + {square.y() as i8 + change.ref_y() * multiplier}, + multiplier, + variant.as_piece_variant() + ); } - if self.ref_rows() - [(square.y() as i8 + change.ref_y()) as usize] - [(square.x() as i8 + change.ref_x()) as usize] == + [(square.y() as i8 + change.ref_y() * multiplier) as usize] + [(square.x() as i8 + change.ref_x() * multiplier) as usize] == Some(Piece::new(!to_move, variant.as_piece_variant())) { + trace!( + "{:?}x{:?} \t{:?}\tpush\t{:?}", + {square.x() as i8 + change.ref_x() * multiplier}, + {square.y() as i8 + change.ref_y() * multiplier}, + multiplier, + variant.as_piece_variant() + ); + attacker.push(Square::new( - (square.x() as i8 + change.ref_x()) as u8, - (square.y() as i8 + change.ref_y()) as u8, + (square.x() as i8 + change.ref_x() * multiplier) as u8, + (square.y() as i8 + change.ref_y() * multiplier) as u8, )); } if !variant.iterable() { @@ -386,6 +471,9 @@ impl Board { } } } + trace!("{:?}", attacker); attacker } } + + diff --git a/src/chess/moves.rs b/src/chess/moves.rs index d1cec27..1b76252 100644 --- a/src/chess/moves.rs +++ b/src/chess/moves.rs @@ -1,5 +1,6 @@ use super::{piece::PieceVariant, square::Square}; +use log::trace; #[cfg(feature = "custom_pieces")] use serde_derive::Deserialize; @@ -32,6 +33,7 @@ pub struct Change { } #[cfg(not(feature = "custom_pieces"))] +#[derive(Debug)] pub struct Change { x: i8, y: i8 @@ -114,7 +116,7 @@ impl MoveVariant { let new_square = current.add_change(change); if let Some(new_square) = new_square { moves.push(Move { - from: current.clone(), + from: current, to: new_square, promotion: None }); diff --git a/src/chess/piece.rs b/src/chess/piece.rs index b9df470..89d9f66 100644 --- a/src/chess/piece.rs +++ b/src/chess/piece.rs @@ -12,7 +12,7 @@ pub enum PieceVariant { Pawn } -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Debug, Clone)] pub struct Piece { white: bool, variant: PieceVariant @@ -40,6 +40,10 @@ impl Piece { _ => None } } + + pub fn as_piece_variant(self) -> PieceVariant { + self.variant + } } diff --git a/src/chess/square.rs b/src/chess/square.rs index 8f785b4..471d6d6 100644 --- a/src/chess/square.rs +++ b/src/chess/square.rs @@ -29,7 +29,7 @@ impl Square { pub fn add_change(&self, change: &Change) -> Option { let x = self.x as i8 + change.ref_x(); let y = self.y as i8 + change.ref_y(); - if !(0..7).contains(&x) || !(0..7).contains(&y) { + if !(0..8).contains(&x) || !(0..8).contains(&y) { None } else { Some(Square::new(x as u8, y as u8)) diff --git a/src/main.rs b/src/main.rs index 3e9cda4..45174aa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ mod logging; fn main() { let config = get_config().unwrap_or_else(||panic!("")); - trace!("{:?}", config); + trace!("{:#?}", config); let mut board = Board::from_fen( // "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1".to_string() // start