use std::fmt::{self, Display, Formatter}; use thiserror::Error; use crate::data::BagData; #[derive(Error, Debug)] pub enum BagError { #[error("Not enough tiles")] NotEnoughTiles, } #[derive(Clone, Copy, Debug, PartialEq)] pub struct Tile { letter: char, value: u8, } impl Tile { pub fn letter(&self) -> char { self.letter } pub fn value(&self) -> u8 { self.value } } #[derive(Clone, Debug, PartialEq)] pub struct Bag { tiles: Vec, } impl Bag { pub fn take(&mut self, count: usize) -> Result { if count > self.tiles.len() { return Err(BagError::NotEnoughTiles); } let mut tiles = Vec::new(); for _ in 0..count { let random_tile = self .tiles .remove(rand::random::() % self.tiles.len()); tiles.push(random_tile); } Ok(Bag { tiles }) } } impl From for Bag { fn from(data: BagData) -> Self { let mut tiles = Vec::new(); for tile in data.tiles() { for _ in 0..tile.count() { tiles.push(Tile { letter: tile.letter(), value: tile.value(), }); } } Bag { tiles } } } impl Display for Bag { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "Bag {{ tiles: [")?; for tile in &self.tiles { write!(f, "{}, ", tile.letter)?; } write!(f, "] }}") } }