diff --git a/84_Super_Star_Trek/rust/src/main.rs b/84_Super_Star_Trek/rust/src/main.rs index 46e932c3..481d2378 100644 --- a/84_Super_Star_Trek/rust/src/main.rs +++ b/84_Super_Star_Trek/rust/src/main.rs @@ -1,12 +1,9 @@ use std::{io::{stdin, stdout, Write}, process::exit, str::FromStr}; -use model::Galaxy; - -use crate::text_constants::BAD_NAV; +use model::{Galaxy, Pos}; mod model; mod commands; -mod text_constants; fn main() { ctrlc::set_handler(move || { exit(0) }) @@ -30,6 +27,8 @@ fn main() { } fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy) { + const BAD_NAV: &str = " Lt. Sulu reports, 'Incorrect course data, sir!'"; + let dir = prompt_value::("Course (1-9)?", 1, 9); if dir.is_none() { println!("{}", BAD_NAV); @@ -42,7 +41,42 @@ fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy) { return; } - let distance = (speed.unwrap() * 8.0) as i32; + let distance = (speed.unwrap() * 8.0) as u8; + let galaxy_pos = galaxy.enterprise.quadrant * 8u8 + galaxy.enterprise.sector; + let (mut nx, mut ny) = galaxy_pos.translate(dir.unwrap(), distance); + + let mut hit_edge = false; + if nx < 0 { + nx = 0; + hit_edge = true; + } + if ny < 0 { + ny = 0; + hit_edge = true; + } + if nx >= 64 { + ny = 63; + hit_edge = true; + } + if nx >= 64 { + ny = 63; + hit_edge = true; + } + + let new_quadrant = Pos((nx / 8) as u8, (ny / 8) as u8); + let new_sector = Pos((nx % 8) as u8, (ny % 8) as u8); + + if hit_edge { + println!("Lt. Uhura report message from Starfleet Command: + 'Permission to attempt crossing of galactic perimeter + is hereby *Denied*. Shut down your engines.' + Chief Engineer Scott reports, 'Warp engines shut down + at sector {} of quadrant {}.'", new_quadrant, new_sector); + } + + galaxy.enterprise.quadrant = new_quadrant; + galaxy.enterprise.sector = new_sector; + // could be done with a step function - while distance > 0, move by digit. // if passing a boundary, test for the next quadrant in that direction // if present, change quadrant and move to border diff --git a/84_Super_Star_Trek/rust/src/model.rs b/84_Super_Star_Trek/rust/src/model.rs index a0f80751..36ec9628 100644 --- a/84_Super_Star_Trek/rust/src/model.rs +++ b/84_Super_Star_Trek/rust/src/model.rs @@ -1,3 +1,5 @@ +use std::{ops::{Mul, Add}, fmt::Display}; + use rand::Rng; pub struct Galaxy { @@ -5,13 +7,53 @@ pub struct Galaxy { pub enterprise: Enterprise } -#[derive(PartialEq)] +#[derive(PartialEq, Clone, Copy)] pub struct Pos(pub u8, pub u8); impl Pos { + const DIRECTIONS : [(i8, i8); 8] = [ + (1, 0), + (1, -1), + (0, -1), + (-1, -1), + (-1, 0), + (-1, 1), + (0, 1), + (1, 1), + ]; + pub fn as_index(&self) -> usize { (self.0 * 8 + self.1).into() } + + pub fn translate(&self, dir: u8, dist: u8) -> (i8, i8) { + let (dx, dy): (i8, i8) = Self::DIRECTIONS[dir as usize]; + let x = (self.0 as i8) + dx * dist as i8; + let y = (self.1 as i8) + dy * dist as i8; + (x, y) + } +} + +impl Mul for Pos { + type Output = Self; + + fn mul(self, rhs: u8) -> Self::Output { + Pos(self.0 * rhs, self.1 * rhs) + } +} + +impl Add for Pos { + type Output = Self; + + fn add(self, rhs: Pos) -> Self::Output { + Pos(self.0 + rhs.0, self.1 + rhs.1) + } +} + +impl Display for Pos { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + todo!() + } } #[derive(PartialEq)] diff --git a/84_Super_Star_Trek/rust/src/text_constants.rs b/84_Super_Star_Trek/rust/src/text_constants.rs deleted file mode 100644 index 36339abe..00000000 --- a/84_Super_Star_Trek/rust/src/text_constants.rs +++ /dev/null @@ -1,2 +0,0 @@ - -pub const BAD_NAV: &str = " Lt. Sulu reports, 'Incorrect course data, sir!'"; \ No newline at end of file