word-engine/src/baggy.rs
2023-09-14 17:39:18 -04:00

73 lines
1.5 KiB
Rust

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<Tile>,
}
impl Bag {
pub fn take(&mut self, count: usize) -> Result<Bag, BagError> {
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::<usize>() % self.tiles.len());
tiles.push(random_tile);
}
Ok(Bag { tiles })
}
}
impl From<BagData> 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, "] }}")
}
}