yahtzee-engine 0.1.0

Yahtzee rules, scoring, and bots: a fast heuristic and an exact optimal expected-value solver
Documentation
//! Solver and bot decision latency.

use criterion::{BatchSize, Criterion, criterion_group, criterion_main};
use std::hint::black_box;
use yahtzee_engine::{Category, Dice, Game, Solver, State, Strategy, TurnAction};

/// A late-game state with six categories open: a realistic advisor query.
fn endgame() -> State {
    let open = Category::Sixes
        .bit()
        .with(Category::ThreeOfAKind)
        .with(Category::FullHouse)
        .with(Category::SmallStraight)
        .with(Category::Yahtzee)
        .with(Category::Chance);
    State::new(!open, 45, false)
}

fn dice(s: &str) -> Dice {
    s.parse().expect("a valid roll")
}

fn solver_benches(c: &mut Criterion) {
    let mut group = c.benchmark_group("solve");
    group.sample_size(10);
    group.bench_function("six_open_cone", |b| {
        b.iter_batched(
            Solver::new,
            |mut solver| solver.value(black_box(endgame())),
            BatchSize::LargeInput,
        );
    });
    group.finish();

    let mut solver = Solver::new();
    solver.value(endgame());
    c.bench_function("best_action_solved", |b| {
        b.iter(|| solver.best_action(black_box(endgame()), black_box(dice("35556")), 2));
    });
}

fn heuristic_benches(c: &mut Criterion) {
    let mut game = Game::new(1);
    game.roll(dice("35556")).expect("first roll");
    let mut bot = yahtzee_engine::HeuristicBot::new();
    c.bench_function("heuristic_action", |b| {
        b.iter(|| -> TurnAction { bot.choose_action(black_box(&game.view())) });
    });
}

criterion_group!(benches, solver_benches, heuristic_benches);
criterion_main!(benches);