Решение на Hangman от Иван Велков
Резултати
- 12 точки от тестове
- 0 бонус точки
- 12 точки общо
- 12 успешни тест(а)
- 3 неуспешни тест(а)
Код
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20171210-6053-1f9d1m1/solution) warning: unused import: `Write` --> src/lib.rs:1:31 | 1 | use std::fmt::{self, Display, Write}; | ^^^^^ | = note: #[warn(unused_imports)] on by default warning: unused import: `Write` --> src/lib.rs:1:31 | 1 | use std::fmt::{self, Display, Write}; | ^^^^^ | = note: #[warn(unused_imports)] on by default Finished dev [unoptimized + debuginfo] target(s) in 5.18 secs Running target/debug/deps/solution-3f98bfa5c86a5dd9 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/solution_test-3d9e4ea2eafbbc82 running 15 tests test solution_test::test_command_parsing_cyrillic ... FAILED test solution_test::test_command_parsing_extra_stuff ... ok test solution_test::test_command_parsing_full_words ... ok test solution_test::test_command_parsing_partial_words ... ok test solution_test::test_command_parsing_spacing ... ok test solution_test::test_command_parsing_special ... FAILED test solution_test::test_game_basic ... ok test solution_test::test_game_cyrillic ... ok test solution_test::test_game_display ... ok test solution_test::test_game_error ... ok test solution_test::test_game_guess_basic ... FAILED test solution_test::test_game_guess_state_lose ... ok test solution_test::test_game_guess_state_won ... ok test solution_test::test_game_guess_word ... ok test solution_test::test_game_over_guesses ... ok failures: ---- solution_test::test_command_parsing_cyrillic stdout ---- thread 'solution_test::test_command_parsing_cyrillic' panicked at 'Expected Ok(Command::TryLetter('\u{44f}')) to match Err(ParseError("kek"))', tests/solution_test.rs:235:4 note: Run with `RUST_BACKTRACE=1` for a backtrace. ---- solution_test::test_command_parsing_special stdout ---- thread 'solution_test::test_command_parsing_special' panicked at 'Expected Ok(Command::TryLetter('\u{44f}')) to match Err(ParseError("kek"))', tests/solution_test.rs:194:4 ---- solution_test::test_game_guess_basic stdout ---- thread 'solution_test::test_game_guess_basic' panicked at 'assertion failed: `(left == right)` left: `10`, right: `9`', tests/solution_test.rs:84:4 failures: solution_test::test_command_parsing_cyrillic solution_test::test_command_parsing_special solution_test::test_game_guess_basic test result: FAILED. 12 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (2 версии и 1 коментар)
Иван качи решение на 08.12.2017 16:48 (преди почти 8 години)
use std::fmt::{self, Display, Write};
use std::str::FromStr;
use std::collections::HashSet;
#[derive(Debug)]
pub enum GameError {
ParseError(String),
BadGuess(String),
InvalidSolution(String),
GameOver,
}
impl Display for GameError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
GameError::ParseError(_) => write!(f, "error!"),
GameError::BadGuess(_) => write!(f, "error!"),
GameError::InvalidSolution(_) => write!(f, "error!"),
GameError::GameOver => write!(f, "Хлип, хлип - толкос!"),
}
}
}
#[derive(Debug)]
pub enum Command {
TryLetter(char),
TryWord(String),
Info,
Help,
Quit,
}
impl FromStr for Command {
type Err = GameError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let cmd = s.to_lowercase();
let mut iter = cmd.split_whitespace();
+ // този код ми дава лошо,
+ // нямах време да разучавам за по адекватни варианти,
+ // каквито предполагам има с try! или ? , ама кек
Ами, сега имаш доста варианти, които можеш да погледнеш, ей тук: https://fmi.rust-lang.bg/tasks/4/solutions :)
match iter.next() {
Some(arg) => {
match arg.chars().nth(0).unwrap() {
'i' => return Ok(Command::Info),
'h' => return Ok(Command::Help),
'q' => return Ok(Command::Quit),
't' => {
match iter.next() {
Some(kek) => {
match kek.chars().nth(0).unwrap() {
'l' => {
match iter.next() {
Some(val) => {
if val.len() == 1 {
return Ok(Command::TryLetter(val.chars().nth(0).unwrap()))
}
return Err(GameError::ParseError(String::from("kek")))
}
_ => return Err(GameError::ParseError(String::from("kek")))
}
},
'w' => {
match iter.next() {
Some(val) => {
return Ok(Command::TryWord(String::from(val)))
}
_ => return Err(GameError::ParseError(String::from("kek")))
}
},
_ => return Err(GameError::ParseError(String::from("kek")))
}
}
_ => return Err(GameError::ParseError(String::from("kek")))
}
},
_ => return Err(GameError::ParseError(String::from("kek")))
}
},
None => return Err(GameError::ParseError(String::from("kek")))
}
}
}
pub struct Game {
pub attempted_letters: HashSet<char>,
pub attempted_words: HashSet<String>,
pub attempts_remaining: u32,
is_continuing: bool,
answer: String,
letters_remaining: u32
}
impl Game {
pub fn new(solution: &str, attempts: u32) -> Result<Self, GameError> {
if solution.is_empty() || solution.find(|x| char::is_alphabetic(x) == false) != None {
return Err(GameError::InvalidSolution(String::from("kek!")));
}
let mut letters = HashSet::new();
for i in solution.chars() {
letters.insert(i);
}
Ok(Self {
attempted_letters: HashSet::new(),
attempted_words: HashSet::new(),
attempts_remaining: attempts,
is_continuing: attempts != 0,
answer: String::from(solution),
letters_remaining: letters.len() as u32
})
}
pub fn guess_letter(&mut self, guess: char) -> Result<bool, GameError> {
if self.is_over() {
return Err(GameError::GameOver)
}
if self.attempted_letters.insert(guess) {
if self.answer.find(guess) != None {
self.letters_remaining -= 1;
if self.letters_remaining == 0 {
self.is_continuing = false;
}
else {
self.make_turn();
}
return Ok(true)
}
else {
self.make_turn();
return Ok(false)
}
}
Err(GameError::BadGuess(String::from("kek")))
}
pub fn guess_word(&mut self, guess: &str) -> Result<bool, GameError> {
if self.is_over() {
return Err(GameError::GameOver)
}
if self.attempted_words.insert(String::from(guess)) {
if self.answer == guess {
self.is_continuing = false;
return Ok(true)
}
else {
self.make_turn();
return Ok(false)
}
}
Err(GameError::BadGuess(String::from("kek")))
}
pub fn is_over(&self) -> bool {
!self.is_continuing
}
fn make_turn(&mut self) {
self.attempts_remaining -= 1;
self.is_continuing = self.attempts_remaining != 0;
}
}
impl Display for Game {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_over() {
if self.attempts_remaining == 0 {
return write!(f, "lost {:?}", self.answer)
}
return write!(f, "won {:?}", self.answer)
}
let mut res = String::new();
for i in self.answer.chars() {
if self.attempted_letters.contains(&i) {
res.push(i);
}
else {
res.push('_');
}
res.push(' ');
}
write!(f, "{:?} {:?}", self.attempts_remaining, res)
}
}
Ами, сега имаш доста варианти, които можеш да погледнеш, ей тук: https://fmi.rust-lang.bg/tasks/4/solutions :)