Решение на Wordle от Христо Жаблянов

Обратно към всички решения

Към профила на Христо Жаблянов

Резултати

  • 17 точки от тестове
  • 0 бонус точки
  • 17 точки общо
  • 13 успешни тест(а)
  • 2 неуспешни тест(а)

Код

use std::{
collections::HashMap,
fmt::{self},
};
#[derive(Debug, Clone, Copy)]
pub enum GameStatus {
InProgress,
Won,
Lost,
}
#[derive(Debug)]
pub enum GameError {
NotInAlphabet(char),
WrongLength { expected: usize, actual: usize },
GameIsOver(GameStatus),
}
#[derive(Debug)]
pub struct Game {
pub status: GameStatus,
pub attempts: u8,
ans_len: usize,
ans_str: String,
guesses: Vec<Word>,
symbols: HashMap<char, bool>,
}
#[derive(Debug, Clone)]
enum LetterMatch {
Full,
Partial,
None,
}
#[derive(Debug, Clone)]
pub struct Word {
chars: Vec<char>,
matches: Vec<LetterMatch>,
}
impl Word {
pub fn new() -> Word {
Word {
chars: Vec::new(),
matches: Vec::new(),
}
}
fn push(&mut self, c: char, l: LetterMatch) {
self.chars.push(c);
self.matches.push(l);
}
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
let mut symbols = HashMap::with_capacity(alphabet.len()); // byte length is fine.
for c in alphabet.chars() {
symbols.insert(c, false);
}
let mut ans_len = 0;
for c in word.chars() {
match symbols.get_mut(&c) {
Some(v) => *v = true,
None => return Err(GameError::NotInAlphabet(c)),
}
ans_len += 1;
}
Ok(Game {
status: GameStatus::InProgress,
guesses: Vec::new(),
attempts: 0,
ans_str: String::from(word),
ans_len,
symbols,
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
match &self.status {
GameStatus::InProgress => {}
_ => return Err(GameError::GameIsOver(self.status)),
}
let mut expected = self.ans_str.chars();
let mut actual = guess.chars();
let mut res = Ok::<bool, GameError>(true);
let mut word = Word::new();
loop {
let l = expected.next();
let r = actual.next();
if l.is_some() != r.is_some() {
return Err(GameError::WrongLength {
expected: self.ans_len,
actual: actual.count(),
});
}
if let Some(l) = l {
let r = r.unwrap();
if l == r {
word.push(l, LetterMatch::Full);
} else {
word.push(
r,
match self.symbols.get(&r) {
Some(v) => {
res = Ok(false);
if *v {
LetterMatch::Partial
} else {
LetterMatch::None
}
}
None => {
res = Err(GameError::NotInAlphabet(r));
LetterMatch::None
}
},
);
}
continue;
}
break;
}
match res {
Err(e) => return Err(e),
Ok(ok) => {
self.attempts += 1;
self.status = if ok {
GameStatus::Won
} else if self.attempts > 4 {
GameStatus::Lost
} else {
GameStatus::InProgress
}
}
}
self.guesses.push(word);
Ok(self.guesses.last().unwrap().clone())
}
}
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for i in 0..self.chars.len() {
let c = self.chars[i].to_uppercase();
match self.matches[i] {
LetterMatch::Full => f.write_fmt(format_args!("[{}]", c))?,
LetterMatch::Partial => f.write_fmt(format_args!("({})", c))?,
LetterMatch::None => f.write_fmt(format_args!(">{}<", c))?,
};
}
Ok(())
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let empty = "|_|".repeat(self.ans_len);
f.write_str(empty.as_str())?;
for w in &self.guesses {
f.write_fmt(format_args!("\n{}", w))?;
}
Ok(())
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20230111-3772066-j5aaok/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.88s
     Running tests/solution_test.rs (target/debug/deps/solution_test-0edbea2040daef01)

running 15 tests
test solution_test::test_game_display ... ok
test solution_test::test_game_display_cyrillic ... ok
test solution_test::test_game_display_german ... ok
test solution_test::test_game_state_1 ... ok
test solution_test::test_game_state_2 ... ok
test solution_test::test_game_state_3 ... ok
test solution_test::test_word_display ... ok
test solution_test::test_word_display_german ... ok
test solution_test::test_word_display_bulgarian ... ok
test solution_test::test_word_display_with_repetitions ... ok
test solution_test::test_word_not_in_alphabet_on_construction ... ok
test solution_test::test_word_not_in_alphabet_on_guess ... ok
test solution_test::test_word_not_in_alphabet_on_construction_cyrrilic ... ok
test solution_test::test_word_not_in_alphabet_on_guess_cyrillic ... FAILED
test solution_test::test_wrong_length ... FAILED

failures:

---- solution_test::test_word_not_in_alphabet_on_guess_cyrillic stdout ----
thread 'solution_test::test_word_not_in_alphabet_on_guess_cyrillic' panicked at 'Expression Err(NotInAlphabet('а')) does not match the pattern "Err(GameError::NotInAlphabet('х'))"', tests/solution_test.rs:46:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_wrong_length stdout ----
thread 'solution_test::test_wrong_length' panicked at 'Expression Err(WrongLength { expected: 4, actual: 2 }) does not match the pattern "Err(GameError::WrongLength { expected: 4, actual: 7 })"', tests/solution_test.rs:96:5


failures:
    solution_test::test_word_not_in_alphabet_on_guess_cyrillic
    solution_test::test_wrong_length

test result: FAILED. 13 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--test solution_test`

История (1 версия и 0 коментара)

Христо качи първо решение на 22.11.2022 00:42 (преди почти 3 години)