From b56819aadffe74fb53d3dd8ab7de51a1cb161045 Mon Sep 17 00:00:00 2001 From: Christopher Date: Wed, 1 Mar 2023 15:36:42 +1300 Subject: [PATCH] implemented taking damage and dying --- 84_Super_Star_Trek/rust/src/commands.rs | 4 +- 84_Super_Star_Trek/rust/src/main.rs | 27 ++++++++++++- 84_Super_Star_Trek/rust/src/model.rs | 50 ++++++++++++++++++++++--- 84_Super_Star_Trek/rust/tasks.md | 9 ++++- 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/84_Super_Star_Trek/rust/src/commands.rs b/84_Super_Star_Trek/rust/src/commands.rs index 100803a3..ffbdad61 100644 --- a/84_Super_Star_Trek/rust/src/commands.rs +++ b/84_Super_Star_Trek/rust/src/commands.rs @@ -1,4 +1,4 @@ -use crate::model::{Galaxy, Pos, SectorStatus, COURSES}; +use crate::model::{Galaxy, Pos, SectorStatus, COURSES, Quadrant}; pub fn short_range_scan(model: &Galaxy) { let quadrant = &model.quadrants[model.enterprise.quadrant.as_index()]; @@ -35,7 +35,7 @@ pub fn short_range_scan(model: &Galaxy) { } pub fn move_enterprise(course: u8, warp_speed: f32, galaxy: &mut Galaxy) { - + let end = find_end_quadrant_sector(galaxy.enterprise.quadrant, galaxy.enterprise.sector, course, warp_speed); if end.hit_edge { diff --git a/84_Super_Star_Trek/rust/src/main.rs b/84_Super_Star_Trek/rust/src/main.rs index a9b5f4ce..9c2ea606 100644 --- a/84_Super_Star_Trek/rust/src/main.rs +++ b/84_Super_Star_Trek/rust/src/main.rs @@ -2,6 +2,8 @@ use std::{io::{stdin, stdout, Write}, process::exit, str::FromStr}; use model::Galaxy; +use crate::model::Condition; + mod model; mod commands; @@ -10,7 +12,7 @@ fn main() { .expect("Error setting Ctrl-C handler"); let mut galaxy = Galaxy::generate_new(); - // init options, starting state and notes + // todo: init options, starting state and notes commands::short_range_scan(&galaxy); loop { @@ -19,6 +21,14 @@ fn main() { "NAV" => gather_dir_and_speed_then_move(&mut galaxy), _ => print_command_help() } + + if galaxy.enterprise.condition == Condition::Destroyed { // todo: also check if stranded + println!("Is is stardate {}. + There were {} Klingon battle cruisers left at + the end of your mission. + ", galaxy.stardate, galaxy.remaining_klingons()); + break; + } } } @@ -37,6 +47,21 @@ fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy) { return; } + let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()]; + for k in 0..quadrant.klingons.len() { + let new_sector = quadrant.find_empty_sector(); + quadrant.klingons[k].sector = new_sector; + } + + // todo: check if enterprise is protected by a starbase + + for k in 0..quadrant.klingons.len() { + quadrant.klingons[k].fire_on(&mut galaxy.enterprise); + } + + if galaxy.enterprise.condition == Condition::Destroyed { + return; + } commands::move_enterprise(course.unwrap(), speed.unwrap(), galaxy); } diff --git a/84_Super_Star_Trek/rust/src/model.rs b/84_Super_Star_Trek/rust/src/model.rs index 7fffd81f..94e9128f 100644 --- a/84_Super_Star_Trek/rust/src/model.rs +++ b/84_Super_Star_Trek/rust/src/model.rs @@ -15,7 +15,21 @@ pub struct Quadrant { } pub struct Klingon { - pub sector: Pos + pub sector: Pos, + energy: f32 +} + +impl Klingon { + pub fn fire_on(&mut self, enterprise: &mut Enterprise) { + let mut rng = rand::thread_rng(); + let attack_strength = rng.gen::(); + let dist_to_enterprise = self.sector.abs_diff(enterprise.sector) as f32; + let hit_strength = self.energy * (2.0 + attack_strength) / dist_to_enterprise; + + self.energy /= 3.0 + attack_strength; + + enterprise.take_hit(self.sector, hit_strength as u16); + } } pub struct Enterprise { @@ -26,10 +40,30 @@ pub struct Enterprise { pub total_energy: u16, pub shields: u16, } +impl Enterprise { + fn take_hit(&mut self, sector: Pos, hit_strength: u16) { + if self.condition == Condition::Destroyed { + return; + } + + println!("{hit_strength} unit hit on Enterprise from sector {sector}"); -#[derive(Debug)] + // absorb into shields + + if self.shields <= 0 { + println!("The Enterprise has been destroyed. The Federation will be conquered."); + self.condition = Condition::Destroyed; + } + + // report shields + // take damage if strength is greater than 20 + } +} + +#[derive(PartialEq, Debug)] pub enum Condition { - Green, Yellow, Red + Green, Yellow, Red, + Destroyed, } #[derive(PartialEq, Clone, Copy, Debug)] @@ -39,6 +73,10 @@ impl Pos { pub fn as_index(&self) -> usize { (self.0 * 8 + self.1).into() } + + fn abs_diff(&self, other: Pos) -> u8 { + self.0.abs_diff(other.0) + self.1.abs_diff(other.1) + } } impl Mul for Pos { @@ -128,7 +166,7 @@ impl Galaxy { _ => 0 }; for _ in 0..klingon_count { - quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector() }); + quadrant.klingons.push(Klingon { sector: quadrant.find_empty_sector(), energy: rng.gen_range(100..=300) as f32 }); } result.push(quadrant); @@ -162,7 +200,7 @@ impl Quadrant { klingons.into_iter().find(|k| &k.sector == sector).is_some() } - fn find_empty_sector(&self) -> Pos { + pub fn find_empty_sector(&self) -> Pos { let mut rng = rand::thread_rng(); loop { let pos = Pos(rng.gen_range(0..8), rng.gen_range(0..8)); @@ -171,4 +209,4 @@ impl Quadrant { } } } -} \ No newline at end of file +} diff --git a/84_Super_Star_Trek/rust/tasks.md b/84_Super_Star_Trek/rust/tasks.md index 3fcb826a..8a9951b5 100644 --- a/84_Super_Star_Trek/rust/tasks.md +++ b/84_Super_Star_Trek/rust/tasks.md @@ -2,6 +2,11 @@ Started after movement and display of stats was finished (no energy management or collision detection or anything). -- [ ] stop before hitting an object +- [x] klingon movement +- [x] klingon firing, game over etc - [ ] remove energy on move -- [ ] klingon movement \ No newline at end of file +- [ ] shields +- [ ] stranded... +- [ ] stop before hitting an object + - when moving across a sector, the enterprise should stop before it runs into something + - the current move is a jump, which makes this problematic. would need to rewrite it