diff --git a/src/solve/naive/mod.rs b/src/solve/naive/mod.rs index ea34d20..e824dde 100644 --- a/src/solve/naive/mod.rs +++ b/src/solve/naive/mod.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use libpt::log::{debug, info, trace}; +use libpt::log::{debug, error, info, trace}; use crate::error::{SolverError, WResult}; use crate::game::evaluation::{Evaluation, EvaluationUnit}; @@ -75,20 +75,29 @@ impl<'wl, WL: WordList> Solver<'wl, WL> for NaiveSolver<'wl, WL> { // get all words that have the correct chars on the same positions let mut matches: Vec = game.wordlist().get_words_matching(&pattern)?; if matches.is_empty() { + error!("no matches even when just considering the known good chars"); return Err(SolverError::NoMatches(game.solution().cloned()).into()); + } else { + trace!("found {} basic matches", matches.len()) } matches = matches .iter() // only words that have not been guessed yet .filter(|p| !game.made_guesses().contains(&&p.0)) .filter(|solution_candidate| { + if !game.responses().is_empty() + && !state.has_all_known_contained(&solution_candidate.0) + { + trace!("known cont:{:#?}", state.get_all_known_contained()); + return false; + } for (idx, c) in solution_candidate.0.char_indices() { let cinfo = state .char_map_mut() .entry(c) .or_insert(CharInfo::new(game.length())); - if !cinfo.part_of_solution() || cinfo.has_been_tried(idx) - // || !cinfo.occurences_of_char_possible(&solution_candidate.0, c) + if !cinfo.occurences_of_char_possible(&solution_candidate.0, c) + || cinfo.has_been_tried(idx) { return false; } diff --git a/src/solve/naive/states.rs b/src/solve/naive/states.rs index 76dac46..486d7e7 100644 --- a/src/solve/naive/states.rs +++ b/src/solve/naive/states.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use std::ops::{Range, RangeBounds}; use crate::error::WResult; +use crate::wlist::word::Word; pub(crate) type CharMap = HashMap; @@ -32,6 +33,22 @@ impl SolverState { pub fn char_map_mut(&mut self) -> &mut CharMap { &mut self.char_map } + + pub(crate) fn get_all_known_contained(&self) -> Vec<(&char, &CharInfo)> { + self.char_map + .iter() + .filter(|(key, value)| value.part_of_solution()) + .collect() + } + + pub(crate) fn has_all_known_contained(&self, guess: &Word) -> bool { + for needed_char in self.get_all_known_contained() { + if !guess.contains(*needed_char.0) { + return false; + } + } + true + } } impl CharInfo { @@ -62,7 +79,7 @@ impl CharInfo { #[must_use] pub fn part_of_solution(&self) -> bool { - self.occurences_amount.end > 0 + self.occurences_amount.start > 0 && self.occurences_amount.end > 0 } pub fn min_occurences(&mut self, min: usize) {