Решение на Wordle от Мирела Граматикова
Към профила на Мирела Граматикова
Резултати
- 13 точки от тестове
- 0 бонус точки
- 13 точки общо
- 10 успешни тест(а)
- 5 неуспешни тест(а)
Код
use std::collections::HashMap;
use std::fmt;
#[derive(Debug)]
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,
pub correct_word: String,
pub all_guesses: Vec<String>,
pub alphabet: String
}
#[derive(Debug)]
pub struct Word {
pub guess: String,
// Correct word
pub word: String
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for c in word.chars() {
if !alphabet.contains(c) {
return Err(GameError::NotInAlphabet(c))
}
}
return Ok(Game {
status: GameStatus::InProgress,
attempts: 0,
correct_word: String::from(word),
all_guesses: Vec::new(),
alphabet: String::from(alphabet)
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
self.attempts += 1;
for c in guess.chars() {
if !self.alphabet.contains(c) {
return Err(GameError::NotInAlphabet(c))
}
}
let guess_len: usize = guess.chars().count();
let correct_len: usize = self.correct_word.chars().count();
if guess_len != correct_len {
return Err(GameError::WrongLength { expected: correct_len, actual: guess_len })
}
self.all_guesses.push(String::from(guess));
if self.attempts >= 5 {
self.status = GameStatus::Lost;
}
if guess == self.correct_word {
if self.attempts < 5 {
self.status = GameStatus::Won;
}
}
Ok(Word {
guess: String::from(guess),
word: self.correct_word.clone()
})
}
}
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut guess_positions: HashMap<char, Vec<u32>> = HashMap::new();
let mut word_positions: HashMap<char, Vec<u32>> = HashMap::new();
let mut correct_positions: Vec<u32> = Vec::new();
let mut correct_chars_incorrect_positions: Vec<u32> = Vec::new();
for (index, char) in self.guess.chars().enumerate() {
if guess_positions.contains_key(&char) {
guess_positions.get_mut(&char).unwrap().push(index as u32);
} else {
let mut vec = Vec::new();
vec.push(index as u32);
guess_positions.insert(char, vec);
}
}
for (index, char) in self.word.chars().enumerate() {
if word_positions.contains_key(&char) {
word_positions.get_mut(&char).unwrap().push(index as u32);
} else {
let mut vec = Vec::new();
vec.push(index as u32);
word_positions.insert(char, vec);
}
}
for key in guess_positions.keys() {
let key_pos = guess_positions.get(key).unwrap();
if word_positions.contains_key(key) {
let word_pos = word_positions.get(key).unwrap();
for position in key_pos.iter() {
for correct_word_key_pos in word_pos.iter() {
if position == correct_word_key_pos {
correct_positions.push(*position);
} else {
correct_chars_incorrect_positions.push(*position)
}
}
}
}
}
// remove duplicates from both arrays since we're not taking into
// account words with repeating characters.
for (index, pos) in correct_positions.clone().into_iter().enumerate() {
for (index_2, second_pos) in correct_chars_incorrect_positions.clone().into_iter().enumerate() {
if pos == second_pos {
correct_chars_incorrect_positions.remove(index_2);
}
}
}
let mut final_string: String = String::from("");
for (index, char) in self.guess.to_uppercase().chars().enumerate() {
if correct_positions.contains(&(index as u32)) {
final_string += format!("[{char}]").as_str();
} else if correct_chars_incorrect_positions.contains(&(index as u32)) {
final_string += format!("({char})").as_str();
} else {
final_string += format!(">{char}<").as_str();
}
}
write!(f, "{}", final_string)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut final_string: String = String::from("");
for (_, _) in self.correct_word.chars().enumerate() {
final_string += "|_|";
}
final_string += "\n";
for attempt in self.all_guesses.iter() {
let word: Word = Word {
guess: attempt.clone(),
word: self.correct_word.clone()
};
final_string += format!("{word}").as_str();
final_string += "\n";
}
final_string.pop();
write!(f, "{}", final_string)
}
}
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20230111-3772066-1yfrd1c/solution) warning: unused variable: `index` --> src/lib.rs:132:14 | 132 | for (index, pos) in correct_positions.clone().into_iter().enumerate() { | ^^^^^ help: if this is intentional, prefix it with an underscore: `_index` | = note: `#[warn(unused_variables)]` on by default warning: `solution` (lib) generated 1 warning Finished test [unoptimized + debuginfo] target(s) in 0.90s 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 ... FAILED test solution_test::test_game_state_1 ... FAILED test solution_test::test_game_state_2 ... FAILED test solution_test::test_game_state_3 ... ok test solution_test::test_word_display ... ok test solution_test::test_word_display_bulgarian ... ok test solution_test::test_word_display_german ... FAILED test solution_test::test_word_not_in_alphabet_on_construction ... ok test solution_test::test_word_not_in_alphabet_on_construction_cyrrilic ... ok test solution_test::test_word_not_in_alphabet_on_guess ... ok test solution_test::test_word_not_in_alphabet_on_guess_cyrillic ... ok test solution_test::test_word_display_with_repetitions ... ok test solution_test::test_wrong_length ... FAILED failures: ---- solution_test::test_game_display_german stdout ---- thread 'solution_test::test_game_display_german' panicked at 'assertion failed: `(left == right)` left: `"|_||_||_|\n>F<[Ü][S]>S<"`, right: `"|_||_||_|\n>F<[Ü][SS]"`', tests/solution_test.rs:135:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ---- solution_test::test_game_state_1 stdout ---- thread 'solution_test::test_game_state_1' panicked at 'Expression Ok(Word { guess: "abc", word: "abc" }) does not match the pattern "Err(GameError::GameIsOver(GameStatus::Won))"', tests/solution_test.rs:146:5 ---- solution_test::test_game_state_2 stdout ---- thread 'solution_test::test_game_state_2' panicked at 'Expression Ok(Word { guess: "abc", word: "abc" }) does not match the pattern "Err(GameError::GameIsOver(GameStatus::Lost))"', tests/solution_test.rs:160:5 ---- solution_test::test_word_display_german stdout ---- thread 'solution_test::test_word_display_german' panicked at 'assertion failed: `(left == right)` left: `">F<[Ü][S]>S<"`, right: `">F<[Ü][SS]"`', tests/solution_test.rs:88:5 ---- solution_test::test_wrong_length stdout ---- thread 'solution_test::test_wrong_length' panicked at 'Expression Err(NotInAlphabet(' ')) does not match the pattern "Err(GameError::WrongLength { expected: 4, actual: 5 })"', tests/solution_test.rs:98:5 failures: solution_test::test_game_display_german solution_test::test_game_state_1 solution_test::test_game_state_2 solution_test::test_word_display_german solution_test::test_wrong_length test result: FAILED. 10 passed; 5 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s error: test failed, to rerun pass `--test solution_test`