diff --git a/96_Word/rust/Cargo.toml b/96_Word/rust/Cargo.toml new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/96_Word/rust/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" diff --git a/96_Word/rust/src/main.rs b/96_Word/rust/src/main.rs new file mode 100644 index 00000000..707779a9 --- /dev/null +++ b/96_Word/rust/src/main.rs @@ -0,0 +1,52 @@ +use crate::word_game::WordGame; +use std::io; +mod progress; +mod word_game; + +fn main() { + println!("\n\n~~WORD~~"); + println!("Creative Computing Morristown, New Jersey"); + + println!("\nI am thinking of a word -- you guess it."); + println!("I will give you clues to help you get it."); + println!("Good luck!!\n"); + + let mut quit = false; + + while quit == false { + let mut game = WordGame::new(); + let mut game_over = false; + + while game_over == false { + game_over = game.tick(); + } + + quit = !play_again(); + } +} + +fn play_again() -> bool { + let mut again = true; + let mut valid_response = false; + + while valid_response == false { + println!("Want to play again? (Y/n)"); + + let mut response = String::new(); + + io::stdin() + .read_line(&mut response) + .expect("Failed to read line."); + + match response.trim().to_uppercase().as_str() { + "Y" | "YES" => valid_response = true, + "N" | "NO" => { + again = false; + valid_response = true; + } + _ => (), + } + } + + again +} diff --git a/96_Word/rust/src/progress.rs b/96_Word/rust/src/progress.rs new file mode 100644 index 00000000..46bf4d39 --- /dev/null +++ b/96_Word/rust/src/progress.rs @@ -0,0 +1,29 @@ +pub struct Progress { + chars: [char; 5], +} + +impl Progress { + pub fn new() -> Self { + Progress { chars: ['-'; 5] } + } + + pub fn set_char_at(&mut self, c: char, i: usize) { + self.chars[i] = c; + } + + pub fn print(&self) { + for c in self.chars { + print!("{}", c); + } + } + + pub fn done(&self) -> bool { + for c in self.chars { + if c == '-' { + return false; + } + } + + true + } +} diff --git a/96_Word/rust/src/word_game.rs b/96_Word/rust/src/word_game.rs new file mode 100644 index 00000000..6df72acb --- /dev/null +++ b/96_Word/rust/src/word_game.rs @@ -0,0 +1,113 @@ +use crate::progress::Progress; +use rand::Rng; +use std::io; + +pub struct WordGame<'a> { + word: &'a str, + progress: Progress, + guess: String, + guesses: usize, +} + +impl WordGame<'_> { + pub fn new() -> Self { + const WORDS: [&str; 12] = [ + "DINKY", "SMOKE", "WATER", "GRASS", "TRAIN", "MIGHT", "FIRST", "CANDY", "CHAMP", + "WOULD", "CLUMP", "DOPEY", + ]; + + println!("\nYou are starting a new game..."); + + let random_index: usize = rand::thread_rng().gen_range(0..WORDS.len()); + + //println!("word is: {}", WORDS[random_index]); + + WordGame { + word: WORDS[random_index], + progress: Progress::new(), + guess: String::new(), + guesses: 0, + } + } + + pub fn tick(&mut self) -> bool { + self.guesses += 1; + + println!("\n\nGuess a five letter word?"); + + let mut game_over = false; + + if WordGame::<'_>::read_guess(self) { + game_over = WordGame::<'_>::process_guess(self); + } + + game_over + } + + fn read_guess(&mut self) -> bool { + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line."); + + let invalid_input = |message: &str| { + println!("\n{} Guess again.", message); + return false; + }; + + let guess = guess.trim(); + + for c in guess.chars() { + if c.is_numeric() { + return invalid_input("Your guess cannot include numbers."); + } + if !c.is_ascii_alphabetic() { + return invalid_input("Your guess must only include ASCII characters."); + } + } + + if guess.len() != 5 { + return invalid_input("You must guess a 5 letter word."); + } + + self.guess = guess.to_string(); + + true + } + + fn process_guess<'a>(&mut self) -> bool { + let guess = self.guess.to_uppercase(); + + let mut matches: Vec = Vec::new(); + + for (i, c) in guess.chars().enumerate() { + if self.word.contains(c) { + matches.push(c); + + if self.word.chars().nth(i).unwrap() == c { + self.progress.set_char_at(c, i); + } + } + } + + println!( + "There were {} matches and the common letters were....{}", + matches.len(), + matches.into_iter().collect::() + ); + + print!("From the exact letter matches you know...."); + self.progress.print(); + + if self.progress.done() { + println!( + "\n\nYou have guessed the word. It took {} guesses!\n", + self.guesses + ); + return true; + } + + false + } +}