123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- 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<u32> for Hanger {
- type Error = ();
- fn try_from(v: u32) -> Result<Self, Self::Error> {
- 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<char>,
- input_vec: Vec<char>,
- 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<char> = 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<usize> = self.word.chars().enumerate().map(
- |(index, char)| {
- if char == letter {
- return index + 1
- }
- else {
- return 0;
- }
- }
- ).filter(
- |item| item != &0
- ).collect::<Vec<usize>>();
- 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<T: FromStr>(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::<T>() {
- 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!("❎")
- }
- }
- }
|