mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 15:16:33 -08:00
game loop done
todo: - write/read to/from saved games - win & lose messages
This commit is contained in:
@@ -2,16 +2,16 @@ use rand::{prelude::SliceRandom, Rng};
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CelestialBody {
|
pub enum CelestialBody {
|
||||||
Mercury,
|
MERCURY,
|
||||||
Venus,
|
VENUS,
|
||||||
Earth,
|
EARTH,
|
||||||
Moon,
|
MOON,
|
||||||
Mars,
|
MARS,
|
||||||
Jupiter,
|
JUPITER,
|
||||||
Saturn,
|
SATURN,
|
||||||
Uranus,
|
URANUS,
|
||||||
Neptune,
|
NEPTUNE,
|
||||||
Sun,
|
SUN,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CelestialBody {
|
impl CelestialBody {
|
||||||
@@ -19,16 +19,16 @@ impl CelestialBody {
|
|||||||
use CelestialBody::*;
|
use CelestialBody::*;
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Mercury => 12.2,
|
MERCURY => 12.2,
|
||||||
Venus => 28.3,
|
VENUS => 28.3,
|
||||||
Earth => 32.16,
|
EARTH => 32.16,
|
||||||
Moon => 5.12,
|
MOON => 5.12,
|
||||||
Mars => 12.5,
|
MARS => 12.5,
|
||||||
Jupiter => 85.2,
|
JUPITER => 85.2,
|
||||||
Saturn => 37.6,
|
SATURN => 37.6,
|
||||||
Uranus => 33.8,
|
URANUS => 33.8,
|
||||||
Neptune => 39.6,
|
NEPTUNE => 39.6,
|
||||||
Sun => 896.,
|
SUN => 896.,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,16 +49,16 @@ pub fn random_celestial_body() -> Option<CelestialBody> {
|
|||||||
use CelestialBody::*;
|
use CelestialBody::*;
|
||||||
|
|
||||||
match rand::thread_rng().gen_range(0..10) {
|
match rand::thread_rng().gen_range(0..10) {
|
||||||
0 => Some(Mercury),
|
0 => Some(MERCURY),
|
||||||
1 => Some(Venus),
|
1 => Some(VENUS),
|
||||||
2 => Some(Earth),
|
2 => Some(EARTH),
|
||||||
3 => Some(Moon),
|
3 => Some(MOON),
|
||||||
4 => Some(Mars),
|
4 => Some(MARS),
|
||||||
5 => Some(Jupiter),
|
5 => Some(JUPITER),
|
||||||
6 => Some(Saturn),
|
6 => Some(SATURN),
|
||||||
7 => Some(Uranus),
|
7 => Some(URANUS),
|
||||||
8 => Some(Neptune),
|
8 => Some(NEPTUNE),
|
||||||
9 => Some(Sun),
|
9 => Some(SUN),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
use crate::utility;
|
use crate::utility;
|
||||||
|
|
||||||
pub struct Game {}
|
pub struct Game {
|
||||||
|
altitude: f32,
|
||||||
|
terminal_velocity: f32,
|
||||||
|
acceleration: f32,
|
||||||
|
seconds: f32,
|
||||||
|
interval: f32,
|
||||||
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn new() -> Game {
|
pub fn new() -> Game {
|
||||||
|
let altitude = utility::get_altitude();
|
||||||
|
|
||||||
let terminal_velocity = utility::get_terminal_velocity(
|
let terminal_velocity = utility::get_terminal_velocity(
|
||||||
"SELECT YOUR OWN TERMINAL VELOCITY",
|
"SELECT YOUR OWN TERMINAL VELOCITY",
|
||||||
"WHAT TERMINAL VELOCITY (MI/HR)?",
|
"WHAT TERMINAL VELOCITY (MI/HR)?",
|
||||||
@@ -14,10 +22,95 @@ impl Game {
|
|||||||
"WHAT ACCELERATION (FT/SEC/SEC)?",
|
"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<bool> {
|
pub fn tick(&mut self) -> bool {
|
||||||
todo!()
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,21 +10,24 @@ fn main() {
|
|||||||
|
|
||||||
println!("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES");
|
println!("WELCOME TO 'SPLAT' -- THE GAME THAT SIMULATES");
|
||||||
println!("A PARACHUTE JUMP. TRY OPEN YOUR CHUTE AT THE");
|
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 {
|
// while !quit {
|
||||||
let game = Game::new();
|
loop {
|
||||||
|
let mut game = Game::new();
|
||||||
|
if !game.tick() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
/* loop {
|
||||||
if let Some(play_again) = game.tick() {
|
if let Some(play_again) = game.tick() {
|
||||||
if !play_again {
|
if !play_again {
|
||||||
println!("SSSSSSSSSS.");
|
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ pub fn read_line() -> String {
|
|||||||
input.trim().to_uppercase()
|
input.trim().to_uppercase()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prompt_bool(msg: &str) -> bool {
|
pub fn prompt_bool(msg: &str, template: bool) -> bool {
|
||||||
println!(" {} (YES OR NO)?", msg);
|
if template {
|
||||||
|
println!("{} (YES OR NO)?", msg);
|
||||||
|
} else {
|
||||||
|
println!("{}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let response = read_line();
|
let response = read_line();
|
||||||
@@ -38,23 +42,27 @@ pub fn prompt_numeric(msg: &str) -> f32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_altitude() -> f32 {
|
||||||
|
9001. * rand::random::<f32>() + 1000.
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_terminal_velocity(bool_msg: &str, num_msg: &str) -> f32 {
|
pub fn get_terminal_velocity(bool_msg: &str, num_msg: &str) -> f32 {
|
||||||
let mut _num = 0.0;
|
let mut _num = 0.0;
|
||||||
|
|
||||||
if prompt_bool(bool_msg) {
|
if prompt_bool(bool_msg, true) {
|
||||||
_num = prompt_numeric(num_msg);
|
_num = prompt_numeric(num_msg);
|
||||||
} else {
|
} else {
|
||||||
_num = rand::thread_rng().gen_range(0.0..=1000.0);
|
_num = get_random_float(0., 1000.);
|
||||||
println!("OK. TERMINAL VELOCTY = {} MI/HR", _num);
|
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 {
|
pub fn get_acceleration(bool_msg: &str, num_msg: &str) -> f32 {
|
||||||
let mut _num = 0.0;
|
let mut _num = 0.0;
|
||||||
|
|
||||||
if prompt_bool(bool_msg) {
|
if prompt_bool(bool_msg, true) {
|
||||||
_num = prompt_numeric(num_msg);
|
_num = prompt_numeric(num_msg);
|
||||||
} else {
|
} else {
|
||||||
let b =
|
let b =
|
||||||
@@ -64,5 +72,14 @@ pub fn get_acceleration(bool_msg: &str, num_msg: &str) -> f32 {
|
|||||||
b.print_acceleration_message();
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user