116 lines
2.8 KiB
Rust
116 lines
2.8 KiB
Rust
use std::io;
|
|
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
use crate::{
|
|
pattern::{CharStatus, Pattern},
|
|
solver,
|
|
word_list::WordList,
|
|
};
|
|
|
|
static DEFAULT_VALID_WORDS: &str = include_str!("../../valid-words.txt");
|
|
static DEFAULT_ANSWERS: &str = include_str!("../../answers.txt");
|
|
|
|
#[wasm_bindgen]
|
|
struct Solver(solver::Solver);
|
|
|
|
#[wasm_bindgen]
|
|
pub enum Color {
|
|
GREY,
|
|
YELLOW,
|
|
GREEN,
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub struct WordStats(solver::WordStats);
|
|
|
|
#[allow(dead_code)]
|
|
#[wasm_bindgen]
|
|
impl WordStats {
|
|
#[wasm_bindgen(getter)]
|
|
pub fn word(&self) -> String {
|
|
self.0.word.clone()
|
|
}
|
|
#[wasm_bindgen(getter)]
|
|
pub fn solution_probability(&self) -> f64 {
|
|
self.0.solution_probability
|
|
}
|
|
#[wasm_bindgen(getter)]
|
|
pub fn expected_information_gained(&self) -> f64 {
|
|
self.0.expected_information_gained
|
|
}
|
|
#[wasm_bindgen(getter)]
|
|
pub fn expected_score_after_guess(&self) -> f64 {
|
|
self.0.expected_score_after_guess
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
#[wasm_bindgen]
|
|
impl Solver {
|
|
pub fn new(use_wordle_answers: bool) -> Result<Solver, String> {
|
|
let valid_words =
|
|
WordList::try_from(io::BufReader::new(io::Cursor::new(DEFAULT_VALID_WORDS)))?;
|
|
|
|
if use_wordle_answers {
|
|
let answers = WordList::try_from(io::BufReader::new(io::Cursor::new(DEFAULT_ANSWERS)))?;
|
|
Ok(Solver(solver::Solver::new(valid_words, answers)))
|
|
} else {
|
|
Ok(Solver(solver::Solver::new(
|
|
valid_words.clone(),
|
|
valid_words,
|
|
)))
|
|
}
|
|
}
|
|
|
|
pub fn guess(&mut self, word: &str, colors: Vec<Color>) -> Result<(), String> {
|
|
let pat = Pattern::try_new(
|
|
word,
|
|
colors
|
|
.iter()
|
|
.map(|c| match c {
|
|
Color::GREY => CharStatus::GREY,
|
|
Color::YELLOW => CharStatus::YELLOW,
|
|
Color::GREEN => CharStatus::GREEN,
|
|
})
|
|
.collect(),
|
|
)?;
|
|
|
|
self.0.apply_guess(pat)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn evaluate_words(
|
|
&self,
|
|
n: u32,
|
|
progress: js_sys::Function,
|
|
) -> Result<Vec<WordStats>, String> {
|
|
Ok(self
|
|
.0
|
|
.evaluate_all_words_cb(move |i, n| {
|
|
let _ = progress.call2(&JsValue::NULL, &JsValue::from(i), &JsValue::from(n));
|
|
})?
|
|
.into_iter()
|
|
.take(n as usize)
|
|
.map(|ws| WordStats(ws))
|
|
.collect())
|
|
}
|
|
|
|
pub fn guess_infos(&self) -> Vec<f64> {
|
|
self.0
|
|
.guesses()
|
|
.iter()
|
|
.map(|g| g.information_gained)
|
|
.collect()
|
|
}
|
|
|
|
pub fn solution_space(&self) -> u32 {
|
|
self.0.stats().0 as u32
|
|
}
|
|
|
|
pub fn solution_space_uncertainty(&self) -> f64 {
|
|
self.0.stats().1
|
|
}
|
|
}
|