diff --git a/src/lib.rs b/src/lib.rs index c2076f9..e041f9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,14 +38,14 @@ struct LocatedPiece { file: usize, } -struct Board { +pub struct Board { white: Vec, black: Vec, white_to_move: bool, } impl Board { - fn new() -> Self { + pub fn new() -> Self { let white_pawns = (0..8) .map(|file| LocatedPiece { piece: Piece::Pawn, @@ -100,12 +100,8 @@ impl Board { .sum::(); white_value - black_value } - fn make_move(&mut self, algebra: &str) { - let (mover, non_mover) = if self.white_to_move { - (&mut self.white, &mut self.black) - } else { - (&mut self.black, &mut self.white) - }; + pub fn make_move(&mut self, algebra: &str) { + let (mover, non_mover) = self.movers_or_not(); if algebra == "O-O" || algebra == "0-0" { mover .iter_mut() @@ -134,10 +130,10 @@ impl Board { while let Some(ch) = iter.next() { if let Some(piece) = Piece::from_char(ch) { move_segments.push(MoveSegment::Piece(piece)); - } else if let Some(file) = ch.to_digit(10) { - move_segments.push(MoveSegment::File(file as usize)); + } else if let Some(rank) = ch.to_digit(10) { + move_segments.push(MoveSegment::File(rank as usize)); } else if ch >= 'a' && ch <= 'h' { - move_segments.push(MoveSegment::Rank(ch as usize)); + move_segments.push(MoveSegment::File(ch as usize - 'a' as usize)); } else if ch == 'x' { move_segments.push(MoveSegment::Captures) } else if ch == '=' @@ -147,8 +143,66 @@ impl Board { move_segments.push(MoveSegment::Promotion(piece)); } } + if move_segments.len() == 2 + && let MoveSegment::File(file) = move_segments[0] + && let MoveSegment::Rank(rank) = move_segments[1] + { + self.move_unambiguous(Piece::Pawn, None, None, rank, file); + } } } + fn move_unambiguous( + &mut self, + piece: Piece, + source_rank: Option, + source_file: Option, + dest_rank: usize, + dest_file: usize, + ) { + let piece_to_move = (if self.white_to_move { + &mut self.white + } else { + &mut self.black + }) + .iter_mut() + .filter(|lp| lp.piece == piece) + .filter(|lp| { + source_rank.is_none_or(|rank| rank == lp.rank) + && source_file.is_none_or(|file| file == lp.file) + }) + .find(|lp| self.valid_moves(lp).contains((dest_file, dest_rank))) + .unwrap(); + + self.capture_if_possible(dest_file, dest_rank); + piece_to_move.rank = dest_rank; + piece_to_move.file = dest_file; + } + fn valid_moves(&self, lp: LocatedPiece) -> Vec<(usize, usize)> { + let mut moves = vec![];j + match lp.piece { + Piece::Pawn => ,//todo: en passant (requires a list of moves to keep track of whether the previous + //move was one that is en passantable?) + Piece::Knight => todo!(), + Piece::Bishop => todo!(), + Piece::Rook => todo!(), + Piece::Queen => todo!(), + Piece::King => todo!(), + } + moves.retain(|(file, rank)| !self.mover_is_in_check(file, rank)); + moves + } + fn movers_or_not(&mut self) -> (&mut Vec, &mut Vec) { + if self.white_to_move { + (&mut self.white, &mut self.black) + } else { + (&mut self.black, &mut self.white) + } + } + fn capture_if_possible(&mut self, file: usize, rank: usize) { + self.movers_or_not() + .1 + .retain(|lp| lp.rank != rank && lp.file != file) + } } #[derive(Clone, Copy, PartialEq, Eq)]