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

76 lines
1.9 KiB
Rust

use crate::tile::{Operator, Tile};
/// Calculate the score for a given list of tiles.
pub fn calc_score(tiles: &[Tile]) -> u32 {
tiles
.split(|tile| matches!(tile, Tile::Equals))
.map(calc_expression_score)
.sum()
}
fn calc_expression_score(tiles: &[Tile]) -> u32 {
let mut digit_score = 0u32;
let mut multiplier = 1u32;
for token in tiles {
match token {
Tile::Digit(_) => digit_score += 1,
Tile::Operator(Operator::Add | Operator::Subtract) => multiplier = 2,
Tile::Operator(Operator::Multiply) => multiplier = 3,
Tile::Operator(Operator::Divide) => digit_score += 10,
Tile::Equals => unreachable!(),
}
}
digit_score * multiplier
}
#[cfg(test)]
mod tests {
use crate::tile::Digit;
use super::*;
#[test]
fn only_digits() {
assert_eq!(
calc_score(&[
Tile::Digit(Digit::new(7)),
Tile::Digit(Digit::new(8)),
Tile::Equals,
Tile::Digit(Digit::new(9)),
Tile::Digit(Digit::new(4)),
]),
4
);
}
#[test]
fn calc_individually() {
assert_eq!(
calc_score(&[
Tile::Digit(Digit::new(4)),
Tile::Operator(Operator::Add),
Tile::Digit(Digit::new(5)),
Tile::Equals,
Tile::Digit(Digit::new(3)),
Tile::Operator(Operator::Multiply),
Tile::Digit(Digit::new(3)),
]),
10
);
}
#[test]
fn diviser_add_to_original_sum() {
assert_eq!(
calc_score(&[
Tile::Digit(Digit::new(8)),
Tile::Operator(Operator::Divide),
Tile::Digit(Digit::new(4)),
Tile::Equals,
Tile::Digit(Digit::new(2)),
]),
13
);
}
}