From 45289ac8abdab788d3484e5c2d1de50018ceabd0 Mon Sep 17 00:00:00 2001 From: ashastral Date: Sun, 27 Feb 2022 12:40:36 -0800 Subject: [PATCH] separate into packages & start on actual game --- Cargo.lock | 249 ++++++++++++++++++++- Cargo.toml | 15 +- optimle/Cargo.toml | 13 ++ optimle/src/lib.rs | 90 ++++++++ optimle/src/main.rs | 10 + src/main.rs | 52 ----- web-optimle/Cargo.toml | 23 ++ web-optimle/src/lib.rs | 0 wordlelike/Cargo.toml | 11 + {src => wordlelike/src}/constraints.rs | 0 {src => wordlelike/src}/evaluator.rs | 6 +- {src => wordlelike/src}/game.rs | 9 +- {src => wordlelike/src}/guess.rs | 3 +- {src => wordlelike/src}/guesser.rs | 16 +- wordlelike/src/lib.rs | 8 + wordlelike/src/load.rs | 11 + wordlelike/src/macros.rs | 12 + wordlelike/src/main.rs | 26 +++ {src => wordlelike/src}/words/common.txt | 0 {src => wordlelike/src}/words/uncommon.txt | 0 20 files changed, 482 insertions(+), 72 deletions(-) create mode 100644 optimle/Cargo.toml create mode 100644 optimle/src/lib.rs create mode 100644 optimle/src/main.rs delete mode 100644 src/main.rs create mode 100644 web-optimle/Cargo.toml create mode 100644 web-optimle/src/lib.rs create mode 100644 wordlelike/Cargo.toml rename {src => wordlelike/src}/constraints.rs (100%) rename {src => wordlelike/src}/evaluator.rs (96%) rename {src => wordlelike/src}/game.rs (81%) rename {src => wordlelike/src}/guess.rs (98%) rename {src => wordlelike/src}/guesser.rs (72%) create mode 100644 wordlelike/src/lib.rs create mode 100644 wordlelike/src/load.rs create mode 100644 wordlelike/src/macros.rs create mode 100644 wordlelike/src/main.rs rename {src => wordlelike/src}/words/common.txt (100%) rename {src => wordlelike/src}/words/uncommon.txt (100%) diff --git a/Cargo.lock b/Cargo.lock index 05f2507..b243bfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,34 +2,88 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "bumpalo" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + [[package]] name = "getrandom" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi", ] +[[package]] +name = "js-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "optimle" version = "0.1.0" dependencies = [ "rand", + "rand_chacha", + "wordlelike", ] [[package]] @@ -38,6 +92,24 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.8.5" @@ -68,8 +140,183 @@ dependencies = [ "getrandom", ] +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "syn" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c8d417d87eefa0087e62e3c75ad086be39433449e2961add9a5d9ce5acc2f1" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0e560d44db5e73b69a9757a15512fe7e1ef93ed2061c928871a4025798293dd" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "web-optimle" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "optimle", + "wasm-bindgen", + "wasm-bindgen-test", + "wee_alloc", +] + +[[package]] +name = "web-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wordlelike" +version = "0.1.0" +dependencies = [ + "rand", +] diff --git a/Cargo.toml b/Cargo.toml index 951566d..c9eee2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,6 @@ -[package] -name = "optimle" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = "0.8.5" \ No newline at end of file +[workspace] +members = [ + "wordlelike", + "optimle", + "web-optimle", +] \ No newline at end of file diff --git a/optimle/Cargo.toml b/optimle/Cargo.toml new file mode 100644 index 0000000..0af7831 --- /dev/null +++ b/optimle/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "optimle" +version = "0.1.0" +authors = ["ashastral"] +edition = "2018" + +[lib] +crate-type = ["rlib"] + +[dependencies] +rand = "0.8.5" +rand_chacha = "0.3.1" +wordlelike = { path = "../wordlelike" } \ No newline at end of file diff --git a/optimle/src/lib.rs b/optimle/src/lib.rs new file mode 100644 index 0000000..15bbcdd --- /dev/null +++ b/optimle/src/lib.rs @@ -0,0 +1,90 @@ +use rand_chacha::ChaCha8Rng; +use rand_chacha::rand_core::SeedableRng; +use rand::seq::SliceRandom; + +use wordlelike::constraints; +use wordlelike::constraints::Constraints; +use wordlelike::evaluator; +use wordlelike::evaluator::Evaluator; +use wordlelike::game; +use wordlelike::guess::*; +use wordlelike::guesser; + +pub struct Puzzle { + pub history: GuessHistory, +} + +impl Puzzle { + pub fn new(dictionary: &Dictionary, seed: u64) -> Self { + let mut rng: ChaCha8Rng = ChaCha8Rng::seed_from_u64(seed); + let mut history: Option> = None; + loop { + let initial_secret = dictionary.choose(&mut rng).unwrap(); + let constraints = &mut constraints::Total::new(); + let mut game = game::Game { + evaluator: &mut evaluator::SecretEvaluator::new(*initial_secret), + guesser: &mut guesser::RandomConstraintGuesser::new(dictionary, constraints, &mut rng), + }; + let mut game_history = Vec::new(); + loop { + let result = game.play_round(); + if result.correct() { break; } + game.push(result); + game_history.push(result); + if game_history.len() > 2 { + if result.matches + .iter() + .filter(|&m| *m == LetterMatch::HERE) + .count() < 3 { + continue; + } + let possible_words = game.guesser.get_possible_words(); + if Puzzle::interesting(dictionary, &game_history, possible_words) { + history = Some(game_history); + break; + } + } + } + if history.is_some() { break; } + } + Self { + history: history.unwrap(), + } + } + + fn interesting(dictionary: &Dictionary, history: &GuessHistory, possible_words: Dictionary) -> bool { + let count = possible_words.len(); + if count < 3 || count > 6 { + return false; + } + + let base_constraints = &mut constraints::Total::new(); + let constraints = &mut constraints::Total::new(); + let mut evaluator = evaluator::AdversarialEvaluator::new(dictionary); + for &result in history { + base_constraints.push(result); + evaluator.push(result); + } + + let mut solutions = Vec::new(); + for &word in dictionary { + constraints.clone_from(base_constraints); + let matches = evaluator.evaluate(word); + constraints.push(GuessResult { word, matches }); + let remaining_words = possible_words + .iter() + .filter(|&word| constraints.check(*word)) + .count(); + if remaining_words == 1 { + solutions.push(word); + } + } + + let solution_count = solutions.len(); + let interesting = solution_count > 0 && solution_count <= 100; + if interesting { + println!("Could be: {:?}", possible_words); + } + interesting + } +} \ No newline at end of file diff --git a/optimle/src/main.rs b/optimle/src/main.rs new file mode 100644 index 0000000..98aa0ef --- /dev/null +++ b/optimle/src/main.rs @@ -0,0 +1,10 @@ +use optimle::Puzzle; +use wordlelike::guess::*; + +fn main() { + let common_words: Vec> = wordlelike::load::load_words(include_str!("../../wordlelike/src/words/common.txt")); + let puzzle = Puzzle::new(&common_words, 0); + for result in puzzle.history { + println!("{}", result); + } +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 24c7792..0000000 --- a/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::convert::TryInto; - -#[macro_export] -macro_rules! word { - ( $x:expr ) => { - { - $x.chars() - .collect::>() - .as_slice() - .try_into() - .unwrap() - } - } -} - -mod guess; -use guess::*; - -mod constraints; -mod game; -mod guesser; -mod evaluator; - - -fn play(dictionary: &Dictionary) { - let mut constraints = constraints::Total::new(); - let mut game = game::Game { - evaluator: &mut evaluator::AdversarialEvaluator::new(dictionary), - guesser: &mut guesser::RandomConstraintGuesser::new(dictionary, &mut constraints), - }; - loop { - let result = game.next(); - println!("{}", result); - if result.correct() { - return - } - } -} - -fn load_words(contents: &'static str) -> Vec> { - contents - .split("\n") - .map(|line| word!(line)) - .collect::>() -} - -fn main() { - let common_words: Vec> = load_words(include_str!("words/common.txt")); - loop { - play(&common_words); - } -} diff --git a/web-optimle/Cargo.toml b/web-optimle/Cargo.toml new file mode 100644 index 0000000..e8a18ab --- /dev/null +++ b/web-optimle/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "web-optimle" +version = "0.1.0" +authors = ["ashastral"] +edition = "2018" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["console_error_panic_hook"] + +[dependencies] +wasm-bindgen = "0.2.63" +console_error_panic_hook = { version = "0.1.6", optional = true } +wee_alloc = { version = "0.4.5", optional = true } +optimle = { path = "../optimle" } + +[dev-dependencies] +wasm-bindgen-test = "0.3.13" + +[profie.release] +opt-level = "s" diff --git a/web-optimle/src/lib.rs b/web-optimle/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/wordlelike/Cargo.toml b/wordlelike/Cargo.toml new file mode 100644 index 0000000..950f3d2 --- /dev/null +++ b/wordlelike/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "wordlelike" +version = "0.1.0" +authors = ["ashastral"] +edition = "2018" + +[lib] +crate-type = ["rlib"] + +[dependencies] +rand = "0.8.5" diff --git a/src/constraints.rs b/wordlelike/src/constraints.rs similarity index 100% rename from src/constraints.rs rename to wordlelike/src/constraints.rs diff --git a/src/evaluator.rs b/wordlelike/src/evaluator.rs similarity index 96% rename from src/evaluator.rs rename to wordlelike/src/evaluator.rs index a3652d4..97ab783 100644 --- a/src/evaluator.rs +++ b/wordlelike/src/evaluator.rs @@ -1,4 +1,3 @@ -use std::convert::TryInto; use std::collections::HashSet; use crate::guess::*; @@ -14,6 +13,7 @@ pub struct SecretEvaluator { secret: Word, } +/// Evaluates guesses according to the provided secret word. impl SecretEvaluator { pub fn new(secret: Word) -> Self { Self { @@ -28,6 +28,9 @@ impl Evaluator for SecretEvaluator { } } + +/// Evaluates guesses "adversarially", that is, in a way that maximizes the +/// remaining search space after each guess. pub struct AdversarialEvaluator { possible_words: Dictionary, constraints: constraints::Total, @@ -84,6 +87,7 @@ impl Evaluator for AdversarialEvaluator { #[cfg(test)] mod tests { use super::*; + use std::convert::TryInto; #[test] fn it_evaluates_adversarially() { diff --git a/src/game.rs b/wordlelike/src/game.rs similarity index 81% rename from src/game.rs rename to wordlelike/src/game.rs index 64e1402..74070a1 100644 --- a/src/game.rs +++ b/wordlelike/src/game.rs @@ -8,12 +8,15 @@ pub struct Game<'a, const N: usize> { } impl<'a, const N: usize> Game<'a, N> { - pub fn next(&mut self) -> GuessResult { + pub fn play_round(&mut self) -> GuessResult { let word = self.guesser.guess(); let matches = self.evaluator.evaluate(word); let result = GuessResult { word, matches }; - self.guesser.push(result); - self.evaluator.push(result); result } + + pub fn push(&mut self, result: GuessResult) { + self.guesser.push(result); + self.evaluator.push(result); + } } diff --git a/src/guess.rs b/wordlelike/src/guess.rs similarity index 98% rename from src/guess.rs rename to wordlelike/src/guess.rs index b1116c4..ff2daf2 100644 --- a/src/guess.rs +++ b/wordlelike/src/guess.rs @@ -1,5 +1,3 @@ -use std::convert::TryInto; - #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum LetterMatch { NOWHERE, @@ -77,6 +75,7 @@ pub type Dictionary = Vec>; #[cfg(test)] mod tests { use super::*; + use std::convert::TryInto; #[test] fn it_matches_correct_guess() { diff --git a/src/guesser.rs b/wordlelike/src/guesser.rs similarity index 72% rename from src/guesser.rs rename to wordlelike/src/guesser.rs index 7a4bba6..0ee302d 100644 --- a/src/guesser.rs +++ b/wordlelike/src/guesser.rs @@ -1,35 +1,39 @@ use rand::seq::SliceRandom; - +use rand::RngCore; use crate::guess::*; use crate::constraints; pub trait Guesser { fn push(&mut self, _result: GuessResult) {} - fn guess(&self) -> Word; + fn guess(&mut self) -> Word; + fn get_possible_words(&self) -> Dictionary; } pub struct RandomConstraintGuesser<'a, const N: usize> { possible_words: Dictionary, history: GuessHistory, constraints: &'a mut dyn constraints::Constraints, + rng: &'a mut dyn RngCore, } impl<'a, const N: usize> RandomConstraintGuesser<'a, N> { pub fn new( dictionary: &Dictionary, constraints: &'a mut dyn constraints::Constraints, + rng: &'a mut dyn RngCore, ) -> Self { Self { possible_words: dictionary.to_vec(), history: GuessHistory::new(), constraints, + rng, } } } impl<'a, const N: usize> Guesser for RandomConstraintGuesser<'a, N> { - fn guess(&self) -> Word { - *self.possible_words.choose(&mut rand::thread_rng()).unwrap() + fn guess(&mut self) -> Word { + *self.possible_words.choose(&mut self.rng).unwrap() } fn push(&mut self, result: GuessResult) { @@ -38,4 +42,8 @@ impl<'a, const N: usize> Guesser for RandomConstraintGuesser<'a, N> { let constraints = &self.constraints; self.possible_words.retain(|&word| constraints.check(word)); } + + fn get_possible_words(&self) -> Dictionary { + return self.possible_words.to_vec(); + } } diff --git a/wordlelike/src/lib.rs b/wordlelike/src/lib.rs new file mode 100644 index 0000000..cc86ba8 --- /dev/null +++ b/wordlelike/src/lib.rs @@ -0,0 +1,8 @@ +#[macro_use] +pub mod macros; +pub mod guess; +pub mod constraints; +pub mod game; +pub mod guesser; +pub mod evaluator; +pub mod load; \ No newline at end of file diff --git a/wordlelike/src/load.rs b/wordlelike/src/load.rs new file mode 100644 index 0000000..2204ef3 --- /dev/null +++ b/wordlelike/src/load.rs @@ -0,0 +1,11 @@ +use std::convert::TryInto; + +use crate::guess::*; + + +pub fn load_words(contents: &'static str) -> Vec> { + contents + .split("\n") + .map(|line| word!(line)) + .collect::>() +} diff --git a/wordlelike/src/macros.rs b/wordlelike/src/macros.rs new file mode 100644 index 0000000..2386ff4 --- /dev/null +++ b/wordlelike/src/macros.rs @@ -0,0 +1,12 @@ +#[macro_export] +macro_rules! word { + ( $x:expr ) => { + { + $x.chars() + .collect::>() + .as_slice() + .try_into() + .unwrap() + } + } +} \ No newline at end of file diff --git a/wordlelike/src/main.rs b/wordlelike/src/main.rs new file mode 100644 index 0000000..6aec998 --- /dev/null +++ b/wordlelike/src/main.rs @@ -0,0 +1,26 @@ +use wordlelike::*; +use wordlelike::guess::*; + +fn play(dictionary: &Dictionary) { + let mut constraints = constraints::Total::new(); + let mut rng = rand::thread_rng(); + let mut game = game::Game { + evaluator: &mut evaluator::AdversarialEvaluator::new(dictionary), + guesser: &mut guesser::RandomConstraintGuesser::new(dictionary, &mut constraints, &mut rng), + }; + loop { + let result = game.play_round(); + println!("{}", result); + if result.correct() { + return + } + game.push(result); + } +} + +fn main() { + let common_words: Vec> = load::load_words(include_str!("words/common.txt")); + loop { + play(&common_words); + } +} diff --git a/src/words/common.txt b/wordlelike/src/words/common.txt similarity index 100% rename from src/words/common.txt rename to wordlelike/src/words/common.txt diff --git a/src/words/uncommon.txt b/wordlelike/src/words/uncommon.txt similarity index 100% rename from src/words/uncommon.txt rename to wordlelike/src/words/uncommon.txt