use crate::board::Board; use crate::deck::{EmptyDeckError, RngDeck}; use crate::tile::{Digit, Tile}; #[derive(Default, Debug, Clone, PartialEq)] pub struct Game { pub board: Board, pub in_hand: Hand, } #[derive(Default, Debug, Clone, PartialEq)] pub struct Hand { pub tiles: Vec, } impl Hand { pub fn new(tiles: Vec) -> Self { Self { tiles } } pub fn count_missing_operators(&self) -> usize { 4usize.saturating_sub( self.tiles .iter() .filter(|tile| matches!(tile, Tile::Operator(_))) .count(), ) } pub fn count_missing_numbers(&self) -> usize { 8usize.saturating_sub( self.tiles .iter() .filter(|tile| matches!(tile, Tile::Digit(_))) .count(), ) } pub fn complete(&mut self, deck: &mut RngDeck) -> Result<(), EmptyDeckError> { for _ in 0..self.count_missing_operators() { self.tiles .push(Tile::Operator(deck.rand_operator().ok_or(EmptyDeckError)?)); } for _ in 0..self.count_missing_numbers() { self.tiles.push(Tile::Digit(Digit::new( deck.rand_digit().ok_or(EmptyDeckError)?, ))); } Ok(()) } pub fn push(&mut self, tile: Tile) { self.tiles.push(tile); } pub fn remove(&mut self, idx: usize) -> Option { (idx < self.tiles.len()).then(|| self.tiles.remove(idx)) } pub fn iter(&self) -> impl Iterator { self.tiles.iter() } }