Решение на Wordle от Ива Манчевска

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

Към профила на Ива Манчевска

Резултати

  • 16 точки от тестове
  • 0 бонус точки
  • 16 точки общо
  • 12 успешни тест(а)
  • 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,
pub wordToGuess: String,
pub alphabet: String,
pub words: Vec<Word>,
}
#[derive(Debug)]
pub struct Word {
pub guess: String,
pub letters: Vec<Letter>,
}
#[derive(Debug,Clone)]
pub enum Letter {
Unknown(char),
FullMatch(char),
PartialMatch(char),
NoMatch(char),
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for c in word.chars() {
if alphabet.find(c)==None{
return Err(GameError::NotInAlphabet(c))
}
}
let mut letters = Vec::<Letter>::new();
for i in 1..word.chars().count()+1{
letters.push(Letter::Unknown('_'))
}
Ok(Game{
status: GameStatus::InProgress,
attempts: 0,
wordToGuess: word.to_string().to_uppercase(),
alphabet: alphabet.to_string().to_uppercase(),
words: vec![Word{guess:"".to_string(), letters: letters}]
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
if matches!(self.status, GameStatus::Won){
return Err(GameError::GameIsOver(GameStatus::Won))
}
if matches!(self.status, GameStatus::Lost){
return Err(GameError::GameIsOver(GameStatus::Lost))
}
if guess.to_uppercase().chars().count() != self.wordToGuess.to_uppercase().chars().count(){
return Err(GameError::WrongLength{
expected: self.wordToGuess.to_uppercase().chars().count(),
actual: guess.to_uppercase().chars().count(),
})
}
for c in guess.to_uppercase().chars() {
if !self.alphabet.contains(c){
return Err(GameError::NotInAlphabet(c))
}
}
let mut mainWord = &self.wordToGuess;
let mut letters = Vec::<Letter>::new();
let mut fullMatches=0;
for (i,c) in guess.to_uppercase().chars().enumerate() {
if c == mainWord.chars().nth(i).unwrap(){
fullMatches += 1;
letters.push(Letter::FullMatch(c))
}else{
if mainWord.contains(c){
letters.push(Letter::PartialMatch(c))
}else{
letters.push(Letter::NoMatch(c))
}
}
if fullMatches==mainWord.chars().count(){
let mut newStatus = GameStatus::Won;
std::mem::swap(&mut self.status, &mut newStatus);
}
}
self.attempts += 1;
if self.attempts == 5{
let mut newStatus = GameStatus::Lost;
std::mem::swap(&mut self.status, &mut newStatus);
}
self.words.push( Word{
guess: guess.to_string(),
letters: letters.to_vec(),
});
return Ok(Word{
guess: guess.to_string(),
letters: letters.to_vec(),
})
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
self.letters.iter().map(|l| {
match l{
Letter::Unknown(x) => write!(f, "|{}|", x),
Letter::FullMatch(x) => write!(f,"[{}]",x.to_uppercase()),
Letter::PartialMatch(x) => write!(f,"({})",x.to_uppercase()),
Letter::NoMatch(x) => write!(f,">{}<",x.to_uppercase()),
}
}).collect()
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let count = self.words.iter().count();
self.words.iter().enumerate().map(|(i,w)|{
if i < count-1{
write!(f, "{}\n", w)
}else{
write!(f, "{}", w)
}
}).collect()
}
}
#[cfg(test)]
#[test]
fn test_basic() {
let english_letters = "abcdefghijklmnopqrstuvwxyz";
assert!(Game::new(english_letters, "!!!").is_err());
let mut game = Game::new(&String::from(english_letters), "abc").unwrap();
assert!(matches!(game.status, GameStatus::InProgress));
assert_eq!(game.attempts, 0);
assert_eq!(game.to_string(), "|_||_||_|");
assert_eq!(game.guess_word("abc").unwrap().to_string(), "[A][B][C]");
}

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

Compiling solution v0.1.0 (/tmp/d20230111-3772066-jndfcy/solution)
warning: unused variable: `i`
  --> src/lib.rs:46:13
   |
46 |         for i in 1..word.chars().count()+1{
   |             ^ help: if this is intentional, prefix it with an underscore: `_i`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: variable does not need to be mutable
  --> src/lib.rs:78:17
   |
78 |             let mut mainWord = &self.wordToGuess;
   |                 ----^^^^^^^^
   |                 |
   |                 help: remove this `mut`
   |
   = note: `#[warn(unused_mut)]` on by default

warning: structure field `wordToGuess` should have a snake case name
  --> src/lib.rs:19:9
   |
19 |     pub wordToGuess: String,
   |         ^^^^^^^^^^^ help: convert the identifier to snake case: `word_to_guess`
   |
   = note: `#[warn(non_snake_case)]` on by default

warning: variable `mainWord` should have a snake case name
  --> src/lib.rs:78:21
   |
78 |             let mut mainWord = &self.wordToGuess;
   |                     ^^^^^^^^ help: convert the identifier to snake case: `main_word`

warning: variable `fullMatches` should have a snake case name
  --> src/lib.rs:80:21
   |
80 |             let mut fullMatches=0;
   |                     ^^^^^^^^^^^ help: convert the identifier to snake case: `full_matches`

warning: variable `newStatus` should have a snake case name
  --> src/lib.rs:93:29
   |
93 |                     let mut newStatus = GameStatus::Won;
   |                             ^^^^^^^^^ help: convert the identifier to snake case: `new_status`

warning: variable `newStatus` should have a snake case name
  --> src/lib.rs:99:25
   |
99 |                 let mut newStatus = GameStatus::Lost;
   |                         ^^^^^^^^^ help: convert the identifier to snake case: `new_status`

warning: `solution` (lib) generated 7 warnings
    Finished test [unoptimized + debuginfo] target(s) in 0.86s
     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 ... ok
test solution_test::test_word_display ... ok
test solution_test::test_game_state_3 ... ok
test solution_test::test_word_display_bulgarian ... ok
test solution_test::test_word_display_german ... FAILED
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_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 ... FAILED
test solution_test::test_wrong_length ... ok

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_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_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


failures:
    solution_test::test_game_display_german
    solution_test::test_word_display_german
    solution_test::test_word_not_in_alphabet_on_guess_cyrillic

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`

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

Ива качи първо решение на 24.11.2022 14:56 (преди почти 3 години)

Ива качи решение на 24.11.2022 16:56 (преди почти 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,
pub wordToGuess: String,
pub alphabet: String,
pub words: Vec<Word>,
}
#[derive(Debug)]
pub struct Word {
pub guess: String,
pub letters: Vec<Letter>,
}
#[derive(Debug,Clone)]
pub enum Letter {
Unknown(char),
FullMatch(char),
PartialMatch(char),
NoMatch(char),
}
impl Game {
pub fn new(alphabet: &str, word: &str) -> Result<Self, GameError> {
for c in word.chars() {
if alphabet.find(c)==None{
return Err(GameError::NotInAlphabet(c))
}
}
let mut letters = Vec::<Letter>::new();
for i in 1..word.chars().count()+1{
letters.push(Letter::Unknown('_'))
}
Ok(Game{
status: GameStatus::InProgress,
attempts: 0,
wordToGuess: word.to_string().to_uppercase(),
alphabet: alphabet.to_string().to_uppercase(),
words: vec![Word{guess:"".to_string(), letters: letters}]
})
}
pub fn guess_word(&mut self, guess: &str) -> Result<Word, GameError> {
if matches!(self.status, GameStatus::Won){
return Err(GameError::GameIsOver(GameStatus::Won))
}
if matches!(self.status, GameStatus::Lost){
return Err(GameError::GameIsOver(GameStatus::Lost))
}
- if guess.chars().count() != self.wordToGuess.chars().count(){
+ if guess.to_uppercase().chars().count() != self.wordToGuess.to_uppercase().chars().count(){
return Err(GameError::WrongLength{
- expected: self.wordToGuess.chars().count(),
- actual: guess.chars().count(),
+ expected: self.wordToGuess.to_uppercase().chars().count(),
+ actual: guess.to_uppercase().chars().count(),
})
}
for c in guess.to_uppercase().chars() {
if !self.alphabet.contains(c){
return Err(GameError::NotInAlphabet(c))
}
}
let mut mainWord = &self.wordToGuess;
let mut letters = Vec::<Letter>::new();
let mut fullMatches=0;
for (i,c) in guess.to_uppercase().chars().enumerate() {
if c == mainWord.chars().nth(i).unwrap(){
fullMatches += 1;
letters.push(Letter::FullMatch(c))
}else{
if mainWord.contains(c){
letters.push(Letter::PartialMatch(c))
}else{
letters.push(Letter::NoMatch(c))
}
}
if fullMatches==mainWord.chars().count(){
let mut newStatus = GameStatus::Won;
std::mem::swap(&mut self.status, &mut newStatus);
}
}
self.attempts += 1;
if self.attempts == 5{
let mut newStatus = GameStatus::Lost;
std::mem::swap(&mut self.status, &mut newStatus);
}
self.words.push( Word{
guess: guess.to_string(),
letters: letters.to_vec(),
});
return Ok(Word{
guess: guess.to_string(),
letters: letters.to_vec(),
})
}
}
use std::fmt;
impl fmt::Display for Word {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
self.letters.iter().map(|l| {
match l{
Letter::Unknown(x) => write!(f, "|{}|", x),
Letter::FullMatch(x) => write!(f,"[{}]",x.to_uppercase()),
Letter::PartialMatch(x) => write!(f,"({})",x.to_uppercase()),
Letter::NoMatch(x) => write!(f,">{}<",x.to_uppercase()),
}
}).collect()
}
}
impl fmt::Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let count = self.words.iter().count();
self.words.iter().enumerate().map(|(i,w)|{
if i < count-1{
write!(f, "{}\n", w)
}else{
write!(f, "{}", w)
}
}).collect()
}
}
#[cfg(test)]
#[test]
fn test_basic() {
let english_letters = "abcdefghijklmnopqrstuvwxyz";
assert!(Game::new(english_letters, "!!!").is_err());
let mut game = Game::new(&String::from(english_letters), "abc").unwrap();
assert!(matches!(game.status, GameStatus::InProgress));
assert_eq!(game.attempts, 0);
assert_eq!(game.to_string(), "|_||_||_|");
assert_eq!(game.guess_word("abc").unwrap().to_string(), "[A][B][C]");
-}
-
-fn main(){
-
}