use rand::RngExt; use rand_distr::Binomial; use std::env; use std::io; fn main() { let args = env::args().skip(1).collect::>(); let options = Options::from_args(&args); guess(&options) } struct Options { min: u32, max: u32, use_normal: bool, } impl Options { fn parse(&mut self, args: &Vec) { let mut args = args.iter(); while let Some(arg) = args.next() { match arg.as_str() { "--normal" => self.use_normal = true, "--max" | "-m" => { let max_value = args .next() .expect("Number proceeding --max should be a number"); self.max = max_value .trim() .parse() .expect("Number proceeding --max should be a number"); } "--min" => { let min_value = args .next() .expect("Number proceeding --min should be a number"); self.min = min_value .trim() .parse() .expect("Number proceeding --min should be a number"); } _ => panic!("Unrecognized argument {:?}", arg), } } if self.max < self.min { panic!("min > max, wtf are you even talking about?"); } } fn from_args(args: &Vec) -> Options { let mut opts = Options::new(); opts.parse(args); opts } fn new() -> Options { Options { use_normal: false, min: 0, max: 10, } } } fn random_uniform_range(min: u32, max: u32) -> u32 { let diff = max - min; (rand::random::() % diff) + min } fn random_binomial_range(min: u32, max: u32) -> u32 { let diff = max - min; let bin = Binomial::new(diff as u64, 0.5).expect("Could not make range"); rand::rng().sample(bin) as u32 + min } fn guess(opts: &Options) { let to_guess: u32 = match opts.use_normal { true => random_binomial_range(opts.min, opts.max), false => random_uniform_range(opts.min, opts.max), }; let mut input_string = String::new(); println!( "Enter a number in the range {}<=guess<{}", opts.min, opts.max ); io::stdin() .read_line(&mut input_string) .expect("Could not read string"); let input_number = input_string .trim() .parse::() .expect("Could not parse input"); if input_number == to_guess { println!("You got it right!"); } else { println!("The correct number was {}!", to_guess); } }