diff --git a/src/game.rs b/src/game.rs index cf0edf8..cf7528a 100644 --- a/src/game.rs +++ b/src/game.rs @@ -565,10 +565,11 @@ impl Board { Some(MoveType::Capture) } None => { - // move is valid if it does not un-do the previous move + // move is valid if it does not un-do the previous move for this piece match self.moves.last() { Some(previous) => { - (previous.from != to).then_some(MoveType::Valid) + let is_undo = previous.from == to && previous.to == Some(from); + (!is_undo).then_some(MoveType::Valid) } // First move in the game, this is valid (and impossible) None => { @@ -701,6 +702,40 @@ mod test { assert_eq!(expected, given, "Empty moves"); } + #[test] + fn moves_multi_step() { + use super::*; + + let mut board = Board::from_ascii( + r#"........ + ........ + ....p... + ...p...."#, + ); + + // First assert that the piece can move + { + // The left side pawn can move to capture the right side pawn + let given = board.valid_moves((3, 0).into()); + let expected: HashSet = HashSet::from([(4, 1).into(), (2, 1).into()]); + assert_eq!(expected, given, "Sanity check"); + } + + // Next move the right side pawn + let _ = board.move_piece((4, 1).into(), (3, 2).into()); + + // Assert the spot is now empty + assert_eq!(board.at((4, 1).into()), None); + + // Now assert that the left side pawn can move into the spot taken by the right side pawn + { + // The left side pawn can move to capture the right side pawn + let given = board.valid_moves((3, 0).into()); + let expected: HashSet = HashSet::from([(4, 1).into(), (2, 1).into()]); + assert_eq!(expected, given, "Second step move"); + } + } + /// When a piece is blocked on all sides by friendly, cannot move #[test] fn blocking_friendly() {