initial commit
This commit is contained in:
commit
592dd1473d
11 changed files with 818817 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
*.iml
|
150
Cargo.lock
generated
Normal file
150
Cargo.lock
generated
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ansi_term"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0005d08a8f7b65fb8073cb697aa0b12b631ed251ce73d862ce50eeb52ce3b50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
"rand_hc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_hc"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.10.2+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||||
|
|
||||||
|
[[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 = "wordle"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term",
|
||||||
|
"rand",
|
||||||
|
"regex",
|
||||||
|
]
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "wordle"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ansi_term = "0.12.1"
|
||||||
|
rand = "0.8.4"
|
||||||
|
regex = "1.5.4"
|
72325
dictionaries/ignore/Oxford English Dictionary.txt
Normal file
72325
dictionaries/ignore/Oxford English Dictionary.txt
Normal file
File diff suppressed because it is too large
Load diff
349900
dictionaries/ignore/dictionary.txt
Normal file
349900
dictionaries/ignore/dictionary.txt
Normal file
File diff suppressed because it is too large
Load diff
370103
dictionaries/ignore/words_alpha.txt
Normal file
370103
dictionaries/ignore/words_alpha.txt
Normal file
File diff suppressed because it is too large
Load diff
12971
dictionaries/output/five_letter_words.txt
Normal file
12971
dictionaries/output/five_letter_words.txt
Normal file
File diff suppressed because it is too large
Load diff
12974
dictionaries/worlde.txt
Normal file
12974
dictionaries/worlde.txt
Normal file
File diff suppressed because it is too large
Load diff
194
src/main.rs
Normal file
194
src/main.rs
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use regex::Regex;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::fs::{read_dir, File, OpenOptions};
|
||||||
|
use std::io::{stdin, BufRead, BufReader, Write};
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
mod wordle;
|
||||||
|
|
||||||
|
use utils::str_unique_by_characters;
|
||||||
|
use wordle::{worlde_game_make_guess, WordleState};
|
||||||
|
|
||||||
|
fn generate_wordle_dictionary() -> HashSet<String> {
|
||||||
|
let existing_path = "./dictionaries/output/five_letter_words.txt";
|
||||||
|
let existing = File::open(&existing_path);
|
||||||
|
let paths: Vec<_> = read_dir("./dictionaries")
|
||||||
|
.unwrap()
|
||||||
|
.map(|p| p.unwrap())
|
||||||
|
.filter(|p| p.file_type().unwrap().is_file())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Only regenerate five letter word dictionary if there are new or changed dictionaries
|
||||||
|
let regenerate = existing.map_or(true, |e| {
|
||||||
|
let modified = e.metadata().unwrap().modified().unwrap();
|
||||||
|
paths
|
||||||
|
.iter()
|
||||||
|
.any(|dict| dict.metadata().unwrap().modified().unwrap().gt(&modified))
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("Regenerating five letter word dictionary: {}", regenerate);
|
||||||
|
let mut five_letter_words = HashSet::new();
|
||||||
|
if regenerate {
|
||||||
|
let _ = File::create(&existing_path); // create if not exist
|
||||||
|
let mut f_writer = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(&existing_path)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let five_re = Regex::new(r"^(\w{5})(?:\s|$)").unwrap();
|
||||||
|
paths.iter().for_each(|p| {
|
||||||
|
println!("Loading five letter words from: {}", p.path().display());
|
||||||
|
|
||||||
|
let f = File::open(p.path()).unwrap();
|
||||||
|
let f = BufReader::new(f);
|
||||||
|
f.lines().map(|l| l.unwrap()).for_each(|line| {
|
||||||
|
match five_re.captures(&line) {
|
||||||
|
Some(x) => {
|
||||||
|
let word = x.get(1).unwrap().as_str().to_uppercase();
|
||||||
|
// println!("Capture: {} from {}", word, line);
|
||||||
|
five_letter_words.insert(word.clone());
|
||||||
|
f_writer.write(format!("{}\n", &word).as_ref()).unwrap();
|
||||||
|
}
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
f_writer.flush().unwrap();
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"Loading five letter word dictionary from: {}",
|
||||||
|
&existing_path
|
||||||
|
);
|
||||||
|
let dictionary_f = File::open(&existing_path).unwrap();
|
||||||
|
let dictionary_f = BufReader::new(dictionary_f);
|
||||||
|
dictionary_f.lines().for_each(|l| {
|
||||||
|
five_letter_words.insert(l.unwrap());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
five_letter_words
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_input(prompt: &str) -> String {
|
||||||
|
let mut input = String::new();
|
||||||
|
println!("{prompt}");
|
||||||
|
stdin()
|
||||||
|
.read_line(&mut input)
|
||||||
|
.expect("Failed to read input.");
|
||||||
|
input.trim().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let wordle_dict = generate_wordle_dictionary();
|
||||||
|
// println!("Wordle dict size: {}", wordle_dict.len());
|
||||||
|
|
||||||
|
let unique_words: Vec<_> = wordle_dict
|
||||||
|
.iter()
|
||||||
|
.filter(|x| str_unique_by_characters(x))
|
||||||
|
.map(|w| w)
|
||||||
|
.collect();
|
||||||
|
let worlde_answer = unique_words.choose(&mut rand::thread_rng()).unwrap();
|
||||||
|
|
||||||
|
let mut wordle_game_state = WordleState::new(worlde_answer.as_str());
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut input;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
input = get_input("Guess a word:").to_uppercase();
|
||||||
|
|
||||||
|
if input.len() == 5 && wordle_dict.contains(&input) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.eq("!ANS") || input.eq("!ANSWER") {
|
||||||
|
println!("Answer: {worlde_answer}");
|
||||||
|
} else {
|
||||||
|
println!("Invalid input {input}, try a different one...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worlde_game_make_guess(input.as_ref(), &mut wordle_game_state);
|
||||||
|
print!("Board:\n{}", wordle_game_state);
|
||||||
|
if wordle_game_state.game_over() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match wordle_game_state.won() {
|
||||||
|
true => println!("YOU WON!"),
|
||||||
|
false => println!("YOU LOST!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let data = "Some data!";
|
||||||
|
let f = File::create("/tmp/foo").expect("Unable to create file");
|
||||||
|
let mut f = BufWriter::new(f);
|
||||||
|
f.write_all(data.as_bytes()).expect("Unable to write data");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
fn extract_login(input: &str) -> Option<&str> {
|
||||||
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new(r"(?x)
|
||||||
|
^(?P<login>[^@\s]+)@
|
||||||
|
([[:word:]]+\.)*
|
||||||
|
[[:word:]]+$
|
||||||
|
").unwrap();
|
||||||
|
}
|
||||||
|
RE.captures(input).and_then(|cap| {
|
||||||
|
cap.name("login").map(|login| login.as_str())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(extract_login(r"I❤email@example.com"), Some(r"I❤email"));
|
||||||
|
assert_eq!(
|
||||||
|
extract_login(r"sdf+sdsfsd.as.sdsd@jhkk.d.rl"),
|
||||||
|
Some(r"sdf+sdsfsd.as.sdsd")
|
||||||
|
);
|
||||||
|
assert_eq!(extract_login(r"More@Than@One@at.com"), None);
|
||||||
|
assert_eq!(extract_login(r"Not an email@email"), None);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f = File::open("/etc/hosts").expect("Unable to open file");
|
||||||
|
let f = BufReader::new(f);
|
||||||
|
|
||||||
|
for line in f.lines() {
|
||||||
|
let line = line.expect("Unable to read line");
|
||||||
|
println!("Line: {}", line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let paths = fs::read_dir("./").unwrap();
|
||||||
|
|
||||||
|
for path in paths {
|
||||||
|
println!("Name: {}", path.unwrap().path().display())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
22
src/utils.rs
Normal file
22
src/utils.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
pub fn str_unique_by_characters(s: &str) -> bool {
|
||||||
|
s.chars()
|
||||||
|
.enumerate()
|
||||||
|
.find_map(|(i, c)| {
|
||||||
|
s.chars()
|
||||||
|
.enumerate()
|
||||||
|
.skip(i + 1)
|
||||||
|
.find(|(_, other)| c == *other)
|
||||||
|
.map(|(j, _)| (i, j, c))
|
||||||
|
})
|
||||||
|
.is_none()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn str_to_five_char(s: &str) -> [char; 5] {
|
||||||
|
s.chars()
|
||||||
|
.take(5)
|
||||||
|
.enumerate()
|
||||||
|
.fold([' '; 5], |mut arr, (i, c)| {
|
||||||
|
arr[i] = c;
|
||||||
|
arr
|
||||||
|
})
|
||||||
|
}
|
165
src/wordle.rs
Normal file
165
src/wordle.rs
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
use ansi_term::Color::{Green, Yellow, RGB};
|
||||||
|
use ansi_term::Colour;
|
||||||
|
use std::fmt;
|
||||||
|
use std::fmt::Formatter;
|
||||||
|
|
||||||
|
use crate::utils::str_to_five_char;
|
||||||
|
|
||||||
|
const GRAY: Colour = RGB(188, 188, 188);
|
||||||
|
const DARK_GRAY: Colour = RGB(117, 117, 117);
|
||||||
|
|
||||||
|
#[derive(Copy, PartialEq, Debug)]
|
||||||
|
pub enum CharState {
|
||||||
|
EXCLUDES,
|
||||||
|
CONTAINS,
|
||||||
|
POSITIONED,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for CharState {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
CharState::EXCLUDES => CharState::EXCLUDES,
|
||||||
|
CharState::CONTAINS => CharState::CONTAINS,
|
||||||
|
CharState::POSITIONED => CharState::POSITIONED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WordleState {
|
||||||
|
word: [char; 5],
|
||||||
|
guesses: [Option<[char; 5]>; 5],
|
||||||
|
guess_states: [Option<[CharState; 5]>; 5],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WordleState {
|
||||||
|
pub fn new(word: &str) -> Self {
|
||||||
|
WordleState {
|
||||||
|
word: str_to_five_char(word),
|
||||||
|
guesses: [None; 5],
|
||||||
|
guess_states: [None; 5],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_turn(&self) -> Option<usize> {
|
||||||
|
self.guesses.iter().position(|guess| guess.is_none())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn game_over(&self) -> bool {
|
||||||
|
self.get_turn().is_none() || self.won()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn won(&self) -> bool {
|
||||||
|
let last_index = self.get_turn().map(|t| t - 1).unwrap_or(4);
|
||||||
|
!self.guess_states[last_index]
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.any(|s| !CharState::POSITIONED.eq(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_guess(&mut self, index: usize, guess: [char; 5]) {
|
||||||
|
self.guesses[index] = Option::from(guess);
|
||||||
|
self.calculate_guess_states(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn calculate_missing_guess_states(&mut self) {
|
||||||
|
// self.calculate_guess_states(true)
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn calculate_guess_states(&mut self, skip_existing: bool) {
|
||||||
|
self.guesses.iter().enumerate().for_each(|(i, g)| {
|
||||||
|
if g.is_some() && (!skip_existing || self.guess_states[i].is_none()) {
|
||||||
|
// EXCLUDES is default so anything at the end is considered excluded
|
||||||
|
let mut guess_state = [CharState::EXCLUDES; 5];
|
||||||
|
let mut guess = g.unwrap().map(|c| Option::from(c));
|
||||||
|
let mut word = self.word.map(|c| Option::from(c));
|
||||||
|
|
||||||
|
// POSITIONED
|
||||||
|
for char_index in 0..5 {
|
||||||
|
if guess[char_index].unwrap() == word[char_index].unwrap() {
|
||||||
|
guess[char_index] = None;
|
||||||
|
word[char_index] = None;
|
||||||
|
guess_state[char_index] = CharState::POSITIONED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONTAINS
|
||||||
|
for char_index in 0..5 {
|
||||||
|
if guess[char_index].is_some() {
|
||||||
|
for word_index in 0..5 {
|
||||||
|
if word[word_index].is_some()
|
||||||
|
&& guess[char_index].unwrap() == word[word_index].unwrap()
|
||||||
|
{
|
||||||
|
word[word_index] = None;
|
||||||
|
guess[char_index] = None;
|
||||||
|
guess_state[char_index] = CharState::CONTAINS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.guess_states[i] = Option::from(guess_state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for WordleState {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
self.guesses.iter().enumerate().for_each(|(i, g)| {
|
||||||
|
f.write_str(
|
||||||
|
match g {
|
||||||
|
None => format!("{}\n", GRAY.paint("_ _ _ _ _")),
|
||||||
|
Some(guess) => match self.guess_states[i] {
|
||||||
|
None => format!(
|
||||||
|
"{}\n",
|
||||||
|
GRAY.paint(
|
||||||
|
guess
|
||||||
|
.iter()
|
||||||
|
.map(|c| format!("{} ", c.to_string()))
|
||||||
|
.collect::<String>()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Some(_) => format!(
|
||||||
|
"{}\n",
|
||||||
|
guess
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.fold(String::new(), |mut str, (i_c, c)| {
|
||||||
|
str.push_str(
|
||||||
|
format!(
|
||||||
|
"{} ",
|
||||||
|
match self.guess_states[i].unwrap()[i_c] {
|
||||||
|
CharState::EXCLUDES =>
|
||||||
|
DARK_GRAY.paint(c.to_string()),
|
||||||
|
CharState::CONTAINS => Yellow.paint(c.to_string()),
|
||||||
|
CharState::POSITIONED => Green.paint(c.to_string()),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
);
|
||||||
|
str
|
||||||
|
})
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.as_str(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn worlde_game_make_guess(guess: &str, state: &mut WordleState) {
|
||||||
|
let turn = state.guesses.iter().position(|guess| guess.is_none());
|
||||||
|
match turn {
|
||||||
|
Some(t) => println!("Current turn index: {}", t),
|
||||||
|
None => println!("Game is over"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if turn.is_some() {
|
||||||
|
let turn = turn.unwrap();
|
||||||
|
state.set_guess(turn, str_to_five_char(guess));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue