From 0c4adba682202868253ecbc043370ffd6dda67d2 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Tue, 23 Jul 2024 11:22:50 +0200 Subject: [PATCH] test(solve): add test cases for naive and stupid solver --- src/game/mod.rs | 28 ++++++++++++++------ tests/solver.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 tests/solver.rs diff --git a/src/game/mod.rs b/src/game/mod.rs index bcbfdb3..b778469 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -29,7 +29,6 @@ where step: usize, solution: Option, wordlist: &'wl WL, - finished: bool, responses: Vec, // TODO: keep track of the letters the user has tried } @@ -50,8 +49,8 @@ impl<'wl, WL: WordList> Game<'wl, WL> { /// /// # Errors /// - /// This function will return an error if . - pub(crate) fn build( + /// No Errors + pub fn build( length: usize, precompute: bool, max_steps: usize, @@ -70,13 +69,17 @@ impl<'wl, WL: WordList> Game<'wl, WL> { None }, wordlist: wlist, - finished: false, responses: Vec::new(), }; Ok(game) } + /// set a solution, can be used for testing + pub fn set_solution(&mut self, sol: Option) { + self.solution = sol; + } + /// Make a new guess /// /// The word will be evaluated against the [solution](Game::solution) of the [Game]. @@ -93,7 +96,7 @@ impl<'wl, WL: WordList> Game<'wl, WL> { if guess.len() != self.length { return Err(GameError::GuessHasWrongLength(guess.len())); } - if self.finished || self.step > self.max_steps { + if self.finished() || self.step > self.max_steps { return Err(GameError::TryingToPlayAFinishedGame); } if self.wordlist.get_word(&guess).is_none() { @@ -110,7 +113,6 @@ impl<'wl, WL: WordList> Game<'wl, WL> { panic!("there is neither an evaluation nor a predefined solution for this guess"); } self.responses.push(response.clone()); - self.finished = response.finished(); Ok(response) } @@ -145,7 +147,17 @@ impl<'wl, WL: WordList> Game<'wl, WL> { } pub fn finished(&self) -> bool { - self.finished + if self.responses().is_empty() { + return false; + } + self.responses().last().unwrap().finished() + } + + pub fn won(&self) -> bool { + if self.responses().is_empty() { + return false; + } + self.responses().last().unwrap().won() } pub fn max_steps(&self) -> usize { @@ -182,7 +194,7 @@ impl<'wl, WL: WordList> Game<'wl, WL> { /// # use anyhow::Result; /// # fn main() -> Result<()> { /// let wl = BuiltinWList::default(); -/// let game: Game<_> = GameBuilder::new(&wl) +/// let game: Game<_> = GameBuilder::new(&wl, true) /// .build()?; /// # Ok(()) /// # } diff --git a/tests/solver.rs b/tests/solver.rs new file mode 100644 index 0000000..580ad97 --- /dev/null +++ b/tests/solver.rs @@ -0,0 +1,69 @@ +use wordle_analyzer::game::Game; +use wordle_analyzer::solve::{AnyBuiltinSolver, NaiveSolver, Solver, StupidSolver}; +use wordle_analyzer::wlist::builtin::BuiltinWList; +use wordle_analyzer::wlist::word::Word; +use wordle_analyzer::wlist::WordList; + +fn wordlist() -> impl WordList { + BuiltinWList::default() +} + +#[test] +fn test_build_builtin_solvers() { + let wl = wordlist(); + let stupid_solver = + AnyBuiltinSolver::Stupid(StupidSolver::build(&wl).expect("could not build naive solver")); + let naive_solver = + AnyBuiltinSolver::Naive(NaiveSolver::build(&wl).expect("could not build naive solver")); +} + +#[test] +fn test_naive_play_predetermined_game() -> anyhow::Result<()> { + let wl = wordlist(); + let sl = + AnyBuiltinSolver::Naive(NaiveSolver::build(&wl).expect("could not build naive solver")); + let mut game = Game::build(5, false, 6, &wl, false)?; + game.set_solution(Some(("nines".into(), 0.002))); // The accuracy is made up but shouldn't + // matter + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("which") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("their") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("being") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("since") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("lines") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("mines") + ); + sl.make_a_move(&mut game)?; + assert_eq!( + game.responses().last().unwrap().guess(), + &Word::from("wines") + ); + + // naive is at the moment too bad to solve "nines" + assert!(game.finished()); + assert!(!game.won()); + + Ok(()) +}