73 lines
1.5 KiB
Rust
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, "] }}")
|
|
}
|
|
}
|