diff --git a/84_Super_Star_Trek/rust/src/commands.rs b/84_Super_Star_Trek/rust/src/commands.rs index 2f42edd5..3239b45e 100644 --- a/84_Super_Star_Trek/rust/src/commands.rs +++ b/84_Super_Star_Trek/rust/src/commands.rs @@ -1,6 +1,48 @@ -use crate::{model::{Galaxy, Pos, COURSES, EndPosition}, view}; +use crate::{model::{Galaxy, Pos, COURSES, EndPosition}, view, input}; -pub fn move_enterprise(course: u8, warp_speed: f32, galaxy: &mut Galaxy) { +pub fn get_amount_and_set_shields(galaxy: &mut Galaxy, provided: Vec) { + + // todo check for damaged module + + view::energy_available(galaxy.enterprise.total_energy); + let value = input::param_or_prompt_value(&provided, 0, "Number of units to shields", 0, i32::MAX); + if value.is_none() { + view::shields_unchanged(); + return; + } + let value = value.unwrap() as u16; + if value > galaxy.enterprise.total_energy { + view::ridiculous(); + view::shields_unchanged(); + return; + } + + galaxy.enterprise.shields = value; + view::shields_set(value); +} + +pub fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy, provided: Vec) { + + let course = input::param_or_prompt_value(&provided, 0, "Course (1-9)?", 1, 9); + if course.is_none() { + view::bad_nav(); + return; + } + + let speed = input::param_or_prompt_value(&provided, 1, "Warp Factor (0-8)?", 0.0, 8.0); + if speed.is_none() { + view::bad_nav(); + return; + } + + move_klingons_and_fire(galaxy); + if galaxy.enterprise.destroyed { + return; + } + move_enterprise(course.unwrap(), speed.unwrap(), galaxy); +} + +fn move_enterprise(course: u8, warp_speed: f32, galaxy: &mut Galaxy) { let ship = &mut galaxy.enterprise; @@ -67,7 +109,7 @@ fn find_end_quadrant_sector(start_quadrant: Pos, start_sector: Pos, course: u8, EndPosition { quadrant, sector, hit_edge, energy_cost } } -pub fn move_klingons_and_fire(galaxy: &mut Galaxy) { +fn move_klingons_and_fire(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(); diff --git a/84_Super_Star_Trek/rust/src/input.rs b/84_Super_Star_Trek/rust/src/input.rs new file mode 100644 index 00000000..75f12102 --- /dev/null +++ b/84_Super_Star_Trek/rust/src/input.rs @@ -0,0 +1,37 @@ +use std::{io::{stdin, stdout, Write}, str::FromStr}; + +pub fn prompt(prompt_text: &str) -> Vec { + let stdin = stdin(); + let mut stdout = stdout(); + + print!("{prompt_text} "); + let _ = stdout.flush(); + + let mut buffer = String::new(); + if let Ok(_) = stdin.read_line(&mut buffer) { + return buffer.trim_end().split(" ").map(|s| s.to_string()).collect(); + } + Vec::new() +} + +pub fn prompt_value(prompt_text: &str, min: T, max: T) -> Option { + let passed = prompt(prompt_text); + if passed.len() != 1 { + return None + } + match passed[0].parse::() { + Ok(n) if (n >= min && n <= max) => Some(n), + _ => None + } +} + +pub fn param_or_prompt_value(params: &Vec, param_pos: usize, prompt_text: &str, min: T, max: T) -> Option { + if params.len() > param_pos { + match params[param_pos].parse::() { + Ok(n) => Some(n), + _ => None + } + } else { + return prompt_value::(prompt_text, min, max); + } +} \ No newline at end of file diff --git a/84_Super_Star_Trek/rust/src/main.rs b/84_Super_Star_Trek/rust/src/main.rs index 477a0594..1b9a0522 100644 --- a/84_Super_Star_Trek/rust/src/main.rs +++ b/84_Super_Star_Trek/rust/src/main.rs @@ -1,7 +1,8 @@ -use std::{io::{stdin, stdout, Write, Read}, process::exit, str::FromStr}; +use std::process::exit; use model::Galaxy; +mod input; mod model; mod commands; mod view; @@ -14,104 +15,29 @@ fn main() { view::enterprise(); view::intro(&galaxy); - let _ = prompt("Press Enter when ready to accept command"); + let _ = input::prompt("Press Enter when ready to accept command"); view::starting_quadrant(&galaxy.enterprise.quadrant); view::short_range_scan(&galaxy); loop { - let command = prompt("Command?"); + let command = input::prompt("Command?"); if command.len() == 0 { continue; } match command[0].to_uppercase().as_str() { "SRS" => view::short_range_scan(&galaxy), - "NAV" => gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()), - "SHE" => get_amount_and_set_shields(&mut galaxy, command[1..].into()), + "NAV" => commands::gather_dir_and_speed_then_move(&mut galaxy, command[1..].into()), + "SHE" => commands::get_amount_and_set_shields(&mut galaxy, command[1..].into()), _ => view::print_command_help() } if galaxy.enterprise.destroyed { // todo: also check if stranded view::end_game_failure(&galaxy); + // todo check if can restart break; } + + // todo check for victory } } - -fn get_amount_and_set_shields(galaxy: &mut Galaxy, provided: Vec) { - - // todo check for damaged module - - view::energy_available(galaxy.enterprise.total_energy); - let value = param_or_prompt_value(&provided, 0, "Number of units to shields", 0, i32::MAX); - if value.is_none() { - view::shields_unchanged(); - return; - } - let value = value.unwrap() as u16; - if value > galaxy.enterprise.total_energy { - view::ridiculous(); - view::shields_unchanged(); - return; - } - - galaxy.enterprise.shields = value; - view::shields_set(value); -} - -fn gather_dir_and_speed_then_move(galaxy: &mut Galaxy, provided: Vec) { - - let course = param_or_prompt_value(&provided, 0, "Course (1-9)?", 1, 9); - if course.is_none() { - view::bad_nav(); - return; - } - - let speed = param_or_prompt_value(&provided, 1, "Warp Factor (0-8)?", 0.0, 8.0); - if speed.is_none() { - view::bad_nav(); - return; - } - - commands::move_klingons_and_fire(galaxy); - if galaxy.enterprise.destroyed { - return; - } - commands::move_enterprise(course.unwrap(), speed.unwrap(), galaxy); -} - -fn prompt(prompt_text: &str) -> Vec { - let stdin = stdin(); - let mut stdout = stdout(); - - print!("{prompt_text} "); - let _ = stdout.flush(); - - let mut buffer = String::new(); - if let Ok(_) = stdin.read_line(&mut buffer) { - return buffer.trim_end().split(" ").map(|s| s.to_string()).collect(); - } - Vec::new() -} - -fn prompt_value(prompt_text: &str, min: T, max: T) -> Option { - let passed = prompt(prompt_text); - if passed.len() != 1 { - return None - } - match passed[0].parse::() { - Ok(n) if (n >= min && n <= max) => Some(n), - _ => None - } -} - -fn param_or_prompt_value(params: &Vec, param_pos: usize, prompt_text: &str, min: T, max: T) -> Option { - if params.len() > param_pos { - match params[param_pos].parse::() { - Ok(n) => Some(n), - _ => None - } - } else { - return prompt_value::(prompt_text, min, max); - } -} \ No newline at end of file