#[derive(Debug, Copy, Clone)]
pub struct PartResult {
letter: char,
in_word: bool,
in_position: bool,
}
impl PartResult {
#[must_use]
pub fn letter(&self) -> char {
self.letter
}
#[must_use]
pub fn in_word(&self) -> bool {
self.in_word
}
#[must_use]
pub fn in_position(&self) -> bool {
self.in_position
}
}
#[derive(Debug)]
pub struct GuessResult {
word: String,
parts: Vec<PartResult>,
}
impl GuessResult {
#[must_use]
pub fn word(&self) -> &str {
&self.word
}
#[must_use]
pub fn parts(&self) -> &Vec<PartResult> {
&self.parts
}
}
#[derive(Debug)]
pub struct Wordle<'a> {
word: &'a str,
count: u32,
won: bool,
}
impl Wordle<'_> {
#[must_use]
pub fn new(word: &str) -> Wordle {
Wordle {
word,
count: 0,
won: false,
}
}
pub fn guess(&mut self, guess: &str) -> GuessResult {
if self.word == guess {
self.set_won();
}
assert!(
guess.len() == self.word.len(),
"Guess must be the same length as the word"
);
let mut results = Vec::new();
let mut word_clone = self.word.clone().to_string();
for c in guess.char_indices() {
let letter = c.1;
let in_word = word_clone.contains(letter);
let in_position = self.word.chars().nth(c.0) == Some(letter);
if in_word {
for (i, c) in word_clone.char_indices() {
if c == letter {
word_clone.replace_range(i..i + 1, "_");
break;
}
}
}
results.push(PartResult {
letter,
in_word,
in_position,
});
}
GuessResult {
word: guess.to_string(),
parts: results,
}
}
#[must_use]
pub fn count(&self) -> u32 {
self.count
}
#[must_use]
pub fn won(&self) -> bool {
self.won
}
#[must_use]
pub fn length(&self) -> usize {
self.word.len()
}
#[must_use]
pub fn word(&self) -> &str {
self.word
}
fn set_won(&mut self) {
self.won = true;
}
}