Решение на Wordle от Алекс Божинов

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

Към профила на Алекс Божинов

Резултати

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

Код

#[derive(Debug)]
#[derive(PartialEq)]
#[derive(Clone, Copy)]
pub enum GameStatus {
InProgress,
Won,
Lost,
}
#[derive(Debug)]
#[derive(Clone, Copy)]
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 all_words: Vec<Word>,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Word {
pub text: String,
pub letters_num: usize,
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.text)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut idx: i32 = 0;
for w in &self.all_words {
if idx == 0{
write!(f, "{}", w)?;
}else{
write!(f, "\n{}", w)?;
}
idx+=1;
}
Ok(())
}
}
impl Word{
pub fn new(letters_num: usize) -> Self{
let pattern: String = String::from("|_|");
let mut new_text: String = String::from("");
for _ in 0..letters_num{
new_text.push_str(&pattern);
}
Self{
text: String::from(new_text),
letters_num: letters_num,
}
}
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
let splited_alphabet: Vec<char> = alphabet.chars().collect();
let splited_word: Vec<char> = word.chars().collect();
for ch in splited_word{
if !splited_alphabet.contains(&ch){
return Err(GameError::NotInAlphabet(ch));
}
}
let mut start_vec: Vec<Word> = Vec::new();
let first_try: Word = Word::new(word.len());
start_vec.push(first_try);
Ok(Self{
alphabet: String::from(alphabet),
word: String::from(word),
attempts: 0,
status: GameStatus::InProgress,
all_words: start_vec,
})
}
/// Метода приема `&mut self`, защото всеки валиден опит (такъв, който не връща грешка) се
/// запазва в играта за по-нататък. Метода връща `Word`, което описва освен самите символи на
/// `guess`, и как тези символи са се напаснали на търсената дума. Също така инкрементира
/// `attempts` с 1.
///
/// След опита за напасване на думата, ако всички букви са уцелени на правилните места,
/// очакваме `state` полето да се промени на `Won`. Иначе, ако `attempts` са станали 5,
/// състоянието трябва да е `Lost`.
///
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
let word_length = self.word.len();
let guess_length = guess.len();
let splited_alphabet: Vec<char> = self.alphabet.chars().collect();
let splited_word: Vec<char> = guess.chars().collect();
if self.status == GameStatus::Won || self.status == GameStatus::Lost{
return Err(GameError::GameIsOver(self.status));
}
if word_length != guess_length{
return Err(GameError::WrongLength{expected: word_length, actual: guess_length})
}
for ch in splited_word{
if !splited_alphabet.contains(&ch){
return Err(GameError::NotInAlphabet(ch));
}
}
self.attempts += 1;
let guess_upper = guess.to_uppercase();
let word_upper = self.word.to_uppercase();
let mut from: usize = 0;
let diff: usize =3;
let mut new_word: Word = Word::new(self.word.len());
let mut guess_chars = guess_upper.chars();
let mut word_chars = word_upper.chars();
for _ in 0..guess.len(){
let letter = guess_chars.next();
if letter == word_chars.next(){
new_word.text.remove(from);
new_word.text.insert_str(from,"[");
new_word.text.remove(from+1);
new_word.text.insert(from+1, letter.unwrap());
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,"]");
}else{
new_word.text.remove(from);
new_word.text.insert_str(from,">");
new_word.text.remove(from+1);
new_word.text.insert(from+1, letter.unwrap());
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,"<");
}
from+=diff;
}
from = 0;
guess_chars = guess_upper.chars();
word_chars = word_upper.chars();
for _ in 0..guess.len(){
let letter = guess_chars.next();
if self.word.to_uppercase().contains(letter.unwrap()) && letter != word_chars.next(){
new_word.text.remove(from);
new_word.text.insert_str(from,"(");
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,")");
}
from+=diff;
}
//println!("{:?}", self.all_words);
self.all_words.push(new_word.to_owned());
if self.attempts == 5 && self.status == GameStatus::InProgress{
self.status = GameStatus::Lost;
}
if self.attempts <= 5 && self.word.eq(guess){
self.status = GameStatus::Won
}
return Ok(new_word);
}
}

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

