Решение на Wordle от Таня Сейкова

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

Към профила на Таня Сейкова

Резултати

  • 16 точки от тестове
  • 0 бонус точки
  • 16 точки общо
  • 12 успешни тест(а)
  • 3 неуспешни тест(а)

Код

#[derive(Debug)]
#[derive(Clone)]
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 alphabet: String,
pub word: String,
pub guesses: Vec<Word>
}
#[derive(Debug)]
#[derive(Clone)]
#[derive(PartialEq)]
enum LetterState {
FullMatch,
PartialMatch,
NoMatch,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Word {
guessed: String,
letter_states: Vec<LetterState>
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for letter in word.chars() {
let mut found = false;
for alph_sign in alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
Ok(Self {
status: GameStatus::InProgress,
attempts: 0,
alphabet: String::from(alphabet),
word: String::from(word),
guesses: Vec::<Word>::with_capacity(5),
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
let _status = self.status.clone();
if let GameStatus::Won = _status {
return Err(GameError::GameIsOver(_status));
}
if let GameStatus::Lost = _status {
return Err(GameError::GameIsOver(_status));
}
if guess.chars().count() != self.word.chars().count() {
return Err(GameError::WrongLength{expected: self.word.chars().count(), actual: guess.chars().count()});
}
for letter in guess.chars() {
let mut found = false;
for alph_sign in self.alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
let mut output_vec: Vec<LetterState> = Vec::new();
let mut correct_letters = 0;
for (i, letter) in guess.chars().enumerate() {
if letter == self.word.chars().nth(i).unwrap() {
output_vec.push(LetterState::FullMatch);
correct_letters += 1;
} else {
// this letter is in the word
let mut found = false;
for word_sign in self.word.chars() {
if letter == word_sign {
found = true;
break;
}
}
if found == true {
output_vec.push(LetterState::PartialMatch);
}
else {
output_vec.push(LetterState::NoMatch);
}
}
}
let wrapped_guess = Word{
guessed: String::from(guess),
letter_states: output_vec,
};
self.guesses.push(wrapped_guess.clone());
self.attempts += 1;
if self.attempts > 5 {
self.status = GameStatus::Lost;
} else if correct_letters == guess.chars().count() {
self.status = GameStatus::Won;
}
Ok(wrapped_guess.clone())
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
let copy_word = self.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if self.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if self.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if self.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
write!(f, "{}", result_string)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
for _ in 0..self.word.chars().count() {
result_string += "|_|";
}
for guess in &self.guesses {
result_string += "\n";
let copy_word = guess.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if guess.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if guess.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if guess.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
}
write!(f, "{}", result_string)
}
}

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

Compiling solution v0.1.0 (/tmp/d20230111-3772066-1yspsr9/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.78s
     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_state_1 ... ok
test solution_test::test_game_display_german ... 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_german ... FAILED
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 ... ok
test solution_test::test_wrong_length ... ok

failures:

---- solution_test::test_game_display_german stdout ----
thread 'solution_test::test_game_display_german' panicked at 'index out of bounds: the len is 3 but the index is 3', src/lib.rs:164:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_game_state_2 stdout ----
thread 'solution_test::test_game_state_2' panicked at 'Expression InProgress does not match the pattern "GameStatus::Lost"', tests/solution_test.rs:159:5

---- solution_test::test_word_display_german stdout ----
thread 'solution_test::test_word_display_german' panicked at 'index out of bounds: the len is 3 but the index is 3', src/lib.rs:136:16


failures:
    solution_test::test_game_display_german
    solution_test::test_game_state_2
    solution_test::test_word_display_german

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

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

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

Таня качи първо решение на 20.11.2022 18:17 (преди почти 3 години)

Таня качи решение на 20.11.2022 18:18 (преди почти 3 години)

#[derive(Debug)]
#[derive(Clone)]
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 alphabet: String,
pub word: String,
pub guesses: Vec<Word>
}
#[derive(Debug)]
#[derive(Clone)]
#[derive(PartialEq)]
enum LetterState {
FullMatch,
PartialMatch,
NoMatch,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Word {
guessed: String,
letter_states: Vec<LetterState>
}
impl Game {
- /// Конструира нова игра с думи/букви от дадената в `alphabet` азбука. Alphabet е просто низ,
- /// в който всеки символ е отделна буква, който вероятно искате да си запазите някак за после.
- ///
- /// Подадената дума с `word` трябва да има само букви от тази азбука. Иначе очакваме да върнете
- /// `GameError::NotInAlphabet` грешка с първия символ в `word`, който не е от азбуката.
- ///
- /// Началното състояние на играта е `InProgress` а началния брой опити `attempts` е 0.
- ///
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for letter in word.chars() {
let mut found = false;
for alph_sign in alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
Ok(Self {
status: GameStatus::InProgress,
attempts: 0,
alphabet: String::from(alphabet),
word: String::from(word),
guesses: Vec::<Word>::with_capacity(5),
})
}
- /// Опитва се да познае търсената дума. Опита е в `guess`.
- ///
- /// Ако играта е приключила, тоест статуса ѝ е `Won` или `Lost`, очакваме да върнете
- /// `GameIsOver` със статуса, с който е приключила.
- ///
- /// Ако `guess` има различен брой букви от търсената дума, очакваме да върнете
- /// `GameError::WrongLength`. Полето `expected` на грешката трябва да съдържа броя букви на
- /// търсената дума, а `actual` да е броя букви на опита `guess`.
- ///
- /// Ако `guess` има правилния брой букви, но има буква, която не е от азбуката на играта,
- /// очакваме `GameError::NotInAlphabet` както по-горе, с първия символ от `guess`, който не е
- /// от азбуката.
- ///
- /// Метода приема `&mut self`, защото всеки валиден опит (такъв, който не връща грешка) се
- /// запазва в играта за по-нататък. Метода връща `Word`, което описва освен самите символи на
- /// `guess`, и как тези символи са се напаснали на търсената дума. Също така инкрементира
- /// `attempts` с 1.
- ///
- /// След опита за напасване на думата, ако всички букви са уцелени на правилните места,
- /// очакваме `state` полето да се промени на `Won`. Иначе, ако `attempts` са станали 5,
- /// състоянието трябва да е `Lost`.
- ///
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
let _status = self.status.clone();
if let GameStatus::Won = _status {
return Err(GameError::GameIsOver(_status));
}
if let GameStatus::Lost = _status {
return Err(GameError::GameIsOver(_status));
}
if guess.len() != self.word.len() {
return Err(GameError::WrongLength{expected: self.word.len(), actual: guess.len()});
}
for letter in guess.chars() {
let mut found = false;
for alph_sign in self.alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
let mut output_vec: Vec<LetterState> = Vec::new();
let mut correct_letters = 0;
for (i, letter) in guess.chars().enumerate() {
if letter == self.word.chars().nth(i).unwrap() {
output_vec.push(LetterState::FullMatch);
correct_letters += 1;
} else {
// this letter is in the word
let mut found = false;
for word_sign in self.word.chars() {
if letter == word_sign {
found = true;
break;
}
}
if found == true {
output_vec.push(LetterState::PartialMatch);
}
else {
output_vec.push(LetterState::NoMatch);
}
}
}
let wrapped_guess = Word{
guessed: String::from(guess),
letter_states: output_vec,
};
self.guesses.push(wrapped_guess.clone());
self.attempts += 1;
if self.attempts > 5 {
self.status = GameStatus::Lost;
} else if correct_letters == guess.len() {
self.status = GameStatus::Won;
}
Ok(wrapped_guess.clone())
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
let copy_word = self.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if self.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if self.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if self.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
write!(f, "{}", result_string)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
for _ in 0..self.word.len() {
result_string += "|_|";
}
for guess in &self.guesses {
result_string += "\n";
let copy_word = guess.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if guess.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if guess.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if guess.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
}
write!(f, "{}", result_string)
}
}

Таня качи решение на 20.11.2022 20:17 (преди почти 3 години)

#[derive(Debug)]
#[derive(Clone)]
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 alphabet: String,
pub word: String,
pub guesses: Vec<Word>
}
#[derive(Debug)]
#[derive(Clone)]
#[derive(PartialEq)]
enum LetterState {
FullMatch,
PartialMatch,
NoMatch,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Word {
guessed: String,
letter_states: Vec<LetterState>
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for letter in word.chars() {
let mut found = false;
for alph_sign in alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
Ok(Self {
status: GameStatus::InProgress,
attempts: 0,
alphabet: String::from(alphabet),
word: String::from(word),
guesses: Vec::<Word>::with_capacity(5),
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
let _status = self.status.clone();
if let GameStatus::Won = _status {
return Err(GameError::GameIsOver(_status));
}
if let GameStatus::Lost = _status {
return Err(GameError::GameIsOver(_status));
}
- if guess.len() != self.word.len() {
- return Err(GameError::WrongLength{expected: self.word.len(), actual: guess.len()});
+ if guess.chars().count() != self.word.chars().count() {
+ return Err(GameError::WrongLength{expected: self.word.chars().count(), actual: guess.chars().count()});
}
for letter in guess.chars() {
let mut found = false;
for alph_sign in self.alphabet.chars() {
if letter == alph_sign {
found = true;
break;
}
}
if found == false {
return Err(GameError::NotInAlphabet(letter));
}
}
let mut output_vec: Vec<LetterState> = Vec::new();
let mut correct_letters = 0;
for (i, letter) in guess.chars().enumerate() {
if letter == self.word.chars().nth(i).unwrap() {
output_vec.push(LetterState::FullMatch);
correct_letters += 1;
} else {
// this letter is in the word
let mut found = false;
for word_sign in self.word.chars() {
if letter == word_sign {
found = true;
break;
}
}
if found == true {
output_vec.push(LetterState::PartialMatch);
}
else {
output_vec.push(LetterState::NoMatch);
}
}
}
let wrapped_guess = Word{
guessed: String::from(guess),
letter_states: output_vec,
};
self.guesses.push(wrapped_guess.clone());
self.attempts += 1;
if self.attempts > 5 {
self.status = GameStatus::Lost;
- } else if correct_letters == guess.len() {
+ } else if correct_letters == guess.chars().count() {
self.status = GameStatus::Won;
}
Ok(wrapped_guess.clone())
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
let copy_word = self.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if self.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if self.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if self.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
write!(f, "{}", result_string)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut result_string: String = "".to_owned();
- for _ in 0..self.word.len() {
+ for _ in 0..self.word.chars().count() {
result_string += "|_|";
}
for guess in &self.guesses {
result_string += "\n";
let copy_word = guess.guessed.to_uppercase();
for (i, letter) in copy_word.chars().enumerate(){
if guess.letter_states[i] == LetterState::FullMatch {
result_string = result_string + "[" + &letter.to_string() + "]";
continue;
}
if guess.letter_states[i] == LetterState::PartialMatch {
result_string = result_string + "(" + &letter.to_string() + ")";
continue;
}
if guess.letter_states[i] == LetterState::NoMatch {
result_string = result_string + ">" + &letter.to_string() + "<";
continue;
}
}
}
write!(f, "{}", result_string)
}
}