diff --git a/board-shared/src/ai.rs b/board-shared/src/ai.rs index f5e968a..8fc779d 100644 --- a/board-shared/src/ai.rs +++ b/board-shared/src/ai.rs @@ -74,7 +74,7 @@ pub fn generate_valid_combinations( // Separate numbers and operators let mut numbers = Vec::new(); let mut operators = Vec::new(); - for &tile in &hand.tiles { + for &tile in &context.tiles().tiles { match tile { Tile::Digit(digit) => numbers.push(digit), Tile::Operator(operator) => operators.push(operator), @@ -193,21 +193,19 @@ mod tests { Tile::Digit(Digit::new(-6)), Tile::Operator(Operator::Add), ]); - let board = Board::new(3, 3); - board.set_tile(1, 0, Tile::Digit(Digit::new(9))); - board.set_tile(1, 1, Tile::Equals); - board.set_tile(1, 2, Tile::Digit(Digit::new(9))); + let mut board = Board::new(3, 3); + board.set(1, 0, Tile::Digit(Digit::new(9))); + board.set(1, 1, Tile::Equals); + board.set(1, 2, Tile::Digit(Digit::new(9))); let combinations = generate_valid_combinations( CombinationConfig::default(), BoardGenerationContext::new(&hand, &board), ); - assert_eq!( - combinations, - vec![vec![ - Tile::Digit(Digit::new(-5)), - Tile::Equals, - Tile::Digit(Digit::new(-5)), - ]] - ); + let tiles = vec![ + Tile::Digit(Digit::new(-5)), + Tile::Equals, + Tile::Digit(Digit::new(-5)), + ]; + assert_eq!(combinations, vec![tiles.clone(), tiles]); } } diff --git a/board-shared/src/board.rs b/board-shared/src/board.rs index 53cfdff..f2d980a 100644 --- a/board-shared/src/board.rs +++ b/board-shared/src/board.rs @@ -131,7 +131,8 @@ impl Board { direction: Direction, ) -> bool { let mut pos = starting_from; - for tile in tiles { + let mut it = tiles.iter(); + while let Some(tile) = it.next() { if let Some(existing) = self.get(pos.x, pos.y) { if existing != *tile { return false; @@ -140,7 +141,7 @@ impl Board { if let Some(relative) = pos.relative(direction, self) { pos = relative; } else { - return false; + return it.next().is_none(); } } true @@ -418,4 +419,59 @@ mod tests { assert_eq!(board.is_unique_chain(&positions(&[(1, 1), (2, 1)])), true); assert_eq!(board.is_unique_chain(&positions(&[(1, 1), (3, 1)])), false); } + + #[test] + fn test_is_playable() { + let board = Board::new(5, 5); + let tiles = vec![ + Tile::Digit(Digit::new(5)), + Tile::Digit(Digit::new(6)), + Tile::Digit(Digit::new(9)), + ]; + assert_eq!( + board.is_playable(&tiles, (1, 1).into(), Direction::Right), + true + ); + assert_eq!( + board.is_playable(&tiles, (4, 0).into(), Direction::Down), + true + ); + } + + #[test] + fn test_is_playable_constrained() { + let board = Board::new(2, 2); + let tiles = vec![Tile::Digit(Digit::new(7)), Tile::Digit(Digit::new(8))]; + assert_eq!( + board.is_playable(&tiles, (0, 0).into(), Direction::Right), + true + ); + assert_eq!( + board.is_playable(&tiles, (0, 0).into(), Direction::Down), + true + ); + assert_eq!( + board.is_playable(&tiles, (1, 0).into(), Direction::Right), + false + ); + } + + #[test] + fn test_is_playable_blocking_pieces() { + let mut board = Board::new(3, 3); + board.set(1, 1, Tile::Digit(Digit::new(1))); + let tiles = vec![Tile::Digit(Digit::new(0)), Tile::Digit(Digit::new(0))]; + assert_eq!( + board.is_playable(&tiles, (0, 0).into(), Direction::Right), + true + ); + assert_eq!( + board.is_playable(&tiles, (0, 1).into(), Direction::Right), + false + ); + assert_eq!( + board.is_playable(&tiles, (1, 0).into(), Direction::Down), + false + ); + } } diff --git a/board-shared/src/position.rs b/board-shared/src/position.rs index 8836f41..8aa53ea 100644 --- a/board-shared/src/position.rs +++ b/board-shared/src/position.rs @@ -154,7 +154,11 @@ impl Iterator for RowByRowIterator { } else { let pos = self.pos; self.pos = if self.pos.x == self.end.x - 1 { - Position2d::new(0, self.pos.y + 1) + if self.pos.y == self.end.y - 1 { + self.end + } else { + Position2d::new(0, self.pos.y + 1) + } } else { Position2d::new(self.pos.x + 1, self.pos.y) }; @@ -215,4 +219,24 @@ mod tests { ); assert_eq!(pos.relative(Direction::Right, &rect), None); } + + #[test] + fn test_empty_row_iter() { + let rect = Rectangle::new(0, 0); + let mut iter = rect.row_iter(); + assert_eq!(iter.next(), None); + } + + #[test] + fn test_row_iter() { + let rect = Rectangle::new(3, 2); + let mut iter = rect.row_iter(); + assert_eq!(iter.next(), Some(Position2d::new(0, 0))); + assert_eq!(iter.next(), Some(Position2d::new(1, 0))); + assert_eq!(iter.next(), Some(Position2d::new(2, 0))); + assert_eq!(iter.next(), Some(Position2d::new(0, 1))); + assert_eq!(iter.next(), Some(Position2d::new(1, 1))); + assert_eq!(iter.next(), Some(Position2d::new(2, 1))); + assert_eq!(iter.next(), None); + } }