Решение на Wordle от Христо Георгиев

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

Към профила на Христо Георгиев

Резултати

  • 11 точки от тестове
  • 0 бонус точки
  • 11 точки общо
  • 8 успешни тест(а)
  • 7 неуспешни тест(а)

Код

#[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,
word: Word,
pub alphabet: String,
pub guesses: Vec<Option<String>>,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Letter {
pub letter : char,
pub count : isize,
}
#[derive(Debug)]
pub struct Word {
pub word_original : String,
pub word_validated : String,
pub counting : Vec<Letter>,
}
impl Letter {
pub fn new(letter_to_push : char , count_to_push : isize) -> Letter {
return Letter {letter : letter_to_push , count : count_to_push};
}
// pub fn clone(&self) -> Letter {
// let letter_to_return = Letter::new(self.letter , self.count);
// return letter_to_return;
// }
}
impl Word {
pub fn new(word_passed : String, word_validated_passed : String) -> Word {
let mut letters_to_push = Vec::<Letter>::new();
for _c in word_passed.chars() {
if letters_to_push.is_empty() {
let letter = Letter::new(_c , 1);
letters_to_push.push(letter);
}
else {
let mut has_it = false;
for _i in letters_to_push.iter_mut() {
if _i.letter == _c {
_i.count = _i.count + 1;
has_it = true;
}
}
if !has_it {
let letter = Letter::new(_c , 1);
letters_to_push.push(letter);
}
}
}
return Word {word_original : word_passed, word_validated : word_validated_passed, counting : letters_to_push.to_vec().clone()};
}
pub fn how_many_occurances(&mut self , letter : char) -> isize {
for _i in self.counting.iter_mut() {
if letter == _i.letter {
return _i.count;
}
}
return 0;
}
}
impl Game {
fn is_word_valid(alphabet: &str, word: &str) ->bool {
for c in word.chars() {
if !alphabet.contains(c){
return false;
}
}
return true;
}
fn get_invalid_char(alphabet: &str, word: &str) -> Option<char> {
for _c in word.chars() {
if !alphabet.contains(_c) {
return Some(_c);
}
}
return None
}
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
if !Self::is_word_valid(alphabet, word) {
return Err(GameError::NotInAlphabet(Self::get_invalid_char(alphabet, word).unwrap()));
}
let mut word_validated = String::new();
let word_chars = word.chars();
for c in word_chars {
let curr_letter = String::from(format!("[{}]" ,c.to_uppercase()));
word_validated.push_str( &curr_letter);
}
return Ok(Game{status : GameStatus::InProgress, attempts : 0, word : Word::new(word.to_string(), word_validated), alphabet : alphabet.to_string(), guesses : Vec::new()});
}
pub fn letter_is_in_place(_word: &str, letter: char, pos : usize) -> bool {
let (_first, _second) = _word.split_at(pos-1);
let mut letters = _second.chars();
return letter == letters.next().unwrap();
}
pub fn guess_word(&mut self, _guess: &str) -> Result<Word, GameError> {
match &self.status {
GameStatus::Won => Err(GameError::GameIsOver(GameStatus::Won)),
GameStatus::Lost => Err(GameError::GameIsOver(GameStatus::Lost)),
GameStatus::InProgress => {
let mut letters_original_copied = self.word.counting.clone();
if _guess.len() != self.word.word_original.len() {
let expected_to_pass = self.word.word_original.len();
let actual_to_pass = _guess.len();
return Err(GameError::WrongLength{expected : expected_to_pass , actual : actual_to_pass});
}
else if !Self::is_word_valid(self.alphabet.as_str() , _guess) {
return Err(GameError::NotInAlphabet(Self::get_invalid_char(self.alphabet.as_str() , _guess).unwrap()));
}
else {
let mut placed_guess_res = String::new();
if self.word.word_original == _guess {
self.status = GameStatus::Won;
for _c in _guess.chars() {
let current_letter = _c;
let to_push = String::from(format!("[{}]" , current_letter.to_uppercase()));
placed_guess_res.push_str(&to_push);
}
self.guesses.push(Some(placed_guess_res.clone()));
let to_push = Word::new(self.word.word_original.clone() , self.word.word_validated.clone());
return Ok(to_push);
}
else {
let mut counter_iter = 0;
for c in _guess.chars() {
let current_letter = c;
counter_iter = counter_iter + 1;
if Self::letter_is_in_place(&self.word.word_original, current_letter, counter_iter) {
let curr_letter_to_push = String::from(format!("[{}]" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
let counter = 0;
for _i in self.word.counting.iter() {
if _i.letter == current_letter {
letters_original_copied[counter].count = letters_original_copied[counter].count - 1;
}
break;
}
}
else if self.word.word_original.contains(current_letter) {
let counter = 0;
for _i in self.word.counting.iter() {
if (_i.letter == current_letter) && (letters_original_copied[counter].count == 0) {
let curr_letter_to_push = String::from(format!(">{}<" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
break;
}
else {
let curr_letter_to_push = String::from(format!("({})" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
letters_original_copied[counter].count = letters_original_copied[counter].count - 1;
break;
}
}
}
else {
let curr_letter_to_push = String::from(format!(">{}<" , current_letter.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
}
}
self.guesses.push(Some(placed_guess_res.clone()));
self.attempts = self.attempts + 1;
if self.attempts == 5 {
self.status = GameStatus::Lost;
}
let to_push = Word::new(_guess.to_string() , placed_guess_res);
return Ok(to_push);
}
}
},
}
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.word_validated)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut to_display = String::new();
for _i in self.word.word_original.chars() {
to_display.push_str("|_|");
}
for c in self.guesses.iter() {
to_display.push_str("\n");
to_display.push_str(&c.as_ref().unwrap().clone())
}
write!(f , "{}" , to_display)
}
}

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

Compiling solution v0.1.0 (/tmp/d20230111-3772066-116x10/solution)
    Finished test [unoptimized + debuginfo] target(s) in 0.81s
     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_game_state_3 ... ok
test solution_test::test_word_display ... FAILED
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_display_with_repetitions ... FAILED
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_wrong_length ... ok
test solution_test::test_word_not_in_alphabet_on_guess_cyrillic ... FAILED

failures:

---- solution_test::test_game_display_cyrillic stdout ----
thread 'solution_test::test_game_display_cyrillic' panicked at 'byte index 1 is not a char boundary; it is inside 'а' (bytes 0..2) of `аре`', /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/str/mod.rs:678:13
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 'byte index 2 is not a char boundary; it is inside 'ü' (bytes 1..3) of `süß`', /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/str/mod.rs:678:13

---- solution_test::test_word_display stdout ----
thread 'solution_test::test_word_display' panicked at 'assertion failed: `(left == right)`
  left: `"(P)[O]>B<"`,
 right: `"(P)[O](B)"`', tests/solution_test.rs:58:5

---- solution_test::test_word_display_bulgarian stdout ----
thread 'solution_test::test_word_display_bulgarian' panicked at 'byte index 1 is not a char boundary; it is inside 'с' (bytes 0..2) of `стол`', /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/str/mod.rs:678:13

---- solution_test::test_word_display_german stdout ----
thread 'solution_test::test_word_display_german' panicked at 'byte index 2 is not a char boundary; it is inside 'ü' (bytes 1..3) of `süß`', /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/str/mod.rs:678:13

---- solution_test::test_word_display_with_repetitions stdout ----
thread 'solution_test::test_word_display_with_repetitions' panicked at 'assertion failed: `(left == right)`
  left: `"(P)[O][O]>B<"`,
 right: `"(P)[O][O](B)"`', tests/solution_test.rs:68: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
    solution_test::test_word_display_bulgarian
    solution_test::test_word_display_german
    solution_test::test_word_display_with_repetitions
    solution_test::test_word_not_in_alphabet_on_guess_cyrillic

test result: FAILED. 8 passed; 7 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 11:10 (преди почти 3 години)

Христо качи решение на 24.11.2022 12:39 (преди почти 3 години)

#[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,
word: Word,
pub alphabet: String,
pub guesses: Vec<Option<String>>,
}
#[derive(Debug)]
#[derive(Clone)]
pub struct Letter {
pub letter : char,
pub count : isize,
}
#[derive(Debug)]
pub struct Word {
pub word_original : String,
pub word_validated : String,
pub counting : Vec<Letter>,
}
impl Letter {
pub fn new(letter_to_push : char , count_to_push : isize) -> Letter {
return Letter {letter : letter_to_push , count : count_to_push};
}
// pub fn clone(&self) -> Letter {
// let letter_to_return = Letter::new(self.letter , self.count);
// return letter_to_return;
// }
}
impl Word {
pub fn new(word_passed : String, word_validated_passed : String) -> Word {
let mut letters_to_push = Vec::<Letter>::new();
for _c in word_passed.chars() {
if letters_to_push.is_empty() {
let letter = Letter::new(_c , 1);
letters_to_push.push(letter);
}
else {
let mut has_it = false;
for _i in letters_to_push.iter_mut() {
if _i.letter == _c {
_i.count = _i.count + 1;
has_it = true;
}
}
if !has_it {
let letter = Letter::new(_c , 1);
letters_to_push.push(letter);
}
}
}
return Word {word_original : word_passed, word_validated : word_validated_passed, counting : letters_to_push.to_vec().clone()};
}
pub fn how_many_occurances(&mut self , letter : char) -> isize {
for _i in self.counting.iter_mut() {
if letter == _i.letter {
return _i.count;
}
}
return 0;
}
}
impl Game {
fn is_word_valid(alphabet: &str, word: &str) ->bool {
for c in word.chars() {
if !alphabet.contains(c){
return false;
}
}
return true;
}
fn get_invalid_char(alphabet: &str, word: &str) -> Option<char> {
for _c in word.chars() {
if !alphabet.contains(_c) {
return Some(_c);
}
}
return None
}
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
if !Self::is_word_valid(alphabet, word) {
return Err(GameError::NotInAlphabet(Self::get_invalid_char(alphabet, word).unwrap()));
}
let mut word_validated = String::new();
let word_chars = word.chars();
for c in word_chars {
let curr_letter = String::from(format!("[{}]" ,c.to_uppercase()));
word_validated.push_str( &curr_letter);
}
return Ok(Game{status : GameStatus::InProgress, attempts : 0, word : Word::new(word.to_string(), word_validated), alphabet : alphabet.to_string(), guesses : Vec::new()});
}
pub fn letter_is_in_place(_word: &str, letter: char, pos : usize) -> bool {
let (_first, _second) = _word.split_at(pos-1);
let mut letters = _second.chars();
return letter == letters.next().unwrap();
}
pub fn guess_word(&mut self, _guess: &str) -> Result<Word, GameError> {
match &self.status {
GameStatus::Won => Err(GameError::GameIsOver(GameStatus::Won)),
GameStatus::Lost => Err(GameError::GameIsOver(GameStatus::Lost)),
GameStatus::InProgress => {
let mut letters_original_copied = self.word.counting.clone();
if _guess.len() != self.word.word_original.len() {
let expected_to_pass = self.word.word_original.len();
let actual_to_pass = _guess.len();
return Err(GameError::WrongLength{expected : expected_to_pass , actual : actual_to_pass});
}
else if !Self::is_word_valid(self.alphabet.as_str() , _guess) {
return Err(GameError::NotInAlphabet(Self::get_invalid_char(self.alphabet.as_str() , _guess).unwrap()));
}
- else {
+ else {
+ let mut placed_guess_res = String::new();
+
if self.word.word_original == _guess {
self.status = GameStatus::Won;
+
+ for _c in _guess.chars() {
+ let current_letter = _c;
+ let to_push = String::from(format!("[{}]" , current_letter.to_uppercase()));
+ placed_guess_res.push_str(&to_push);
+ }
+
+ self.guesses.push(Some(placed_guess_res.clone()));
let to_push = Word::new(self.word.word_original.clone() , self.word.word_validated.clone());
return Ok(to_push);
}
else {
- let mut placed_guess_res = String::new();
let mut counter_iter = 0;
for c in _guess.chars() {
let current_letter = c;
counter_iter = counter_iter + 1;
if Self::letter_is_in_place(&self.word.word_original, current_letter, counter_iter) {
let curr_letter_to_push = String::from(format!("[{}]" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
let counter = 0;
for _i in self.word.counting.iter() {
if _i.letter == current_letter {
letters_original_copied[counter].count = letters_original_copied[counter].count - 1;
}
break;
}
}
else if self.word.word_original.contains(current_letter) {
let counter = 0;
for _i in self.word.counting.iter() {
if (_i.letter == current_letter) && (letters_original_copied[counter].count == 0) {
let curr_letter_to_push = String::from(format!(">{}<" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
break;
}
else {
let curr_letter_to_push = String::from(format!("({})" , c.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
letters_original_copied[counter].count = letters_original_copied[counter].count - 1;
break;
}
}
}
else {
let curr_letter_to_push = String::from(format!(">{}<" , current_letter.to_uppercase()));
placed_guess_res.push_str(&curr_letter_to_push);
}
}
self.guesses.push(Some(placed_guess_res.clone()));
+
+
self.attempts = self.attempts + 1;
if self.attempts == 5 {
self.status = GameStatus::Lost;
}
let to_push = Word::new(_guess.to_string() , placed_guess_res);
return Ok(to_push);
}
}
},
}
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.word_validated)
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut to_display = String::new();
for _i in self.word.word_original.chars() {
to_display.push_str("|_|");
}
for c in self.guesses.iter() {
to_display.push_str("\n");
to_display.push_str(&c.as_ref().unwrap().clone())
}
write!(f , "{}" , to_display)
}
}