generic solver
cargo devel CI / cargo CI (push) Successful in 42s Details

This commit is contained in:
Christoph J. Scherr 2024-03-22 15:43:41 +01:00
parent f24f83ad64
commit a5e22349f6
Signed by: cscherrNT
GPG Key ID: 8E2B45BC51A27EA7
4 changed files with 75 additions and 13 deletions

View File

@ -7,7 +7,7 @@ use libpt::log::*;
use wordle_analyzer::game::response::GuessResponse; use wordle_analyzer::game::response::GuessResponse;
use wordle_analyzer::solve::{stupid, BuiltinSolvers, Solver}; use wordle_analyzer::solve::{stupid, BuiltinSolverNames, NaiveSolver, Solver, StupidSolver};
use wordle_analyzer::wlist::builtin::BuiltinWList; use wordle_analyzer::wlist::builtin::BuiltinWList;
use wordle_analyzer::wlist::word::Word; use wordle_analyzer::wlist::word::Word;
use wordle_analyzer::{self, game}; use wordle_analyzer::{self, game};
@ -28,8 +28,8 @@ struct Cli {
#[arg(short, long)] #[arg(short, long)]
verbose: bool, verbose: bool,
/// which solver to use /// which solver to use
#[arg(short, long, default_value_t = BuiltinSolvers::default())] #[arg(short, long, default_value_t = BuiltinSolverNames::default())]
solver: BuiltinSolvers, solver: BuiltinSolverNames,
} }
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
@ -46,10 +46,7 @@ fn main() -> anyhow::Result<()> {
.length(cli.length) .length(cli.length)
.max_steps(cli.max_steps) .max_steps(cli.max_steps)
.precompute(cli.precompute); .precompute(cli.precompute);
let solver = match cli.solver { let solver = cli.solver.to_solver(&wl);
BuiltinSolvers::Naive => stupid::StupidSolver::build(&wl)?,
_ => todo!(),
};
let mut game = builder.build()?; let mut game = builder.build()?;
debug!("{game:#?}"); debug!("{game:#?}");

View File

@ -10,9 +10,11 @@ use crate::{
}; };
pub mod naive; pub mod naive;
pub use naive::NaiveSolver;
pub mod stupid; pub mod stupid;
pub use stupid::StupidSolver;
pub trait Solver<'wl, WL: WordList>: Clone + std::fmt::Debug { pub trait Solver<'wl, WL: WordList>: Clone + std::fmt::Debug + Sized {
fn build(wordlist: &'wl WL) -> WResult<Self>; fn build(wordlist: &'wl WL) -> WResult<Self>;
fn guess_for(&self, game: &Game<'wl, WL>) -> Word; fn guess_for(&self, game: &Game<'wl, WL>) -> Word;
fn play(&self, game: &mut Game<'wl, WL>) -> WResult<GuessResponse> { fn play(&self, game: &mut Game<'wl, WL>) -> WResult<GuessResponse> {
@ -34,17 +36,33 @@ pub trait Solver<'wl, WL: WordList>: Clone + std::fmt::Debug {
} }
Ok(Summary::from(games)) Ok(Summary::from(games))
} }
fn boxed(self) -> Box<Self> {
Box::new(self)
}
}
#[derive(Debug, Clone)]
pub enum AnyBuiltinSolver<'wl, WL: WordList> {
Naive(NaiveSolver<'wl, WL>),
Stupid(StupidSolver<'wl, WL>),
} }
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BuiltinSolvers { pub enum BuiltinSolverNames {
#[default] #[default]
Naive, Naive,
Stupid, Stupid,
} }
impl BuiltinSolverNames {
pub fn to_solver<'wl, WL: WordList>(&self, wl: &'wl WL) -> AnyBuiltinSolver<'wl, WL> {
match self {
Self::Naive => NaiveSolver::build(wl).unwrap().into(),
Self::Stupid => StupidSolver::build(wl).unwrap().into(),
}
}
}
impl FromStr for BuiltinSolvers { impl FromStr for BuiltinSolverNames {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() { match s.to_lowercase().as_str() {
@ -55,8 +73,20 @@ impl FromStr for BuiltinSolvers {
} }
} }
impl Display for BuiltinSolvers { impl Display for BuiltinSolverNames {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self) write!(f, "{:?}", self)
} }
} }
impl<'wl, WL: WordList> Solver<'wl, WL> for AnyBuiltinSolver<'wl, WL> {
fn build(wordlist: &'wl WL) -> WResult<Self> {
Ok(Self::Naive(NaiveSolver::build(wordlist)?))
}
fn guess_for(&self, game: &Game<'wl, WL>) -> Word {
match self {
Self::Naive(solver) => solver.guess_for(game),
Self::Stupid(solver) => solver.guess_for(game),
}
}
}

View File

@ -1 +1,27 @@
use libpt::log::info;
use crate::wlist::word::Word;
use crate::wlist::WordList;
use super::{AnyBuiltinSolver, Solver};
#[derive(Debug, Clone)]
pub struct NaiveSolver<'wl, WL> {
wl: &'wl WL,
}
impl<'wl, WL: WordList> Solver<'wl, WL> for NaiveSolver<'wl, WL> {
fn build(wordlist: &'wl WL) -> crate::error::WResult<Self> {
info!("using naive solver");
Ok(Self { wl: wordlist })
}
fn guess_for(&self, game: &crate::game::Game<WL>) -> Word {
self.wl.rand_word().0
}
}
impl<'wl, WL: WordList> From<NaiveSolver<'wl, WL>> for AnyBuiltinSolver<'wl, WL> {
fn from(value: NaiveSolver<'wl, WL>) -> Self {
Self::Naive(value)
}
}

View File

@ -1,7 +1,9 @@
use libpt::log::info;
use crate::wlist::word::Word; use crate::wlist::word::Word;
use crate::wlist::WordList; use crate::wlist::WordList;
use super::Solver; use super::{AnyBuiltinSolver, Solver};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StupidSolver<'wl, WL> { pub struct StupidSolver<'wl, WL> {
@ -10,9 +12,16 @@ pub struct StupidSolver<'wl, WL> {
impl<'wl, WL: WordList> Solver<'wl, WL> for StupidSolver<'wl, WL> { impl<'wl, WL: WordList> Solver<'wl, WL> for StupidSolver<'wl, WL> {
fn build(wordlist: &'wl WL) -> crate::error::WResult<Self> { fn build(wordlist: &'wl WL) -> crate::error::WResult<Self> {
info!("using stupid solver");
Ok(Self { wl: wordlist }) Ok(Self { wl: wordlist })
} }
fn guess_for(&self, game: &crate::game::Game<WL>) -> Word { fn guess_for(&self, game: &crate::game::Game<WL>) -> Word {
self.wl.rand_word().0 self.wl.rand_word().0
} }
} }
impl<'wl, WL: WordList> From<StupidSolver<'wl, WL>> for AnyBuiltinSolver<'wl, WL> {
fn from(value: StupidSolver<'wl, WL>) -> Self {
Self::Stupid(value)
}
}