Compiling solution v0.1.0 (/tmp/d20230111-3772066-1blfpsz/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.80s
     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 ... FAILED
test solution_test::test_game_display_german ... FAILED
test solution_test::test_game_state_1 ... ok
test solution_test::test_game_state_2 ... ok
test solution_test::test_word_display ... ok
test solution_test::test_game_state_3 ... ok
test solution_test::test_word_display_bulgarian ... FAILED
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_display_with_repetitions ... ok
test solution_test::test_word_not_in_alphabet_on_guess ... ok
test solution_test::test_word_not_in_alphabet_on_guess_cyrillic ... FAILED
test solution_test::test_wrong_length ... ok

failures:

---- solution_test::test_game_display_cyrillic stdout ----
thread 'solution_test::test_game_display_cyrillic' panicked at 'assertion failed: `(left == right)`
  left: `"|_||_||_||_||_||_|"`,
 right: `"|_||_||_|"`', tests/solution_test.rs:119:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- solution_test::test_game_display_german stdout ----
thread 'solution_test::test_game_display_german' panicked at 'assertion failed: `(left == right)`
  left: `"|_||_||_||_||_|"`,
 right: `"|_||_||_|"`', tests/solution_test.rs:133:5

---- solution_test::test_word_display_bulgarian stdout ----
thread 'solution_test::test_word_display_bulgarian' panicked at 'byte index 2 is not a char boundary; it is inside 'Л' (bytes 1..3) of `>Л||_||_||_||_||_||_||_|`', /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/alloc/src/string.rs:1336:24

---- solution_test::test_word_display_german stdout ----
thread 'solution_test::test_word_display_german' panicked at 'assertion failed: `(left == right)`
  left: `"|_||_||_||_||_|"`,
 right: `"|_||_||_|"`', tests/solution_test.rs:87:5

---- 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(WrongLength { expected: 4, actual: 8 }) does not match the pattern "Err(GameError::NotInAlphabet('х'))"', tests/solution_test.rs:46:5


failures:
    solution_test::test_game_display_cyrillic
    solution_test::test_game_display_german
    solution_test::test_word_display_bulgarian
    solution_test::test_word_display_german
    solution_test::test_word_not_in_alphabet_on_guess_cyrillic

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`

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

Алекс качи първо решение на 24.11.2022 07:20 (преди 6 месеца)

Алекс качи решение на 24.11.2022 07:40 (преди 6 месеца)

#[derive(Debug)]
#[derive(PartialEq)]
#[derive(Clone, Copy)]
pub enum GameStatus {
InProgress,
Won,
Lost,
}
#[derive(Debug)]
#[derive(Clone, Copy)]
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 all_words: Vec<Word>,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Word {
pub text: String,
pub letters_num: usize,
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.text)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let mut idx: i32 = 0;
for w in &self.all_words {
- write!(f, "{}\n", w)?;
+ if idx == 0{
+ write!(f, "{}", w)?;
+ }else{
+ write!(f, "\n{}", w)?;
+ }
+ idx+=1;
}
Ok(())
}
}
impl Word{
pub fn new(letters_num: usize) -> Self{
let pattern: String = String::from("|_|");
let mut new_text: String = String::from("");
for _ in 0..letters_num{
new_text.push_str(&pattern);
}
Self{
text: String::from(new_text),
letters_num: letters_num,
}
}
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
let splited_alphabet: Vec<char> = alphabet.chars().collect();
let splited_word: Vec<char> = word.chars().collect();
for ch in splited_word{
if !splited_alphabet.contains(&ch){
return Err(GameError::NotInAlphabet(ch));
}
}
+
+ let mut start_vec: Vec<Word> = Vec::new();
+ let first_try: Word = Word::new(word.len());
+ start_vec.push(first_try);
Ok(Self{
alphabet: String::from(alphabet),
word: String::from(word),
attempts: 0,
status: GameStatus::InProgress,
- all_words: Vec::new(),
+ all_words: start_vec,
})
}
/// Метода приема `&mut self`, защото всеки валиден опит (такъв, който не връща грешка) се
/// запазва в играта за по-нататък. Метода връща `Word`, което описва освен самите символи на
/// `guess`, и как тези символи са се напаснали на търсената дума. Също така инкрементира
/// `attempts` с 1.
///
/// След опита за напасване на думата, ако всички букви са уцелени на правилните места,
/// очакваме `state` полето да се промени на `Won`. Иначе, ако `attempts` са станали 5,
/// състоянието трябва да е `Lost`.
///
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
let word_length = self.word.len();
let guess_length = guess.len();
let splited_alphabet: Vec<char> = self.alphabet.chars().collect();
let splited_word: Vec<char> = guess.chars().collect();
if self.status == GameStatus::Won || self.status == GameStatus::Lost{
return Err(GameError::GameIsOver(self.status));
}
if word_length != guess_length{
return Err(GameError::WrongLength{expected: word_length, actual: guess_length})
}
for ch in splited_word{
if !splited_alphabet.contains(&ch){
return Err(GameError::NotInAlphabet(ch));
}
- }
-
- if self.attempts == 0{
- let first_try: Word = Word::new(self.word.len());
- self.all_words.push(first_try);
}
self.attempts += 1;
let guess_upper = guess.to_uppercase();
let word_upper = self.word.to_uppercase();
let mut from: usize = 0;
let diff: usize =3;
let mut new_word: Word = Word::new(self.word.len());
let mut guess_chars = guess_upper.chars();
let mut word_chars = word_upper.chars();
for _ in 0..guess.len(){
let letter = guess_chars.next();
if letter == word_chars.next(){
new_word.text.remove(from);
new_word.text.insert_str(from,"[");
new_word.text.remove(from+1);
new_word.text.insert(from+1, letter.unwrap());
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,"]");
}else{
new_word.text.remove(from);
new_word.text.insert_str(from,">");
new_word.text.remove(from+1);
new_word.text.insert(from+1, letter.unwrap());
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,"<");
}
from+=diff;
}
from = 0;
guess_chars = guess_upper.chars();
word_chars = word_upper.chars();
for _ in 0..guess.len(){
let letter = guess_chars.next();
if self.word.to_uppercase().contains(letter.unwrap()) && letter != word_chars.next(){
new_word.text.remove(from);
new_word.text.insert_str(from,"(");
new_word.text.remove(from+2);
new_word.text.insert_str(from+2,")");
}
from+=diff;
}
//println!("{:?}", self.all_words);
self.all_words.push(new_word.to_owned());
if self.attempts == 5 && self.status == GameStatus::InProgress{
self.status = GameStatus::Lost;
}
if self.attempts <= 5 && self.word.eq(guess){
self.status = GameStatus::Won
}
return Ok(new_word);
}
}