diff --git a/05_Bagels/rust/Cargo.toml b/05_Bagels/rust/Cargo.toml new file mode 100644 index 00000000..3b1d02f5 --- /dev/null +++ b/05_Bagels/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/05_Bagels/rust/README.md b/05_Bagels/rust/README.md new file mode 100644 index 00000000..90780c4d --- /dev/null +++ b/05_Bagels/rust/README.md @@ -0,0 +1,3 @@ +Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) + +Conversion to [Rust](https://www.rust-lang.org/) by Till Klister [tikste@github](https://github.com/tikste). diff --git a/05_Bagels/rust/src/main.rs b/05_Bagels/rust/src/main.rs new file mode 100644 index 00000000..8a59ce7f --- /dev/null +++ b/05_Bagels/rust/src/main.rs @@ -0,0 +1,131 @@ +use std::io; +use std::io::{stdin, stdout, Write}; + +use rand::prelude::SliceRandom; + +type Digits = [u8; 3]; + +fn main() -> io::Result<()> { + print_header(); + if !read_lowercase_input()?.starts_with('n') { + print_rules(); + } + let mut win_count = 0; + loop { + let solution = generate_random_digits(); + println!("\nO.K. I have a number in mind."); + if guess(solution)? { + win_count += 1; + println!("You got it!!!"); + } else { + println!( + "\nOh well\nThat's twenty guesses: My number was {}{}{}", + solution[0], solution[1], solution[2] + ); + } + println!("\nPlay again (yes or no)?"); + if read_lowercase_input()? != "yes" { + println!(); + if win_count > 0 { + println!("A {win_count} point bagels buff!!"); + } + println!("Hope you had fun. Bye."); + return Ok(()); + } + } +} + +fn print_header() { + println!(" Bagels"); + println!("Creative-Computing Morristown, New Jersey"); + println!(); + println!("Would you like the rules (yes or no)?"); +} + +fn print_rules() { + println!(); + println!("I am thinking of a three-digit number. Try to guess"); + println!("my number and I will give you clues as follows:"); + println!(" Pico - one digit correct but in the wrong position"); + println!(" Fermi - one digit correct and in the right position"); + println!(" Bagles - no digits correct"); +} + +fn read_lowercase_input() -> io::Result { + let mut input = String::new(); + stdin().read_line(&mut input)?; + Ok(input.trim().to_lowercase()) +} + +fn generate_random_digits() -> Digits { + let range = 0..10; + let mut numbers = range.into_iter().collect::>(); + numbers.shuffle(&mut rand::thread_rng()); + let mut digits = Digits::default(); + let len = digits.len(); + digits.copy_from_slice(&numbers[..len]); + digits +} + +fn guess(solution: Digits) -> io::Result { + for round in 1..21 { + let guess = read_valid_guess(round)?; + if guess == solution { + return Ok(true); + } else { + let mut pico = 0; + let mut fermi = 0; + for i in 0..guess.len() { + if guess[i] == solution[i] { + fermi += 1; + } else if solution.contains(&guess[i]) { + pico += 1; + } + } + let mut status = String::new(); + if pico == 0 && fermi == 0 { + status += "Bagels"; + } else { + for _ in 0..pico { + status += "Pico "; + } + for _ in 0..fermi { + status += "Fermi "; + } + }; + println!("{}", status.trim_end()); + } + } + Ok(false) +} + +fn read_valid_guess(round: u8) -> io::Result { + let mut guess = Digits::default(); + loop { + let space = " ".repeat(if round < 10 { 5 } else { 4 }); + print!("Guess #{round}{space}? "); + stdout().flush()?; + let input = read_lowercase_input()?; + if input.len() == guess.len() { + let mut i = 0; + for c in input.chars() { + if let Ok(digit) = c.to_string().parse::() { + if guess[..i].contains(&digit) { + println!("\nOh, I forgot to tell you that the number I have in mind\nhas no two digits the same."); + break; + } + guess[i] = digit; + i += 1; + if i == guess.len() { + return Ok(guess); + } + } else { + println!("What?"); + break; + } + } + } else { + println!("Try guessing a three-digit number."); + } + } +}