From 5b58b37ad1f1caf95dfcfd6f236f945069a50244 Mon Sep 17 00:00:00 2001 From: Christopher Date: Fri, 3 Mar 2023 07:59:12 +1300 Subject: [PATCH] finished implementing starbases --- 84_Super_Star_Trek/rust/src/commands.rs | 15 +++++++++++---- 84_Super_Star_Trek/rust/src/input.rs | 16 ++++++++++++++++ 84_Super_Star_Trek/rust/src/model.rs | 21 +++++++++++++-------- 84_Super_Star_Trek/rust/src/view.rs | 12 +++++++++--- 84_Super_Star_Trek/rust/tasks.md | 8 ++++---- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/84_Super_Star_Trek/rust/src/commands.rs b/84_Super_Star_Trek/rust/src/commands.rs index 255ced43..60dcb9b9 100644 --- a/84_Super_Star_Trek/rust/src/commands.rs +++ b/84_Super_Star_Trek/rust/src/commands.rs @@ -229,14 +229,21 @@ pub fn run_damage_control(galaxy: &mut Galaxy) { view::damage_control(&ship); - if ship.damaged.len() == 0 || !galaxy.quadrants[ship.quadrant.as_index()].docked_at_starbase(ship.sector) { + let quadrant = &galaxy.quadrants[ship.quadrant.as_index()]; + if ship.damaged.len() == 0 || !quadrant.docked_at_starbase(ship.sector) { return; } - // try repeair - // if so write dam report - // and increment elapsed time + let repair_delay = quadrant.star_base.as_ref().unwrap().repair_delay; + let repair_time = (ship.damaged.len() as f32 * 0.1 + repair_delay).max(0.9); + view::repair_estimate(repair_time); + if !input::prompt_yes_no("Will you authorize the repair order") { + return; + } + + ship.damaged.clear(); + galaxy.stardate += repair_time; view::damage_control(&ship); } diff --git a/84_Super_Star_Trek/rust/src/input.rs b/84_Super_Star_Trek/rust/src/input.rs index 75f12102..5bd35fb3 100644 --- a/84_Super_Star_Trek/rust/src/input.rs +++ b/84_Super_Star_Trek/rust/src/input.rs @@ -14,6 +14,22 @@ pub fn prompt(prompt_text: &str) -> Vec { Vec::new() } +pub fn prompt_yes_no(prompt_text: &str) -> bool { + loop { + let response = prompt(&format!("{prompt_text} (Y/N)")); + if response.len() == 0 { + continue; + } + let first_word = response[0].to_uppercase(); + if first_word.starts_with("Y") { + return true; + } + if first_word.starts_with("N") { + return false; + } + } +} + pub fn prompt_value(prompt_text: &str, min: T, max: T) -> Option { let passed = prompt(prompt_text); if passed.len() != 1 { diff --git a/84_Super_Star_Trek/rust/src/model.rs b/84_Super_Star_Trek/rust/src/model.rs index 31fb3191..a12673af 100644 --- a/84_Super_Star_Trek/rust/src/model.rs +++ b/84_Super_Star_Trek/rust/src/model.rs @@ -14,10 +14,15 @@ pub struct Galaxy { pub struct Quadrant { pub stars: Vec, - pub star_base: Option, + pub star_base: Option, pub klingons: Vec } +pub struct StarBase { + pub sector: Pos, + pub repair_delay: f32, +} + pub struct Klingon { pub sector: Pos, energy: f32 @@ -243,7 +248,7 @@ impl Galaxy { } if rng.gen::() > 0.96 { - quadrant.star_base = Some(quadrant.find_empty_sector()); + quadrant.star_base = Some(StarBase { sector: quadrant.find_empty_sector(), repair_delay: rng.gen::() * 0.5 }); } let klingon_count = @@ -264,10 +269,10 @@ impl Galaxy { } impl Quadrant { - pub fn sector_status(&self, sector: &Pos) -> SectorStatus { + pub fn sector_status(&self, sector: Pos) -> SectorStatus { if self.stars.contains(§or) { SectorStatus::Star - } else if self.is_starbase(§or) { + } else if self.is_starbase(sector) { SectorStatus::StarBase } else if self.has_klingon(§or) { SectorStatus::Klingon @@ -276,10 +281,10 @@ impl Quadrant { } } - fn is_starbase(&self, sector: &Pos) -> bool { + fn is_starbase(&self, sector: Pos) -> bool { match &self.star_base { None => false, - Some(p) => p == sector + Some(p) => p.sector == sector } } @@ -292,13 +297,13 @@ impl Quadrant { let mut rng = rand::thread_rng(); loop { let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8)); - if self.sector_status(&pos) == SectorStatus::Empty { + if self.sector_status(pos) == SectorStatus::Empty { return pos } } } pub fn docked_at_starbase(&self, enterprise_sector: Pos) -> bool { - self.star_base.is_some() && self.star_base.unwrap().abs_diff(enterprise_sector) == 1 + self.star_base.is_some() && self.star_base.as_ref().unwrap().sector.abs_diff(enterprise_sector) == 1 } } diff --git a/84_Super_Star_Trek/rust/src/view.rs b/84_Super_Star_Trek/rust/src/view.rs index c7cc836d..77b70057 100644 --- a/84_Super_Star_Trek/rust/src/view.rs +++ b/84_Super_Star_Trek/rust/src/view.rs @@ -218,7 +218,7 @@ pub fn short_range_scan(model: &Galaxy) { if &pos == &model.enterprise.sector { print!("<*> ") } else { - match quadrant.sector_status(&pos) { + match quadrant.sector_status(pos) { SectorStatus::Star => print!(" * "), SectorStatus::StarBase => print!(">!< "), SectorStatus::Klingon => print!("+K+ "), @@ -375,7 +375,7 @@ pub fn long_range_scan(galaxy: &Galaxy) -> Vec { let quadrant = &galaxy.quadrants[pos.as_index()]; klingons = format!("{}", quadrant.klingons.len()); - star_bases = quadrant.star_base.map_or("0", |_| "1"); + star_bases = quadrant.star_base.as_ref().map_or("0", |_| "1"); stars = format!("{}", quadrant.stars.len()); } @@ -428,7 +428,7 @@ pub(crate) fn galaxy_scanned_map(galaxy: &Galaxy) { let pos = Pos(x, y); if galaxy.scanned.contains(&pos) { let quadrant = &galaxy.quadrants[pos.as_index()]; - print!(" {}{}{} ", quadrant.klingons.len(), quadrant.stars.len(), quadrant.star_base.map_or("0", |_| "1")) + print!(" {}{}{} ", quadrant.klingons.len(), quadrant.stars.len(), quadrant.star_base.as_ref().map_or("0", |_| "1")) } else { print!(" *** "); } @@ -455,3 +455,9 @@ pub fn phasers_locked(available_energy: u16) { pub fn starbase_shields() { println!("Starbase shields protect the Enterprise") } + +pub fn repair_estimate(repair_time: f32) { + println!( +"Technicians standing by to effect repairs to your ship; +Estimated time to repair: {repair_time} stardates.") +} diff --git a/84_Super_Star_Trek/rust/tasks.md b/84_Super_Star_Trek/rust/tasks.md index 8f5b3bab..bdd44481 100644 --- a/84_Super_Star_Trek/rust/tasks.md +++ b/84_Super_Star_Trek/rust/tasks.md @@ -21,10 +21,10 @@ Started after movement and display of stats was finished (no energy management o - the current move is a jump, which makes this problematic. would need to rewrite it - also, movement courses could be floats, according to the instructions, allowing for more precise movement and aiming - [x] better command reading - support entering multiple values on a line (e.g. nav 3 0.1) -- [ ] starbases - - [ ] proximity detection for docking - - [ ] repair on damage control - - [ ] protection from shots +- [x] starbases + - [x] proximity detection for docking + - [x] repair on damage control + - [x] protection from shots - [ ] weapons - [ ] phasers - [ ] torpedoes