use std::{io::stdin, str::FromStr}; enum GameStatus { InProgress, Win, Fail, } enum Hanger { Base, BaseWithPost, BaseWithHanger, HangedHead, HangedTorso, HangedRHand, HangedLHand, HangedRLeg, HangedLLeg, } impl Hanger { fn draw(&self) -> String{ match self { Hanger::Base => { r#" ____________ ___/ \____ "#.to_owned() }, Hanger::BaseWithPost => { r#" | | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::BaseWithHanger => { r#" ________ | | | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedHead => { r#" ________ | | o | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedTorso => { r#" ________ | | o | | | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedRHand => { r#" ________ | | o | |\ | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedLHand => { r#" ________ | | o | /|\ | | | | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedRLeg => { r#" ________ | | o | /|\ | | | \ | ________|___ ___/ \____ "#.to_owned() }, Hanger::HangedLLeg => { r#" ________ | | o | /|\ | | | / \ | ________|___ ___/ \____ "#.to_owned() }, } } } impl TryFrom for Hanger { type Error = (); fn try_from(v: u32) -> Result { match v { x if x == Hanger::Base as u32 => Ok(Hanger::Base), x if x == Hanger::BaseWithPost as u32 => Ok(Hanger::BaseWithPost), x if x == Hanger::BaseWithHanger as u32 => Ok(Hanger::BaseWithHanger), x if x == Hanger::HangedHead as u32 => Ok(Hanger::HangedHead), x if x == Hanger::HangedTorso as u32 => Ok(Hanger::HangedTorso), x if x == Hanger::HangedRHand as u32 => Ok(Hanger::HangedRHand), x if x == Hanger::HangedLHand as u32 => Ok(Hanger::HangedLHand), x if x == Hanger::HangedRLeg as u32 => Ok(Hanger::HangedRLeg), x if x == Hanger::HangedLLeg as u32 => Ok(Hanger::HangedLLeg), _ => Err(()), } } } struct HangedManWord { word_vec: Vec, input_vec: Vec, word: String, counter_def: u32, counter: u32, counter_err: u32, hanger_art: Hanger } impl HangedManWord { fn new(word: String, counter_def: u32) -> Self { let word_vec = Vec::from_iter( std::iter::repeat('_').take(word.chars().count()) ); let input_vec: Vec = Vec::new(); HangedManWord { word_vec, input_vec, word, counter_def, counter: 0, counter_err: 0, hanger_art: Hanger::Base } } fn check_letter(&mut self, letter: char) -> bool{ self.input_vec.push(letter); let indices: Vec = self.word.chars().enumerate().map( |(index, char)| { if char == letter { return index + 1 } else { return 0; } } ).filter( |item| item != &0 ).collect::>(); for index in indices.clone() { self.word_vec[index-1] = letter } self.counter += 1; if indices.is_empty() { self.counter_err += 1; self.hanger_art = Hanger::try_from(self.counter_err).unwrap_or(Hanger::Base); return false } true } fn check_complete(&self) -> bool { !self.word_vec.contains(&'_') } fn check_status(&self) -> GameStatus { if self.counter_def <= self.counter_err { return GameStatus::Fail; } if self.check_complete() { return GameStatus::Win; } GameStatus::InProgress } } fn input(print: String, error_msg: String, type_error_msg: String) -> T { println!("{}", print); let result: T; let mut input_buff = String::new(); loop { input_buff.clear(); match stdin().read_line(&mut input_buff) { Ok(_) => {} Err(_) => { println!("{}", error_msg); continue; } }; result = match input_buff.trim().parse::() { Ok(res) => res, Err(_) => { println!("{}", type_error_msg); continue; } }; break; } result } fn main() { let word: String = input( "Введите слово".to_owned(), "Повторите ввод".to_owned(), "".to_owned() ); let counter_def: u32 = 8; // input( // "Введите количество возможных ошибок".to_owned(), // "Повторите ввод".to_owned(), // "Введите положительное число".to_owned() // ); let mut hm_word = HangedManWord::new(word,counter_def); for _ in 0..100 { println!() } let mut correct: bool; loop { println!("{:}", hm_word.hanger_art.draw()); println!("Уже введено: {:?}", hm_word.input_vec); println!("{:?}", hm_word.word_vec); match hm_word.check_status() { GameStatus::Win => { println!( "Вы ПОБЕДИЛИ. Кол-во введенных букв: {:}. Кол-во ошибок: {:}/{:}", hm_word.counter, hm_word.counter_err, hm_word.counter_def ); break; } GameStatus::Fail => { println!( "Вы ПРОИГРАЛИ. Загаданные слово: {:} Кол-во введенных букв: {:}. Кол-во ошибок: {:}/{:}", hm_word.word, hm_word.counter, hm_word.counter_err, hm_word.counter_def ); break; } GameStatus::InProgress => () } let letter: char = input( "Введите букву".to_owned(), "Повторите ввод".to_owned(), "Введите одну букву".to_owned() ); correct = hm_word.check_letter(letter); match correct { true => println!("✅"), false => println!("❎") } } }