From 284cac8f4034f15e7edeba5c8232a770fc082e20 Mon Sep 17 00:00:00 2001 From: tom barrett Date: Wed, 13 Feb 2019 13:25:00 -0600 Subject: added engine fuel and simplified/unified txrx from server --- src/client/engines.rs | 11 +++++++---- src/constants.rs | 2 ++ src/item.rs | 4 +++- src/math.rs | 48 ++++++++++++++++++++++----------------------- src/modules/engines.rs | 49 ++++++++++++++++++++++++++++++++++------------ src/modules/navigation.rs | 8 +++++--- src/server/connection.rs | 14 +++++++++++++ src/server/construction.rs | 42 ++++++++++++--------------------------- src/server/dashboard.rs | 6 +----- src/server/engines.rs | 31 ++++++++++++++++------------- src/server/mining.rs | 41 ++++++++++++-------------------------- src/server/navigation.rs | 19 ++++++------------ src/server/refinery.rs | 43 +++++++++++++--------------------------- src/server/tractorbeam.rs | 30 +++++++++++----------------- 14 files changed, 166 insertions(+), 182 deletions(-) (limited to 'src') diff --git a/src/client/engines.rs b/src/client/engines.rs index 8f83998..60ffcfd 100644 --- a/src/client/engines.rs +++ b/src/client/engines.rs @@ -9,6 +9,8 @@ use std::net::TcpStream; use std::thread::sleep; use std::time::Duration; +use crate::server::engines::EnginesData; + pub fn client_engines(mut stream: TcpStream, mut buff_r: BufReader) { let stdout = stdout(); let mut stdout = stdout.lock().into_raw_mode().unwrap(); @@ -17,13 +19,14 @@ pub fn client_engines(mut stream: TcpStream, mut buff_r: BufReader) { loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - let has_target = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + let engines_data: EnginesData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); writeln!( stdout, - "{}{}use numpad to freely move", + "{}{}{}Fuel\nuse numpad to freely move", termion::clear::All, - termion::cursor::Goto(1, 1) + termion::cursor::Goto(1, 1), + engines_data.fuel ) .unwrap(); write!(stdout, "{}+ : speedup", termion::cursor::Goto(1, 2)).unwrap(); @@ -31,7 +34,7 @@ pub fn client_engines(mut stream: TcpStream, mut buff_r: BufReader) { write!(stdout, "{}s : stop", termion::cursor::Goto(1, 4)).unwrap(); write!(stdout, "{}q : quit", termion::cursor::Goto(1, 5)).unwrap(); - if has_target { + if engines_data.has_target { write!( stdout, "{}c : mimic targets velocity vector", diff --git a/src/constants.rs b/src/constants.rs index c896a39..85b0638 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -13,8 +13,10 @@ pub const SHIP_NAVIGATION_TIME: u64 = 3; pub const SHIP_NAVIGATION_RANGE: f64 = 100.0; pub const SHIP_REFINERY_TIME: u64 = 5; pub const SHIP_TRACTORBEAM_STRENGTH: f64 = 0.1; +pub const SHIP_ENGINES_FUEL_START: f64 = 100.0; pub const IRON_SIZE: usize = 1; +pub const HYDROGEN_SIZE: usize = 1; pub const CRUDE_MINERALS_SIZE: usize = 10; pub const SLEEP_DURATION: u64 = 100; diff --git a/src/item.rs b/src/item.rs index 0d655e4..1e0e7ab 100644 --- a/src/item.rs +++ b/src/item.rs @@ -5,6 +5,7 @@ use crate::math::rand_name; pub enum ItemType { CrudeMinerals, Iron, + Hydrogen, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -17,8 +18,9 @@ pub struct Item { impl Item { pub fn new(itemtype: ItemType) -> Item { let size = match itemtype { - ItemType::CrudeMinerals => constants::CRUDE_MINERALS_SIZE, ItemType::Iron => constants::IRON_SIZE, + ItemType::Hydrogen => constants::HYDROGEN_SIZE, + ItemType::CrudeMinerals => constants::CRUDE_MINERALS_SIZE, }; Item { name: serde_json::to_string(&itemtype).unwrap() + &rand_name(), diff --git a/src/math.rs b/src/math.rs index 0816149..99839df 100644 --- a/src/math.rs +++ b/src/math.rs @@ -13,42 +13,42 @@ pub fn rand_name() -> String { #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Vector { - pub a: f64, - pub b: f64, - pub c: f64, + pub x: f64, + pub y: f64, + pub z: f64, } impl Vector { pub fn new(v: (f64, f64, f64)) -> Vector { Vector { - a: v.0, - b: v.1, - c: v.2, + x: v.0, + y: v.1, + z: v.2, } } pub fn distance_from(&self, other: Vector) -> f64 { - ((self.a - other.a).powf(2.0) + (self.b - other.b).powf(2.0) + (self.c - other.c).powf(2.0)) + ((self.x - other.x).powf(2.0) + (self.y - other.y).powf(2.0) + (self.z - other.z).powf(2.0)) .sqrt() } pub fn unitize(&self) -> Vector { let denominator = self.magnitude(); Vector { - a: self.a / denominator, - b: self.b / denominator, - c: self.c / denominator, + x: self.x / denominator, + y: self.y / denominator, + z: self.z / denominator, } } pub fn magnitude(&self) -> f64 { - (self.a.powf(2.0) + self.b.powf(2.0) + self.c.powf(2.0)).sqrt() + (self.x.powf(2.0) + self.y.powf(2.0) + self.z.powf(2.0)).sqrt() } } impl std::fmt::Display for Vector { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "({:.2}, {:.2}, {:.2})", self.a, self.b, self.c) + write!(f, "({:.2}, {:.2}, {:.2})", self.x, self.y, self.z) } } @@ -57,9 +57,9 @@ impl std::ops::Add for Vector { fn add(self, other: Vector) -> Vector { Vector { - a: self.a + other.a, - b: self.b + other.b, - c: self.c + other.c, + x: self.x + other.x, + y: self.y + other.y, + z: self.z + other.z, } } } @@ -69,9 +69,9 @@ impl std::ops::Sub for Vector { fn sub(self, other: Vector) -> Vector { Vector { - a: self.a - other.a, - b: self.b - other.b, - c: self.c - other.c, + x: self.x - other.x, + y: self.y - other.y, + z: self.z - other.z, } } } @@ -81,9 +81,9 @@ impl std::ops::Mul for Vector { fn mul(self, other: f64) -> Vector { Vector { - a: self.a * other, - b: self.b * other, - c: self.c * other, + x: self.x * other, + y: self.y * other, + z: self.z * other, } } } @@ -91,9 +91,9 @@ impl std::ops::Mul for Vector { impl std::ops::AddAssign for Vector { fn add_assign(&mut self, other: Vector) { *self = Vector { - a: self.a + other.a, - b: self.b + other.b, - c: self.c + other.c, + x: self.x + other.x, + y: self.y + other.y, + z: self.z + other.z, } } } diff --git a/src/modules/engines.rs b/src/modules/engines.rs index 55b9af9..fa16bf9 100644 --- a/src/modules/engines.rs +++ b/src/modules/engines.rs @@ -1,22 +1,45 @@ +use crate::constants; use crate::mass::Mass; use crate::math::Vector; +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum EnginesStatus { + None, + ApproachingTargetVelocity, +} + +impl Default for EnginesStatus { + fn default() -> Self { + EnginesStatus::None + } +} + #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Engines { acceleration: Vector, + target_velocity: Option, + pub fuel: f64, } impl Engines { pub fn new() -> Engines { Engines { acceleration: Vector::default(), + target_velocity: None, + fuel: constants::SHIP_ENGINES_FUEL_START, } } pub fn recv_acceleration(&mut self) -> Vector { let acceleration = self.acceleration.clone(); self.acceleration = Vector::default(); - acceleration + + if self.fuel - acceleration.magnitude() >= 0.0 { + self.fuel -= acceleration.magnitude(); + acceleration + } else { + Vector::default() + } } pub fn give_client_data( @@ -27,26 +50,26 @@ impl Engines { data: String, ) { let mut acceleration = Vector::default(); - match data.as_bytes() { - b"5\n" => acceleration.a += 0.1, - b"0\n" => acceleration.a -= 0.1, - b"8\n" => acceleration.b += 0.1, - b"2\n" => acceleration.b -= 0.1, - b"4\n" => acceleration.c += 0.1, - b"6\n" => acceleration.c -= 0.1, - b"+\n" => acceleration = velocity * 0.05, - b"-\n" => { + match data.as_str() { + "5" => acceleration.x += 0.1, + "0" => acceleration.x -= 0.1, + "8" => acceleration.y += 0.1, + "2" => acceleration.y -= 0.1, + "4" => acceleration.z += 0.1, + "6" => acceleration.z -= 0.1, + "+" => acceleration = velocity * 0.05, + "-" => { acceleration = velocity * -1.05; } - b"s\n" => { + "s" => { acceleration = velocity * -1.0; } - b"c\n" => { + "c" => { if let Some(target) = target { acceleration = target.velocity.clone() - velocity; } } - b"t\n" => { + "t" => { if let Some(target) = target { acceleration = (target.position.clone() - position) * 0.01; } diff --git a/src/modules/navigation.rs b/src/modules/navigation.rs index 0e855f8..0e010cb 100644 --- a/src/modules/navigation.rs +++ b/src/modules/navigation.rs @@ -48,9 +48,11 @@ impl Navigation { } pub fn give_target(&mut self, target_name: String) { - self.start = Some(SystemTime::now()); - self.status = NavigationStatus::Targeting; - self.target_name = Some(target_name); + if !target_name.is_empty() { + self.start = Some(SystemTime::now()); + self.status = NavigationStatus::Targeting; + self.target_name = Some(target_name); + } } pub fn verify_target(&mut self, ship_position: Vector, masses: &HashMap) { diff --git a/src/server/connection.rs b/src/server/connection.rs index 662e33d..9275b67 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -57,3 +57,17 @@ impl ServerConnection { } } } + +pub fn receive(buff_r: &mut BufReader) -> Option { + let mut recv = String::new(); + match buff_r.read_line(&mut recv) { + Ok(result) => { + if result == 0 { + None + } else { + Some(recv.replace("\n", "")) + } + } + Err(_) => Some(String::new()), + } +} diff --git a/src/server/construction.rs b/src/server/construction.rs index 9c700ae..d45135c 100644 --- a/src/server/construction.rs +++ b/src/server/construction.rs @@ -1,7 +1,6 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::constants; @@ -10,7 +9,7 @@ use crate::mass::{Mass, MassType}; use crate::modules::construction::Construction; use crate::modules::construction::ConstructionStatus; use crate::modules::types::ModuleType; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -32,8 +31,18 @@ impl ServerConnection { let construction = construction.as_mut().unwrap(); let construction_data = get_construction_data(storage, construction); - if self.open && self.txrx_construction(&construction_data) { - construction.toggle(); + let send = serde_json::to_string(&construction_data).unwrap() + "\n"; + self.open = self.stream.write(send.as_bytes()).is_ok(); + + match receive(&mut self.buff_r) { + Some(recv) => { + if let "c" = recv.as_str() { + if construction_data.has_enough { + construction.toggle(); + } + } + } + None => self.open = false, } if construction_data.status == ConstructionStatus::Constructed { @@ -52,31 +61,6 @@ impl ServerConnection { masses.insert(self.name.clone(), ship); } - - fn txrx_construction(&mut self, construction_data: &ConstructionData) -> bool { - let send = serde_json::to_string(construction_data).unwrap() + "\n"; - if let Err(_err) = self.stream.write(send.as_bytes()) { - self.open = false; - } - - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - match recv.as_bytes() { - b"c\n" => { - if construction_data.has_enough { - return true; - } - } - _ => { - if result == 0 { - self.open = false; - } - } - } - } - - false - } } fn get_construction_data(storage: &Storage, construction: &Construction) -> ConstructionData { diff --git a/src/server/dashboard.rs b/src/server/dashboard.rs index 981158b..cff2398 100644 --- a/src/server/dashboard.rs +++ b/src/server/dashboard.rs @@ -11,11 +11,7 @@ impl ServerConnection { if self.open { let ship = masses.get(&self.name).unwrap(); let send = serde_json::to_string(&ship).unwrap() + "\n"; - - self.open = match self.stream.write(send.as_bytes()) { - Ok(_result) => true, - Err(_error) => false, - }; + self.open = self.stream.write(send.as_bytes()).is_ok(); } } } diff --git a/src/server/engines.rs b/src/server/engines.rs index f3e68f0..86ef5ec 100644 --- a/src/server/engines.rs +++ b/src/server/engines.rs @@ -1,12 +1,17 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::mass::{Mass, MassType}; use crate::modules::navigation::NavigationStatus; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct EnginesData { + pub has_target: bool, + pub fuel: f64, +} impl ServerConnection { pub fn server_engines(&mut self, masses: &mut HashMap) { @@ -21,29 +26,27 @@ impl ServerConnection { { let navigation = navigation.clone().unwrap(); let engines = engines.as_mut().unwrap(); - let targeted = navigation.status == NavigationStatus::Targeted; - let send = serde_json::to_string(&targeted).unwrap() + "\n"; - if let Err(_err) = self.stream.write(send.as_bytes()) { - self.open = false; - } + let engines_data = EnginesData { + has_target: navigation.status == NavigationStatus::Targeted, + fuel: engines.fuel, + }; + let send = serde_json::to_string(&engines_data).unwrap() + "\n"; + self.open = self.stream.write(send.as_bytes()).is_ok(); let target = match navigation.target_name { Some(name) => masses.get(&name), None => None, }; - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - engines.give_client_data( + match receive(&mut self.buff_r) { + Some(recv) => engines.give_client_data( ship.position.clone(), ship.velocity.clone(), target, recv, - ); - if result == 0 { - self.open = false; - } + ), + None => self.open = false, } } diff --git a/src/server/mining.rs b/src/server/mining.rs index 4c1d3f6..b9b0ca0 100644 --- a/src/server/mining.rs +++ b/src/server/mining.rs @@ -1,7 +1,6 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::item::ItemType; @@ -9,7 +8,7 @@ use crate::mass::{Mass, MassType}; use crate::math::Vector; use crate::modules::mining::{Mining, MiningStatus}; use crate::modules::navigation::Navigation; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct MiningData { @@ -35,8 +34,18 @@ impl ServerConnection { let navigation = navigation.as_ref().unwrap(); let mining_data = get_mining_data(ship.position.clone(), mining, navigation, masses); - if self.open && self.txrx_mining(&mining_data) { - mining.toggle(); + let send = serde_json::to_string(&mining_data).unwrap() + "\n"; + self.open = self.stream.write(send.as_bytes()).is_ok(); + + match receive(&mut self.buff_r) { + Some(recv) => { + if let "F" = recv.as_str() { + if mining_data.is_within_range { + mining.toggle(); + } + } + } + None => self.open = false, } if !mining_data.is_within_range { @@ -69,30 +78,6 @@ impl ServerConnection { masses.insert(self.name.clone(), ship); } - - fn txrx_mining(&mut self, mining_data: &MiningData) -> bool { - let send = serde_json::to_string(mining_data).unwrap() + "\n"; - if let Err(_err) = self.stream.write(send.as_bytes()) { - self.open = false; - } - - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - match recv.as_bytes() { - b"F\n" => { - if mining_data.is_within_range { - return true; - } - } - _ => { - if result == 0 { - self.open = false; - } - } - } - } - false - } } fn get_mining_data( diff --git a/src/server/navigation.rs b/src/server/navigation.rs index 8fc7731..e14c340 100644 --- a/src/server/navigation.rs +++ b/src/server/navigation.rs @@ -1,11 +1,10 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::mass::{Mass, MassType}; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; impl ServerConnection { pub fn server_navigation(&mut self, masses: &mut HashMap) { @@ -28,19 +27,13 @@ impl ServerConnection { if self.open { let send = serde_json::to_string(&within_range).unwrap() + "\n"; + self.open = self.stream.write(send.as_bytes()).is_ok(); - if let Err(_err) = self.stream.write(send.as_bytes()) { - self.open = false; - }; - - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - if result == 0 { - self.open = false; - } - if !recv.is_empty() { - navigation.give_target(recv.replace("\n", "")); + match receive(&mut self.buff_r) { + Some(recv) => { + navigation.give_target(recv); } + None => self.open = false, } } } diff --git a/src/server/refinery.rs b/src/server/refinery.rs index 7cec23e..1a9a6ab 100644 --- a/src/server/refinery.rs +++ b/src/server/refinery.rs @@ -1,13 +1,12 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::item::{Item, ItemType}; use crate::mass::{Mass, MassType}; use crate::modules::refinery::RefineryStatus; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RefineryData { @@ -35,8 +34,18 @@ impl ServerConnection { status: refinery.status.clone(), }; - if self.open && self.txrx_refinery(&refinery_data) { - refinery.toggle(); + let send = serde_json::to_string(&refinery_data).unwrap() + "\n"; + self.open = self.stream.write(send.as_bytes()).is_ok(); + + match receive(&mut self.buff_r) { + Some(recv) => { + if let "R" = recv.as_str() { + if refinery_data.has_crude_minerals { + refinery.toggle(); + } + } + } + None => self.open = false, } if !refinery_data.has_crude_minerals { @@ -46,35 +55,11 @@ impl ServerConnection { if refinery.status == RefineryStatus::Refined { storage.take_item(ItemType::CrudeMinerals); storage.give_item(Item::new(ItemType::Iron)); + storage.give_item(Item::new(ItemType::Hydrogen)); refinery.taken(); } } masses.insert(self.name.clone(), ship); } - - fn txrx_refinery(&mut self, refinery_data: &RefineryData) -> bool { - let send = serde_json::to_string(refinery_data).unwrap() + "\n"; - if let Err(_err) = self.stream.write(send.as_bytes()) { - self.open = false; - } - - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - match recv.as_bytes() { - b"R\n" => { - if refinery_data.has_crude_minerals { - return true; - } - } - _ => { - if result == 0 { - self.open = false; - } - } - } - } - - false - } } diff --git a/src/server/tractorbeam.rs b/src/server/tractorbeam.rs index fc76b7c..b7c11af 100644 --- a/src/server/tractorbeam.rs +++ b/src/server/tractorbeam.rs @@ -1,13 +1,12 @@ extern crate serde_json; use std::collections::HashMap; -use std::io::BufRead; use std::io::Write; use crate::mass::{Mass, MassType}; use crate::modules::navigation::NavigationStatus; use crate::modules::tractorbeam::TractorbeamStatus; -use crate::server::connection::ServerConnection; +use crate::server::connection::{receive, ServerConnection}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct TractorbeamData { @@ -35,23 +34,16 @@ impl ServerConnection { }; let send = serde_json::to_string(&tractorbeam_data).unwrap() + "\n"; - self.open = match self.stream.write(send.as_bytes()) { - Ok(_result) => true, - Err(_error) => false, - }; - - let mut recv = String::new(); - if let Ok(result) = self.buff_r.read_line(&mut recv) { - match recv.as_bytes() { - b"o\n" => tractorbeam.toggle_pull(), - b"p\n" => tractorbeam.toggle_push(), - b"t\n" => tractorbeam.toggle_bring(5.0), - _ => { - if result == 0 { - self.open = false; - } - } - } + self.open = self.stream.write(send.as_bytes()).is_ok(); + + match receive(&mut self.buff_r) { + Some(recv) => match recv.as_str() { + "o" => tractorbeam.toggle_pull(), + "p" => tractorbeam.toggle_push(), + "t" => tractorbeam.toggle_bring(5.0), + _ => (), + }, + None => self.open = false, } } -- cgit v1.2.3