diff --git a/81_Splat/rust/src/celestial_body.rs b/81_Splat/rust/src/celestial_body.rs index 4033ad31..594a3bcb 100644 --- a/81_Splat/rust/src/celestial_body.rs +++ b/81_Splat/rust/src/celestial_body.rs @@ -2,16 +2,16 @@ use rand::{prelude::SliceRandom, Rng}; #[derive(Debug)] pub enum CelestialBody { - Mercury, - Venus, - Earth, - Moon, - Mars, - Jupiter, - Saturn, - Uranus, - Neptune, - Sun, + MERCURY, + VENUS, + EARTH, + MOON, + MARS, + JUPITER, + SATURN, + URANUS, + NEPTUNE, + SUN, } impl CelestialBody { @@ -19,16 +19,16 @@ impl CelestialBody { use CelestialBody::*; match self { - Mercury => 12.2, - Venus => 28.3, - Earth => 32.16, - Moon => 5.12, - Mars => 12.5, - Jupiter => 85.2, - Saturn => 37.6, - Uranus => 33.8, - Neptune => 39.6, - Sun => 896., + MERCURY => 12.2, + VENUS => 28.3, + EARTH => 32.16, + MOON => 5.12, + MARS => 12.5, + JUPITER => 85.2, + SATURN => 37.6, + URANUS => 33.8, + NEPTUNE => 39.6, + SUN => 896., } } @@ -49,16 +49,16 @@ pub fn random_celestial_body() -> Option { use CelestialBody::*; match rand::thread_rng().gen_range(0..10) { - 0 => Some(Mercury), - 1 => Some(Venus), - 2 => Some(Earth), - 3 => Some(Moon), - 4 => Some(Mars), - 5 => Some(Jupiter), - 6 => Some(Saturn), - 7 => Some(Uranus), - 8 => Some(Neptune), - 9 => Some(Sun), + 0 => Some(MERCURY), + 1 => Some(VENUS), + 2 => Some(EARTH), + 3 => Some(MOON), + 4 => Some(MARS), + 5 => Some(JUPITER), + 6 => Some(SATURN), + 7 => Some(URANUS), + 8 => Some(NEPTUNE), + 9 => Some(SUN), _ => None, } } diff --git a/81_Splat/rust/src/game.rs b/81_Splat/rust/src/game.rs index b1df745c..7bad9b69 100644 --- a/81_Splat/rust/src/game.rs +++ b/81_Splat/rust/src/game.rs @@ -1,9 +1,17 @@ use crate::utility; -pub struct Game {} +pub struct Game { + altitude: f32, + terminal_velocity: f32, + acceleration: f32, + seconds: f32, + interval: f32, +} impl Game { pub fn new() -> Game { + let altitude = utility::get_altitude(); + let terminal_velocity = utility::get_terminal_velocity( "SELECT YOUR OWN TERMINAL VELOCITY", "WHAT TERMINAL VELOCITY (MI/HR)?", @@ -14,10 +22,95 @@ impl Game { "WHAT ACCELERATION (FT/SEC/SEC)?", ); - Game {} + println!(""); + println!(" ALTITUDE = {} FT", altitude); + println!(" TERM. VELOCITY = {} FT/SEC +-5%", terminal_velocity); + println!(" ACCELERATION = {} FT/SEC/SEC +-5%", acceleration); + + let seconds = + utility::prompt_numeric("\nSET THE TIMER FOR YOUR FREEFALL.\nHOW MANY SECONDS?"); + + println!("\nHERE WE GO.\n"); + + println!("TIME (SEC)\tDIST TO FALL (FT)"); + println!("==========\t================="); + + Game { + altitude, + terminal_velocity, + acceleration, + seconds, + interval: seconds / 8., + } } - pub fn tick(&self) -> Option { - todo!() + pub fn tick(&mut self) -> bool { + let mut splat = false; + let mut terminal_velocity_reached = false; + + let (v, a) = (self.terminal_velocity, self.acceleration); + let terminal_velocity_time = v / a; + + let mut final_altitude = self.altitude; + + for i in 0..=8 { + let dt = i as f32 * self.interval; + + if dt >= terminal_velocity_time { + if !terminal_velocity_reached { + println!( + "TERMINAL VELOCITY REACHED AT T PLUS {} SECONDS.", + terminal_velocity_time + ); + terminal_velocity_reached = true; + } + + let d1 = v.powi(2) / (2. * a); + let d2 = v * (dt - (terminal_velocity_time)); + final_altitude = self.altitude - (d1 + d2); + + if final_altitude <= 0. { + let t = (self.altitude - d1) / v; + utility::print_splat(t + terminal_velocity_time); + + splat = true; + break; + } + } else { + let d1 = (a * 0.5) * (dt.powi(2)); + final_altitude = self.altitude - d1; + + if final_altitude <= 0. { + let t = (2. * self.altitude * a).sqrt(); + utility::print_splat(t); + + splat = true; + break; + } + } + + println!("{}\t\t{}", dt, final_altitude); + + std::thread::sleep(std::time::Duration::from_secs(1)); + } + + if !splat { + println!("\nCHUTE OPEN\n") + + // get saved statistics from previous games + // compare and present a message. + } + + use utility::prompt_bool; + if !prompt_bool("DO YOU WANT TO PLAY AGAIN?", true) { + if !prompt_bool("PLEASE?", false) { + if !prompt_bool("YES OR NO PLEASE?", false) { + println!("SSSSSSSSSS."); + return false; + } + } + } + + true } } diff --git a/81_Splat/rust/src/main.rs b/81_Splat/rust/src/main.rs index 9a03fdb1..492bd2e3 100644 --- a/81_Splat/rust/src/main.rs +++ b/81_Splat/rust/src/main.rs @@ -10,21 +10,24 @@ fn main() { println!("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES"); println!("A PARACHUTE JUMP. TRY OPEN YOUR CHUTE AT THE"); - println!("LAST POSSIBLE MOMENT WITHOUT GOING SPLAT."); + println!("LAST POSSIBLE MOMENT WITHOUT GOING SPLAT.\n"); - let mut quit = false; + //let mut quit = false; - while !quit { - let game = Game::new(); + // while !quit { + loop { + let mut game = Game::new(); + if !game.tick() { + break; + } - loop { + /* loop { if let Some(play_again) = game.tick() { if !play_again { - println!("SSSSSSSSSS."); quit = true; } break; } - } + } */ } } diff --git a/81_Splat/rust/src/utility.rs b/81_Splat/rust/src/utility.rs index c57a8927..e4cbf2a7 100644 --- a/81_Splat/rust/src/utility.rs +++ b/81_Splat/rust/src/utility.rs @@ -10,8 +10,12 @@ pub fn read_line() -> String { input.trim().to_uppercase() } -pub fn prompt_bool(msg: &str) -> bool { - println!(" {} (YES OR NO)?", msg); +pub fn prompt_bool(msg: &str, template: bool) -> bool { + if template { + println!("{} (YES OR NO)?", msg); + } else { + println!("{}", msg); + } loop { let response = read_line(); @@ -38,23 +42,27 @@ pub fn prompt_numeric(msg: &str) -> f32 { } } +pub fn get_altitude() -> f32 { + 9001. * rand::random::() + 1000. +} + pub fn get_terminal_velocity(bool_msg: &str, num_msg: &str) -> f32 { let mut _num = 0.0; - if prompt_bool(bool_msg) { + if prompt_bool(bool_msg, true) { _num = prompt_numeric(num_msg); } else { - _num = rand::thread_rng().gen_range(0.0..=1000.0); + _num = get_random_float(0., 1000.); println!("OK. TERMINAL VELOCTY = {} MI/HR", _num); } - _num * ((5280 / 3600) as f32) + (_num * ((5280 / 3600) as f32)) * get_random_float(0.95, 1.05) } pub fn get_acceleration(bool_msg: &str, num_msg: &str) -> f32 { let mut _num = 0.0; - if prompt_bool(bool_msg) { + if prompt_bool(bool_msg, true) { _num = prompt_numeric(num_msg); } else { let b = @@ -64,5 +72,14 @@ pub fn get_acceleration(bool_msg: &str, num_msg: &str) -> f32 { b.print_acceleration_message(); } - _num + _num * get_random_float(0.95, 1.05) +} + +fn get_random_float(min: f32, max: f32) -> f32 { + rand::thread_rng().gen_range(min..=max) +} + +pub fn print_splat(t: f32) { + println!("{}\t\tSPLAT!", t); + //get random death message }