mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-24 20:10:15 -08:00
work on starbases
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use rand::Rng;
|
||||
|
||||
use crate::{model::{Galaxy, Pos, COURSES, EndPosition, self, Enterprise, systems}, view, input::{self, prompt_value, param_or_prompt_value}};
|
||||
use crate::{model::*, view, input::{self, param_or_prompt_value}};
|
||||
|
||||
pub fn perform_short_range_scan(galaxy: &Galaxy) {
|
||||
if galaxy.enterprise.damaged.contains_key(systems::SHORT_RANGE_SCAN) {
|
||||
@@ -64,7 +64,9 @@ pub fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy, provided: Vec<String>
|
||||
return;
|
||||
}
|
||||
|
||||
move_klingons_and_fire(galaxy);
|
||||
klingons_move(galaxy);
|
||||
klingons_fire(galaxy);
|
||||
|
||||
if galaxy.enterprise.destroyed {
|
||||
return;
|
||||
}
|
||||
@@ -156,10 +158,17 @@ fn move_enterprise(course: u8, warp_speed: f32, galaxy: &mut Galaxy) {
|
||||
ship.quadrant = end.quadrant;
|
||||
ship.sector = end.sector;
|
||||
|
||||
ship.total_energy = (ship.total_energy - end.energy_cost).max(0);
|
||||
if ship.shields > ship.total_energy {
|
||||
view::divert_energy_from_shields();
|
||||
ship.shields = ship.total_energy;
|
||||
let quadrant = &galaxy.quadrants[end.quadrant.as_index()];
|
||||
if quadrant.docked_at_starbase(ship.sector) {
|
||||
ship.shields = 0;
|
||||
ship.photon_torpedoes = MAX_PHOTON_TORPEDOES;
|
||||
ship.total_energy = MAX_ENERGY;
|
||||
} else {
|
||||
ship.total_energy = (ship.total_energy - end.energy_cost).max(0);
|
||||
if ship.shields > ship.total_energy {
|
||||
view::divert_energy_from_shields();
|
||||
ship.shields = ship.total_energy;
|
||||
}
|
||||
}
|
||||
|
||||
view::short_range_scan(&galaxy)
|
||||
@@ -189,27 +198,46 @@ fn find_end_quadrant_sector(start_quadrant: Pos, start_sector: Pos, course: u8,
|
||||
EndPosition { quadrant, sector, hit_edge, energy_cost }
|
||||
}
|
||||
|
||||
fn move_klingons_and_fire(galaxy: &mut Galaxy) {
|
||||
fn klingons_move(galaxy: &mut Galaxy) {
|
||||
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
|
||||
fn klingons_fire(galaxy: &mut Galaxy) {
|
||||
let quadrant = &mut galaxy.quadrants[galaxy.enterprise.quadrant.as_index()];
|
||||
if quadrant.docked_at_starbase(galaxy.enterprise.sector) {
|
||||
view::starbase_shields();
|
||||
return;
|
||||
}
|
||||
|
||||
for k in 0..quadrant.klingons.len() {
|
||||
quadrant.klingons[k].fire_on(&mut galaxy.enterprise);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_damage_control(enterprise: &Enterprise) {
|
||||
if enterprise.damaged.contains_key(systems::DAMAGE_CONTROL) {
|
||||
pub fn run_damage_control(galaxy: &mut Galaxy) {
|
||||
|
||||
let ship = &mut galaxy.enterprise;
|
||||
|
||||
if ship.damaged.contains_key(systems::DAMAGE_CONTROL) {
|
||||
view::inoperable(&systems::name_for(systems::DAMAGE_CONTROL));
|
||||
return;
|
||||
}
|
||||
|
||||
view::damage_control(enterprise);
|
||||
view::damage_control(&ship);
|
||||
|
||||
if ship.damaged.len() == 0 || !galaxy.quadrants[ship.quadrant.as_index()].docked_at_starbase(ship.sector) {
|
||||
return;
|
||||
}
|
||||
|
||||
// try repeair
|
||||
// if so write dam report
|
||||
// and increment elapsed time
|
||||
|
||||
view::damage_control(&ship);
|
||||
}
|
||||
|
||||
pub fn perform_long_range_scan(galaxy: &mut Galaxy) {
|
||||
@@ -291,7 +319,5 @@ pub fn get_power_and_fire_phasers(galaxy: &mut Galaxy, provided: Vec<String>) {
|
||||
|
||||
// fire on each klingon
|
||||
|
||||
for klingon in &mut quadrant.klingons {
|
||||
klingon.fire_on(&mut galaxy.enterprise)
|
||||
}
|
||||
klingons_fire(galaxy);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ fn main() {
|
||||
systems::SHORT_RANGE_SCAN => commands::perform_short_range_scan(&galaxy),
|
||||
systems::WARP_ENGINES => commands::gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()),
|
||||
systems::SHIELD_CONTROL => commands::get_amount_and_set_shields(&mut galaxy, command[1..].into()),
|
||||
systems::DAMAGE_CONTROL => commands::display_damage_control(&galaxy.enterprise),
|
||||
systems::DAMAGE_CONTROL => commands::run_damage_control(&mut galaxy),
|
||||
systems::LONG_RANGE_SCAN => commands::perform_long_range_scan(&mut galaxy),
|
||||
systems::COMPUTER => commands::access_computer(&galaxy, command[1..].into()),
|
||||
systems::PHASERS => commands::get_power_and_fire_phasers(&mut galaxy, command[1..].into()),
|
||||
|
||||
@@ -25,8 +25,6 @@ pub struct Klingon {
|
||||
|
||||
impl Klingon {
|
||||
pub fn fire_on(&mut self, enterprise: &mut Enterprise) {
|
||||
// todo check if enterprise is protected
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let attack_strength = rng.gen::<f32>();
|
||||
let dist_to_enterprise = self.sector.abs_diff(enterprise.sector) as f32;
|
||||
@@ -149,7 +147,7 @@ impl Pos {
|
||||
(self.0 * 8 + self.1).into()
|
||||
}
|
||||
|
||||
fn abs_diff(&self, other: Pos) -> u8 {
|
||||
pub fn abs_diff(&self, other: Pos) -> u8 {
|
||||
self.0.abs_diff(other.0) + self.1.abs_diff(other.1)
|
||||
}
|
||||
}
|
||||
@@ -192,6 +190,9 @@ pub enum SectorStatus {
|
||||
Empty, Star, StarBase, Klingon
|
||||
}
|
||||
|
||||
pub const MAX_PHOTON_TORPEDOES: u8 = 28;
|
||||
pub const MAX_ENERGY: u16 = 3000;
|
||||
|
||||
impl Galaxy {
|
||||
pub fn remaining_klingons(&self) -> u8 {
|
||||
let quadrants = &self.quadrants;
|
||||
@@ -224,8 +225,8 @@ impl Galaxy {
|
||||
damaged: HashMap::new(),
|
||||
quadrant: enterprise_quadrant,
|
||||
sector: enterprise_sector,
|
||||
photon_torpedoes: 28,
|
||||
total_energy: 3000,
|
||||
photon_torpedoes: MAX_PHOTON_TORPEDOES,
|
||||
total_energy: MAX_ENERGY,
|
||||
shields: 0 }
|
||||
}
|
||||
}
|
||||
@@ -296,4 +297,8 @@ impl Quadrant {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn docked_at_starbase(&self, enterprise_sector: Pos) -> bool {
|
||||
self.star_base.is_some() && self.star_base.unwrap().abs_diff(enterprise_sector) == 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,10 @@ pub fn enter_quadrant(quadrant: &Pos) {
|
||||
pub fn short_range_scan(model: &Galaxy) {
|
||||
let quadrant = &model.quadrants[model.enterprise.quadrant.as_index()];
|
||||
let mut condition = "GREEN";
|
||||
if quadrant.klingons.len() > 0 {
|
||||
if quadrant.docked_at_starbase(model.enterprise.sector) {
|
||||
println!("Shields dropped for docking purposes");
|
||||
condition = "DOCKED";
|
||||
} else if quadrant.klingons.len() > 0 {
|
||||
condition = "*RED*";
|
||||
} else if model.enterprise.damaged.len() > 0 {
|
||||
condition = "YELLOW";
|
||||
@@ -448,3 +451,7 @@ pub fn computer_accuracy_issue() {
|
||||
pub fn phasers_locked(available_energy: u16) {
|
||||
println!("Phasers locked on target; Energy available = {available_energy} units")
|
||||
}
|
||||
|
||||
pub fn starbase_shields() {
|
||||
println!("Starbase shields protect the Enterprise")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user