use yahtzee_engine::{Solver, State};
fn debug_build() -> bool {
if cfg!(debug_assertions) {
eprintln!("skipped: run this tripwire with --release");
return true;
}
false
}
#[test]
#[ignore = "solves the full game; run with --release -- --ignored"]
fn optimal_ev_matches_the_forced_joker_value() {
if debug_build() {
return;
}
let mut solver = Solver::new();
solver.solve();
let value = solver.value(State::START);
assert!((value - 254.5877).abs() < 1e-3, "got {value}");
}
#[cfg(feature = "rand")]
mod empirical {
use super::debug_build;
use rand::SeedableRng;
use yahtzee_engine::{Game, HeuristicBot, OptimalBot, Strategy, play_game};
fn mean_score(strategy: &mut dyn Strategy, games: u32) -> f64 {
let mut rng = rand::rngs::StdRng::seed_from_u64(0x5EED);
let mut sum = 0.0;
for _ in 0..games {
let mut game = Game::new(1);
let total =
play_game(&mut game, &mut [strategy], &mut rng).expect("bots play legally")[0];
sum += f64::from(total);
}
sum / f64::from(games)
}
#[test]
#[ignore = "statistical tripwire; run with --release -- --ignored"]
fn heuristic_mean_score_clears_the_floor() {
if debug_build() {
return;
}
let mean = mean_score(&mut HeuristicBot::new(), 10_000);
assert!(mean >= 205.0, "heuristic mean dropped to {mean}");
}
#[test]
#[ignore = "solves the full game and simulates; run with --release -- --ignored"]
fn optimal_bot_scores_its_expected_value() {
if debug_build() {
return;
}
let mean = mean_score(&mut OptimalBot::presolved(), 2_000);
assert!((mean - 254.5877).abs() < 5.0, "optimal bot averaged {mean}");
}
}