From c18a1004a5042ca360f92a0c08044c10b8419626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20K=C3=BCpeli?= Date: Tue, 4 Oct 2022 18:30:30 +0300 Subject: [PATCH 1/2] Rust implementation of 92 Trap --- 92_Trap/rust/src/lib.rs | 155 --------------------------------------- 92_Trap/rust/src/main.rs | 111 ++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 186 deletions(-) delete mode 100644 92_Trap/rust/src/lib.rs diff --git a/92_Trap/rust/src/lib.rs b/92_Trap/rust/src/lib.rs deleted file mode 100644 index d796a20a..00000000 --- a/92_Trap/rust/src/lib.rs +++ /dev/null @@ -1,155 +0,0 @@ -/* - lib.rs contains all the logic of the program -*/ -use rand::{Rng, prelude::thread_rng}; //rng -use std::error::Error; //better errors -use std::io::{self, Write}; //io interactions -use std::{str::FromStr, fmt::Display}; //traits - -//DATA - -/// handles setup for the game -pub struct Config { -} -impl Config { - /// creates and returns a new Config from user input - pub fn new() -> Result> { - //DATA - let config: Config = Config { - }; - - //return new config - return Ok(config); - } -} - -/// run the program -pub fn run(_config: &Config) -> Result<(), Box> { - //DATA - let mut rng = thread_rng(); - - let mut speed_train_1; - let mut time_difference; - let mut speed_train_2; - - let mut guess; - let mut answer; - - let mut error:f32; - - //Game loop - loop { - //initialize variables - speed_train_1 = rng.gen_range(40..65); - time_difference = rng.gen_range(5..20); - speed_train_2 = rng.gen_range(20..39); - - //print starting message / conditions - println!("A CAR TRAVELING {} MPH CAN MAKE A CERTAIN TRIP IN\n{} HOURS LESS THAN A TRAIN TRAVELING AT {} MPH",speed_train_1,time_difference,speed_train_2); - println!(); - - //get guess - guess = loop { - match get_number_from_input("HOW LONG DOES THE TRIP TAKE BY CAR?",0,-1) { - Ok(num) => break num, - Err(err) => { - eprintln!("{}",err); - continue; - }, - } - }; - - //calculate answer and error - answer = time_difference * speed_train_2 / (speed_train_1 - speed_train_2); - error = ((answer - guess) as isize).abs() as f32 * 100.0/(guess as f32) + 0.5; - - //check guess against answer - if error > 5.0 { - println!("SORRY, YOU WERE OFF BY {} PERCENT.", error); - println!("CORRECT ANSWER IS {} HOURS.",answer); - } else { - println!("GOOD! ANSWER WITHIN {} PERCENT.", error); - } - - //ask user if they want to go again - match get_string_from_user_input("ANOTHER PROBLEM (Y/N)") { - Ok(s) => if !s.to_uppercase().eq("Y") {break;} else {continue;}, - _ => break, - } - } - - //return to main - Ok(()) -} - -/// gets a string from user input -fn get_string_from_user_input(prompt: &str) -> Result> { - //DATA - let mut raw_input = String::new(); - - //print prompt - print!("{}", prompt); - //make sure it's printed before getting input - io::stdout().flush().expect("couldn't flush stdout"); - - //read user input from standard input, and store it to raw_input, then return it or an error as needed - raw_input.clear(); //clear input - match io::stdin().read_line(&mut raw_input) { - Ok(_num_bytes_read) => return Ok(String::from(raw_input.trim())), - Err(err) => return Err(format!("ERROR: CANNOT READ INPUT!: {}", err).into()), - } -} -/// generic function to get a number from the passed string (user input) -/// pass a min lower than the max to have minimum and maximum bounds -/// pass a min higher than the max to only have a minimum bound -/// pass a min equal to the max to only have a maximum bound -/// -/// Errors: -/// no number on user input -fn get_number_from_input(prompt: &str, min:T, max:T) -> Result> { - //DATA - let raw_input: String; - let processed_input: String; - - - //input loop - raw_input = loop { - match get_string_from_user_input(prompt) { - Ok(input) => break input, - Err(e) => { - eprintln!("{}",e); - continue; - }, - } - }; - - //filter out non-numeric characters from user input - processed_input = raw_input.chars().filter(|c| c.is_numeric()).collect(); - - //from input, try to read a number - match processed_input.trim().parse() { - Ok(i) => { - //what bounds must the input fall into - if min < max { //have a min and max bound: [min,max] - if i >= min && i <= max {//is input valid, within bounds - return Ok(i); //exit the loop with the value i, returning it - } else { //print error message specific to this case - return Err(format!("ONLY BETWEEN {} AND {}, PLEASE!", min, max).into()); - } - } else if min > max { //only a min bound: [min, infinity) - if i >= min { - return Ok(i); - } else { - return Err(format!("NO LESS THAN {}, PLEASE!", min).into()); - } - } else { //only a max bound: (-infinity, max] - if i <= max { - return Ok(i); - } else { - return Err(format!("NO MORE THAN {}, PLEASE!", max).into()); - } - } - }, - Err(_e) => return Err(format!("Error: couldn't find a valid number in {}",raw_input).into()), - } -} diff --git a/92_Trap/rust/src/main.rs b/92_Trap/rust/src/main.rs index 438f69be..5fc89876 100644 --- a/92_Trap/rust/src/main.rs +++ b/92_Trap/rust/src/main.rs @@ -1,41 +1,90 @@ -use std::process;//allows for some better error handling +use std::io::stdin; -mod lib; //allows access to lib.rs -use lib::Config; +use rand::Rng; -/// main function -/// responsibilities: -/// - Calling the command line logic with the argument values -/// - Setting up any other configuration -/// - Calling a run function in lib.rs -/// - Handling the error if run returns an error fn main() { - //greet user - welcome(); + println!("\n\t\tTRAP"); + println!("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n"); - // set up other configuration - let mut config = Config::new().unwrap_or_else(|err| { - eprintln!("Problem configuring program: {}", err); - process::exit(1); - }); + let max_guess = 6; + let max_number = 100; - // run the program - if let Err(e) = lib::run(&mut config) { - eprintln!("Application Error: {}", e); //use the eprintln! macro to output to standard error - process::exit(1); //exit the program with an error code + prompt_instructions(); + + loop { + let number = rand::thread_rng().gen_range(1..(max_number + 1)); + let mut guesses = 1u8; + + loop { + let (min, max) = prompt_numbers(guesses); + + if min == number && max == number { + println!("\nYou got it!!!"); + break; + } else if (min..=max).contains(&number) { + println!("You have trapped my number."); + } else if number < min { + println!("My number is smaller than your trap numbers."); + } else if number > max { + println!("My number is bigger than your trap numbers."); + } + + guesses += 1; + if guesses > max_guess { + println!("\nSorry, that was {max_guess} guesses. Number was {number}"); + break; + } + } + + println!("\nTry again."); } - - //end of program - println!("THANKS FOR PLAYING!"); } -/// print the welcome message -fn welcome() { - println!(" - Train - CREATIVE COMPUTING MORRISTOWN, NEW JERSEY +fn prompt_instructions() { + println!("Instructions?\t"); - -TIME - SPEED DISTANCE EXERCISE - "); + let mut input = String::new(); + if let Ok(_) = stdin().read_line(&mut input) { + match input.to_uppercase().trim() { + "YES" | "Y" => { + println!("\nI am thinking of a number between 1 and 100"); + println!("Try to guess my number. On each guess,"); + println!("you are to enter 2 numbers, trying to trap"); + println!("my number between the two numbers. I will"); + println!("tell you if you have trapped my number, if my"); + println!("number is larger than your two numbers, or if"); + println!("my number is smaller than your two numbers."); + println!("If you want to guess one single number, type"); + println!("your guess for both your trap numbers."); + println!("You get 6 guesses to get my number."); + } + _ => (), + } + } +} + +fn prompt_numbers(guess: u8) -> (u8, u8) { + loop { + let mut nums: Vec = Vec::new(); + println!("\nGuess # {guess} ?"); + + let mut input = String::new(); + if let Ok(_) = stdin().read_line(&mut input) { + let input: Vec<&str> = input.trim().split(",").collect(); + + for string in input { + if let Ok(number) = string.parse::() { + nums.push(number); + } else { + break; + } + } + + if nums.len() == 2 { + if nums[0] <= nums[1] { + return (nums[0], nums[1]); + } + } + } + } } From 06f2e8cc7ff83b6868a42ab0cc449692748be96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20K=C3=BCpeli?= Date: Tue, 4 Oct 2022 18:31:45 +0300 Subject: [PATCH 2/2] Rust implementation --- 92_Trap/rust/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/92_Trap/rust/README.md b/92_Trap/rust/README.md index 7e85f9a1..362bf922 100644 --- a/92_Trap/rust/README.md +++ b/92_Trap/rust/README.md @@ -1,3 +1,3 @@ Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html) -Conversion to [Rust](https://www.rust-lang.org/) by Anthony Rubick [AnthonyMichaelTDM](https://github.com/AnthonyMichaelTDM) +Conversion to [Rust](https://www.rust-lang.org/) by Uğur Küpeli [ugurkupeli](https://github.com/ugurkupeli) \ No newline at end of file