Files
scrabble-with-numbers/board-shared/src/game.rs

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()
}
}