From 6ac6ed36ef765dff8c2e53982d4f03d7e14fb7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?U=C4=9Fur=20K=C3=BCpeli?= Date: Thu, 5 May 2022 00:22:30 +0300 Subject: [PATCH] Final --- 81_Splat/rust/src/game.rs | 39 ++++++---------- 81_Splat/rust/src/main.rs | 28 +++++++----- 81_Splat/rust/src/stats.rs | 88 ++++++++++++++++++++++++++++++++++++ 81_Splat/rust/src/utility.rs | 63 +++++++++++++++++++++++++- 4 files changed, 181 insertions(+), 37 deletions(-) create mode 100644 81_Splat/rust/src/stats.rs diff --git a/81_Splat/rust/src/game.rs b/81_Splat/rust/src/game.rs index 6f2b4872..8b3bba18 100644 --- a/81_Splat/rust/src/game.rs +++ b/81_Splat/rust/src/game.rs @@ -4,7 +4,6 @@ pub struct Game { altitude: f32, terminal_velocity: f32, acceleration: f32, - seconds: f32, interval: f32, } @@ -39,19 +38,18 @@ impl Game { altitude, terminal_velocity, acceleration, - seconds, interval: seconds / 8., } } - pub fn tick(&mut self) -> bool { + pub fn tick(&mut self) -> f32 { 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; + let initial_altitude = self.altitude; for i in 0..=8 { let dt = i as f32 * self.interval; @@ -67,10 +65,10 @@ impl Game { let d1 = v.powi(2) / (2. * a); let d2 = v * (dt - (terminal_velocity_time)); - final_altitude = self.altitude - (d1 + d2); + self.altitude = initial_altitude - (d1 + d2); - if final_altitude <= 0. { - let t = (self.altitude - d1) / v; + if self.altitude <= 0. { + let t = (initial_altitude - d1) / v; utility::print_splat(t + terminal_velocity_time); splat = true; @@ -78,10 +76,10 @@ impl Game { } } else { let d1 = (a * 0.5) * (dt.powi(2)); - final_altitude = self.altitude - d1; + self.altitude = initial_altitude - d1; - if final_altitude <= 0. { - let t = (2. * self.altitude * a).sqrt(); + if self.altitude <= 0. { + let t = (2. * initial_altitude / a).sqrt(); utility::print_splat(t); splat = true; @@ -89,28 +87,19 @@ impl Game { } } - println!("{}\t\t{}", dt, final_altitude); + println!("{}\t\t{}", dt, self.altitude); std::thread::sleep(std::time::Duration::from_secs(1)); } + let mut a = -1.; + if !splat { - println!("\nCHUTE OPEN\n") + println!("\nCHUTE OPEN\n"); - // get saved statistics from previous games - // compare and present a message. + a = self.altitude; } - 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 + a } } diff --git a/81_Splat/rust/src/main.rs b/81_Splat/rust/src/main.rs index 492bd2e3..eec8bfe6 100644 --- a/81_Splat/rust/src/main.rs +++ b/81_Splat/rust/src/main.rs @@ -1,7 +1,8 @@ -use crate::game::Game; +use crate::{game::Game, stats::Stats}; mod celestial_body; mod game; +mod stats; mod utility; fn main() { @@ -12,22 +13,27 @@ fn main() { println!("A PARACHUTE JUMP. TRY OPEN YOUR CHUTE AT THE"); println!("LAST POSSIBLE MOMENT WITHOUT GOING SPLAT.\n"); - //let mut quit = false; + let mut stats = Stats::new(); - // while !quit { loop { let mut game = Game::new(); - if !game.tick() { - break; + + let latest_altitude = game.tick(); + + if latest_altitude > 0. { + if let Some(s) = &mut stats { + s.add_altitude(latest_altitude); + } } - /* loop { - if let Some(play_again) = game.tick() { - if !play_again { - quit = true; + 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."); + break; } - break; } - } */ + } } } diff --git a/81_Splat/rust/src/stats.rs b/81_Splat/rust/src/stats.rs new file mode 100644 index 00000000..c86b83ae --- /dev/null +++ b/81_Splat/rust/src/stats.rs @@ -0,0 +1,88 @@ +use std::{ + fs::{self, File}, + io::Write, +}; + +use crate::utility; + +pub struct Stats { + altitudes: Vec, +} + +impl Stats { + pub fn new() -> Option { + if utility::prompt_bool("WOULD YOU LIKE TO LOAD PREVIOUS GAME DATA?", false) { + let path = "src/stats.txt"; + let mut altitudes = Vec::new(); + + if let Ok(stats) = fs::read_to_string(path) { + if stats.is_empty() { + return Some(Stats { + altitudes: Vec::new(), + }); + } + + let stats: Vec<&str> = stats.trim().split(",").collect(); + + for s in stats { + if s.is_empty() { + continue; + } + + let s = s.parse::().expect("Corrupt stats file!"); + altitudes.push(s); + } + + return Some(Stats { altitudes }); + } else { + println!("PREVIOUS GAME DATA NOT FOUND!"); + + if !utility::prompt_bool("WOULD YOU LIKE TO CREATE ONE?", false) { + return None; + } else { + let mut file = File::create(path).expect("Invalid file path!"); + file.write_all("".as_bytes()) + .expect("Could not create file!"); + + return Some(Stats { + altitudes: Vec::new(), + }); + } + } + } + + println!("\nRESULTS OF THIS SESSION WILL NOT BE SAVED."); + None + } + + pub fn add_altitude(&mut self, a: f32) { + let all_jumps = self.altitudes.len() + 1; + let mut placement = all_jumps; + + for (i, altitude) in self.altitudes.iter().enumerate() { + if a <= *altitude { + placement = i + 1; + break; + } + } + + utility::print_win(all_jumps, placement); + + self.altitudes.push(a); + self.altitudes.sort_by(|a, b| a.partial_cmp(b).unwrap()); + + self.write(); + } + + fn write(&self) { + let mut file = File::create("src/stats.txt").expect("Error loading stats data!"); + + let mut altitudes = String::new(); + + for a in &self.altitudes { + altitudes.push_str(format!("{},", a).as_str()); + } + + write!(&mut file, "{}", altitudes.trim()).expect("ERROR WRITING Stats FILE!"); + } +} diff --git a/81_Splat/rust/src/utility.rs b/81_Splat/rust/src/utility.rs index c1118747..c37a2af3 100644 --- a/81_Splat/rust/src/utility.rs +++ b/81_Splat/rust/src/utility.rs @@ -94,6 +94,7 @@ fn get_random_float(min: f32, max: f32) -> f32 { pub fn print_splat(t: f32) { print_random(format!("{}\t\tSPLAT!", t).as_str(), &DEATH_MESSAGES); + print!("I'LL GIVE YOU ANOTHER CHANCE.\n"); } fn print_random(msg: &str, choices: &[&str]) { @@ -103,5 +104,65 @@ fn print_random(msg: &str, choices: &[&str]) { let mut rng = thread_rng(); println!("{}", msg); - println!("\n{}", choices.choose(&mut rng).unwrap()); + println!("\n{}\n", choices.choose(&mut rng).unwrap()); +} + +pub fn print_win(total: usize, placement: usize) { + if total <= 3 { + let order; + + match total { + 1 => order = "1ST", + 2 => order = "2ND", + 3 => order = "3RD", + _ => order = "#INVALID#", + } + + println!("AMAZING!!! NOT BAD FOR YOUR {} SUCCESSFUL JUMP!!!", order); + return; + } + + let (total, placement) = (total as f32, placement as f32); + + let betters = placement - 1.; + let p: f32 = (total - betters) / total; + + println!("{}", p); + + println!( + "placement: {}, total jumps: {}, percent is: {}", + placement, total, p + ); + + if p < 0.1 { + println!( + "HEY! YOU PULLED THE RIP CORD MUCH TOO SOON. {} SUCCESSFUL\nJUMPS BEFORE YOURS AND YOU CAME IN NUMBER {}! GET WITH IT!", + total, placement + ); + } else if p < 0.25 { + println!( + "HUMPH! DON'T YOU HAVE ANY SPORTING BLOOD? THERE WERE\n{} SUCCESSFUL JUMPS BEFORE YOURS AND YOU CAME IN {} JUMPS\nBETTER THAN THE WORST. SHAPE UP!!!", + total, placement + ); + } else if p < 0.5 { + println!( + "CONSERVATIVE, AREN'T YOU? YOU RANKED ONLY {} IN THE\n{} SUCCESSFUL JUMPS BEFORE YOURS.", + placement, total + ); + } else if p < 0.75 { + println!( + "NOT BAD. THERE HAVE BEEN {} SUCCESSFUL JUMPS BEFORE YOURS.\nYOU WERE BEATEN OUT BY {} OF THEM.", + total, betters + ); + } else if p < 0.9 { + println!( + "PRETTY GOOD! {} SUCCESSFUL JUMPS PRECEDED YOURS AND ONLY\n{} OF THEM GOT LOWER THAN YOU DID BEFORE THEIR CHUTES\nOPENED.", + total, betters + ) + } else { + println!( + "WOW! THAT'S SOME JUMPING. OF THE {} SUCCESSFUL JUMPS\nBEFORE YOURS, ONLY {} OPENED THEIR CHUTES LOWER THAN\nYOU DID.", + total, betters + ) + } }