64 lines
1.6 KiB
Rust
64 lines
1.6 KiB
Rust
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<Tile>,
|
|
}
|
|
|
|
impl Hand {
|
|
pub fn new(tiles: Vec<Tile>) -> 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<Tile> {
|
|
(idx < self.tiles.len()).then(|| self.tiles.remove(idx))
|
|
}
|
|
|
|
pub fn iter(&self) -> impl Iterator<Item = &Tile> {
|
|
self.tiles.iter()
|
|
}
|
|
}
|