diff options
-rw-r--r-- | src/mass.rs | 36 | ||||
-rw-r--r-- | src/modules/construction.rs | 21 | ||||
-rw-r--r-- | src/modules/mining.rs | 25 | ||||
-rw-r--r-- | src/storage.rs | 32 | ||||
-rw-r--r-- | tests/tests.rs | 233 |
5 files changed, 159 insertions, 188 deletions
diff --git a/src/mass.rs b/src/mass.rs index 8d9f9fc..7cc7d70 100644 --- a/src/mass.rs +++ b/src/mass.rs @@ -272,4 +272,40 @@ impl Mass { } } } + + pub fn take_item(&mut self, item_type: ItemType) -> Option<Item> { + match self.mass_type { + MassType::Ship { + ref mut storage, .. + } => storage.take_item(item_type), + MassType::Astroid { + ref mut resources, .. + } => resources.take_item(item_type), + _ => None, + } + } + + pub fn give_item(&mut self, item: Item) -> bool { + match self.mass_type { + MassType::Ship { + ref mut storage, .. + } => storage.give_item(item), + MassType::Astroid { + ref mut resources, .. + } => resources.give_item(item), + _ => false, + } + } + + pub fn item_count(&self, item_type: ItemType) -> usize { + match &self.mass_type { + MassType::Ship { + storage, .. + } => storage.item_count(item_type), + MassType::Astroid { + resources, .. + } => resources.item_count(item_type), + _ => 0, + } + } } diff --git a/src/modules/construction.rs b/src/modules/construction.rs index 0eec155..091ebc6 100644 --- a/src/modules/construction.rs +++ b/src/modules/construction.rs @@ -33,7 +33,7 @@ impl Construction { masses: &mut HashMap<String, Mass>, storage: &mut Storage, ) { - if !self.has_enough(storage) { + if storage.item_count(ItemType::Iron) < constants::SHIP_CONSTRUCTION_IRON_COST { self.off(); } if let Some(timer) = self.start { @@ -43,9 +43,10 @@ impl Construction { } } if self.status == Status::Constructed { - storage - .take_items(ItemType::Iron, constants::SHIP_CONSTRUCTION_IRON_COST) - .unwrap(); + for _ in 0..constants::SHIP_CONSTRUCTION_IRON_COST { + storage.take_item(ItemType::Iron).unwrap(); + } + masses.insert( "Station".to_string(), Mass::new_station( @@ -60,7 +61,8 @@ impl Construction { pub fn get_client_data(&self, storage: &Storage) -> String { let client_data = ClientData { - has_enough: self.has_enough(storage), + has_enough: storage.item_count(ItemType::Iron) + >= constants::SHIP_CONSTRUCTION_IRON_COST, status: self.status.clone(), }; serde_json::to_string(&client_data).unwrap() + "\n" @@ -72,15 +74,6 @@ impl Construction { } } - fn has_enough(&self, storage: &Storage) -> bool { - storage - .items - .iter() - .filter(|item| item.item_type == ItemType::Iron) - .count() - >= constants::SHIP_CONSTRUCTION_IRON_COST - } - fn toggle(&mut self) { match self.status { Status::None => self.on(), diff --git a/src/modules/mining.rs b/src/modules/mining.rs index 816313e..01d7663 100644 --- a/src/modules/mining.rs +++ b/src/modules/mining.rs @@ -42,23 +42,18 @@ impl Mining { } } if self.status == Status::Mined { - if let MassType::Astroid { - ref mut resources, .. - } = target.mass_type - { - match resources.take_item(ItemType::CrudeMinerals) { - Some(item) => { - if !storage.give_item(item.clone()) { - let mass = Mass::new_item( - item.clone(), - target.position.clone(), - target.velocity.clone(), - ); - masses.insert(item.name.clone(), mass); - } + match target.take_item(ItemType::CrudeMinerals) { + Some(item) => { + if !storage.give_item(item.clone()) { + let mass = Mass::new_item( + item.clone(), + target.position.clone(), + target.velocity.clone(), + ); + masses.insert(item.name.clone(), mass); } - None => self.off(), } + None => self.off(), } self.mined(); } diff --git a/src/storage.rs b/src/storage.rs index 5cbd55e..fbb99b1 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -35,31 +35,6 @@ impl Storage { } } - pub fn take_items(&mut self, item_type: ItemType, count: usize) -> Option<Vec<Item>> { - if self - .items - .iter() - .filter(|item| item.item_type == item_type) - .count() - >= count - { - let mut items = Vec::new(); - for _ in 0..count { - let index = self - .items - .iter() - .position(|item| item.item_type == item_type) - .unwrap(); - let item = self.items.remove(index); - self.carrying -= item.size; - items.push(item); - } - Some(items) - } else { - None - } - } - pub fn give_item(&mut self, item: Item) -> bool { if self.capacity >= self.carrying + item.size { self.carrying += item.size; @@ -69,4 +44,11 @@ impl Storage { false } } + + pub fn item_count(&self, item_type: ItemType) -> usize { + self.items + .iter() + .filter(|item| item.item_type == item_type) + .count() + } } diff --git a/tests/tests.rs b/tests/tests.rs index c953594..53c314a 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -10,10 +10,11 @@ mod test { use space::item::{Item, ItemType}; use space::mass::{Mass, MassType}; use space::math::Vector; - use space::modules::mining::MiningStatus; - use space::modules::refinery::RefineryStatus; - use space::modules::navigation::NavigationStatus; - use space::modules::construction::ConstructionStatus; + use space::modules::construction; + use space::modules::mining; + use space::modules::navigation; + use space::modules::refinery; + use space::modules::types::ModuleType; fn setup() -> (Mass, HashMap<String, Mass>) { let ship = Mass::new_ship(); @@ -27,54 +28,45 @@ mod test { } fn setup_ship_target(ship: &mut Mass, masses: &mut HashMap<String, Mass>) { - if let MassType::Ship { - ref mut navigation, .. - } = ship.mass_type - { - let astroid = masses.get_mut("astroid").unwrap(); - astroid.position = Vector::default(); - navigation.give_received_data(String::from("astroid")); - navigation.process(ship.position.clone(), masses); - sleep(Duration::from_secs(constants::SHIP_NAVIGATION_TIME + 1)); - navigation.process(ship.position.clone(), masses); - } + ship.give_received_data(ModuleType::Navigation, String::from("astroid"), &masses); + ship.process(masses); + sleep(Duration::from_secs(constants::SHIP_NAVIGATION_TIME + 1)); + ship.process(masses); } #[test] fn test_navigation_range() { let (mut ship, mut masses) = setup(); - if let MassType::Ship { - ref mut navigation, .. - } = ship.mass_type - { - navigation.give_received_data(String::from("astroid")); - navigation.process(ship.position.clone(), &mut masses); - assert!(navigation.status == NavigationStatus::Targeting); - - let astroid = masses.get_mut("astroid").unwrap(); - astroid.position = Vector::new((constants::SHIP_NAVIGATION_RANGE + 1.0, 0.0, 0.0)); - navigation.process(ship.position.clone(), &mut masses); - assert!(navigation.status == NavigationStatus::None); - } + ship.give_received_data(ModuleType::Navigation, String::from("astroid"), &masses); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Navigation, &masses); + let navigation_data: navigation::ClientData = serde_json::from_str(&data).unwrap(); + assert!(navigation_data.status == navigation::Status::Targeting); + + let astroid = masses.get_mut("astroid").unwrap(); + astroid.position = Vector::new((constants::SHIP_NAVIGATION_RANGE + 1.0, 0.0, 0.0)); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Navigation, &masses); + let navigation_data: navigation::ClientData = serde_json::from_str(&data).unwrap(); + assert!(navigation_data.status == navigation::Status::None); } #[test] fn test_navigation_range_targeted() { let (mut ship, mut masses) = setup(); - setup_ship_target(&mut ship, &mut masses); - if let MassType::Ship { - ref mut navigation, .. - } = ship.mass_type - { - assert!(navigation.status == NavigationStatus::Targeted); - let astroid = masses.get_mut("astroid").unwrap(); - astroid.position = Vector::new((constants::SHIP_NAVIGATION_RANGE + 1.0, 0.0, 0.0)); - navigation.process(ship.position.clone(), &mut masses); - assert!(navigation.status == NavigationStatus::None); - } + let data = ship.get_client_data(ModuleType::Navigation, &masses); + let navigation_data: navigation::ClientData = serde_json::from_str(&data).unwrap(); + assert!(navigation_data.status == navigation::Status::Targeted); + + let astroid = masses.get_mut("astroid").unwrap(); + astroid.position = Vector::new((constants::SHIP_NAVIGATION_RANGE + 1.0, 0.0, 0.0)); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Navigation, &masses); + let navigation_data: navigation::ClientData = serde_json::from_str(&data).unwrap(); + assert!(navigation_data.status == navigation::Status::None); } #[test] @@ -82,20 +74,18 @@ mod test { let (mut ship, mut masses) = setup(); setup_ship_target(&mut ship, &mut masses); - if let MassType::Ship { - ref mut storage, - ref mut mining, - .. - } = ship.mass_type - { - mining.give_received_data(String::from("F")); - assert!(mining.status == MiningStatus::Mining); - - let mut astroid = masses.remove("astroid").unwrap(); - astroid.position = Vector::new((constants::SHIP_MINING_RANGE + 1.0, 0.0, 0.0)); - mining.process(ship.position.clone(), &mut masses, &mut astroid, storage); - assert!(mining.status == MiningStatus::None); - } + ship.give_received_data(ModuleType::Mining, String::from("F"), &masses); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Mining, &masses); + let mining_data: mining::ClientData = serde_json::from_str(&data).unwrap(); + assert!(mining_data.status == mining::Status::Mining); + + let mut astroid = masses.get_mut("astroid").unwrap(); + astroid.position = Vector::new((constants::SHIP_MINING_RANGE + 1.0, 0.0, 0.0)); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Mining, &masses); + let mining_data: mining::ClientData = serde_json::from_str(&data).unwrap(); + assert!(mining_data.status == mining::Status::None); } #[test] @@ -103,38 +93,15 @@ mod test { let (mut ship, mut masses) = setup(); setup_ship_target(&mut ship, &mut masses); - if let MassType::Ship { - ref mut storage, - ref mut mining, - .. - } = ship.mass_type - { - mining.give_received_data(String::from("F")); - assert!(mining.status == MiningStatus::Mining); - - let mut astroid = masses.remove("astroid").unwrap(); - sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); - mining.process(ship.position.clone(), &mut masses, &mut astroid, storage); - assert!( - storage - .items - .iter() - .filter(|item| item.item_type == ItemType::CrudeMinerals) - .count() - == 1 - ); + ship.give_received_data(ModuleType::Mining, String::from("F"), &masses); + ship.process(&mut masses); + sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); + ship.process(&mut masses); + assert!(ship.item_count(ItemType::CrudeMinerals) == 1); - sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); - mining.process(ship.position.clone(), &mut masses, &mut astroid, storage); - assert!( - storage - .items - .iter() - .filter(|item| item.item_type == ItemType::CrudeMinerals) - .count() - == 2 - ); - } + sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); + ship.process(&mut masses); + assert!(ship.item_count(ItemType::CrudeMinerals) == 2); } #[test] @@ -142,24 +109,16 @@ mod test { let (mut ship, mut masses) = setup(); setup_ship_target(&mut ship, &mut masses); - if let MassType::Ship { - ref mut storage, - ref mut mining, - .. - } = ship.mass_type - { - for _ in 0..10 { - storage.give_item(Item::new(ItemType::CrudeMinerals)); - } - - mining.give_received_data(String::from("F")); - - let mut astroid = masses.remove("astroid").unwrap(); - sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); - assert!(masses.len() == 0); - mining.process(ship.position.clone(), &mut masses, &mut astroid, storage); - assert!(masses.len() == 1); + for _ in 0..10 { + ship.give_item(Item::new(ItemType::CrudeMinerals)); } + + ship.give_received_data(ModuleType::Mining, String::from("F"), &masses); + ship.process(&mut masses); + sleep(Duration::from_secs(constants::SHIP_MINING_TIME + 1)); + assert!(masses.len() == 1); + ship.process(&mut masses); + assert!(masses.len() == 2); } #[test] @@ -167,33 +126,24 @@ mod test { let (mut ship, mut masses) = setup(); setup_ship_target(&mut ship, &mut masses); - if let MassType::Ship { - ref mut storage, - ref mut refinery, - .. - } = ship.mass_type - { - refinery.give_received_data(String::from("R")); - refinery.process(storage); - assert!(refinery.status == RefineryStatus::None); - - storage.give_item(Item::new(ItemType::CrudeMinerals)); - - refinery.give_received_data(String::from("R")); - refinery.process(storage); - assert!(refinery.status == RefineryStatus::Refining); - - sleep(Duration::from_secs(constants::SHIP_REFINERY_TIME + 1)); - refinery.process(storage); - assert!(storage - .items - .iter() - .any(|item| item.item_type == ItemType::Iron)); - assert!(storage - .items - .iter() - .any(|item| item.item_type == ItemType::Hydrogen)); - } + ship.give_received_data(ModuleType::Refinery, String::from("R"), &masses); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Refinery, &masses); + let mining_data: refinery::ClientData = serde_json::from_str(&data).unwrap(); + assert!(mining_data.status == refinery::Status::None); + + ship.give_item(Item::new(ItemType::CrudeMinerals)); + + ship.give_received_data(ModuleType::Refinery, String::from("R"), &masses); + ship.process(&mut masses); + let data = ship.get_client_data(ModuleType::Refinery, &masses); + let mining_data: refinery::ClientData = serde_json::from_str(&data).unwrap(); + assert!(mining_data.status == refinery::Status::Refining); + + sleep(Duration::from_secs(constants::SHIP_REFINERY_TIME + 1)); + ship.process(&mut masses); + assert!(ship.item_count(ItemType::Iron) == 1); + assert!(ship.item_count(ItemType::Hydrogen) == 1); } #[test] @@ -207,22 +157,37 @@ mod test { } = ship.mass_type { construction.give_received_data(String::from("c")); - construction.process(ship.velocity.clone(), ship.position.clone(), &mut masses, storage); - assert!(construction.status == ConstructionStatus::None); + construction.process( + ship.velocity.clone(), + ship.position.clone(), + &mut masses, + storage, + ); + assert!(construction.status == construction::Status::None); for _ in 0..5 { storage.give_item(Item::new(ItemType::Iron)); } construction.give_received_data(String::from("c")); - construction.process(ship.velocity.clone(), ship.position.clone(), &mut masses, storage); - assert!(construction.status == ConstructionStatus::Constructing); + construction.process( + ship.velocity.clone(), + ship.position.clone(), + &mut masses, + storage, + ); + assert!(construction.status == construction::Status::Constructing); assert!(masses.len() == 1); - sleep(Duration::from_secs(constants::SHIP_CONSTRUCTION_TIME + 1)); - construction.process(ship.velocity.clone(), ship.position.clone(), &mut masses, storage); + construction.process( + ship.velocity.clone(), + ship.position.clone(), + &mut masses, + storage, + ); assert!(masses.len() == 2); + assert!(storage.items.len() == 0); } } } |