def test_set_weight_capacity_raises_an_exception_if_the_requested_capacity_is_less_than_or_equal_to_zero(self): # noqa bag = MixedCargoContainer() with self.assertRaises(CargoContainerException) as error_context: bag.set_weight_capacity(0) self.assertEqual( "Weight capacity must be greater than 0", error_context.exception.message, )
def test_unload_cargo_decreases_load_of_container_and_returns_all_available_cargo_up_to_the_requested_quantity(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 10) bag.get_slot(Fish)['load'] = 3 load = bag.unload_cargo(Fish, 7) self.assertEqual(bag.current_load(Fish), 0) self.assertEqual(load, 3)
def test_load_cargo_returns_entire_load_if_slot_is_already_at_capacity(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 3) bag.get_slot(Fish)['load'] = 3 remains = bag.load_cargo(Fish, 7) self.assertEqual(bag.current_load(Fish), 3) self.assertEqual(remains, 7)
def test_unload_cargo_decreases_load_of_container(self): bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 10) bag.get_slot(Fish)['load'] = 1 load = bag.unload_cargo(Fish, 1) self.assertEqual(bag.current_load(Fish), 0) self.assertEqual(load, 1)
def __init__(self): self.container = MixedCargoContainer() self.container.set_weight_capacity(self.strength) self.tile_map = None self.building_factories = {} self.unit_id = uuid4() self.action_queue = [] self.harvestable_resources = set() self.carryable_resources = set() self.pt = None self.traversable_terrain_types = set() self.target = None
def test_current_load_returns_the_current_number_of_resource_type_held_in_the_container(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(100) slot = bag.get_slot(Fish) slot['load'] = 3 slot = bag.get_slot(Cabbage) slot['load'] = 5 self.assertEqual(bag.current_load(Fish), 3)
def test_remaining_capacity_computes_the_number_of_resource_type_that_can_still_be_held_in_the_container(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(100) slot = bag.get_slot(Fish) slot['load'] = 3 slot = bag.get_slot(Cabbage) slot['load'] = 5 self.assertEqual( bag.remaining_capacity(Wood), (100 - 3 * Fish.weight - 5 * Cabbage.weight) / Wood.weight)
def test_get_current_weight_computes_the_total_weight_of_all_resource_items_in_the_container(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(100) slot = bag.get_slot(Fish) slot['load'] = 3 slot = bag.get_slot(Cabbage) slot['load'] = 5 self.assertEqual( bag.get_current_weight(), 3 * Fish.weight + 5 * Cabbage.weight, )
def test_set_weight_capacity_raises_an_exception_if_the_requested_capacity_is_less_than_or_equal_to_the_current_weight_in_the_container(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 3) slot = bag.get_slot(Fish) slot['load'] = 3 with self.assertRaises(CargoContainerException) as error_context: bag.set_weight_capacity(Fish.weight * 2) self.assertIn( "Capacity must be greater than or equal to the current weight", error_context.exception.message, )
def test_load_cargo_increases_load_of_slot_if_bag_can_hold_the_resource_and_returns_excess_that_could_not_be_loaded(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 5 - 1) remains = bag.load_cargo(Fish, 7) self.assertEqual(bag.current_load(Fish), 4.5) self.assertEqual(remains, 2.5)
def test_load_cargo_increases_load_of_container(self): bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 10) remains = bag.load_cargo(Fish, 1) self.assertEqual(bag.current_load(Fish), 1) self.assertEqual(remains, 0)
def test_unload_cargo_returns_nothing_if_bag_has_no_resources_of_requested_type(self): # noqa bag = MixedCargoContainer() bag.set_weight_capacity(Fish.weight * 10) load = bag.unload_cargo(Fish, 7) self.assertEqual(bag.current_load(Fish), 0) self.assertEqual(load, 0)
class Unit: # grid units per second movement_speed = 0 name = '' strength = 0 def __init__(self): self.container = MixedCargoContainer() self.container.set_weight_capacity(self.strength) self.tile_map = None self.building_factories = {} self.unit_id = uuid4() self.action_queue = [] self.harvestable_resources = set() self.carryable_resources = set() self.pt = None self.traversable_terrain_types = set() self.target = None def __repr__(self): return self.name @property def status(self): return '\n'.join([ 'unit type: {}'.format(self.name), 'movement speed: {}'.format(self.movement_speed), 'current position: {}'.format(self.pt), 'current action: {}'.format(self.current_action), 'container:\n{}'.format(indent(str(self.container), ' ')) ]) @property def current_action(self): if len(self.action_queue) == 0: return None else: return self.action_queue[0] @property def tile(self): return self.tile_map.get_tile(self.pt) def add_harvestable_resource(self, resource): self.harvestable_resources.add(resource) def add_carryable_resource(self, resource): self.carryable_resources.add(resource) def can_harvest_resource(self, resource): return resource in self.harvestable_resources def move(self, v): if self.tile_map is None: raise UnitException("The unit is not yet placed on the map") new_pt = self.pt + v if new_pt not in self.tile_map: raise UnitException("Unit may not move out of bounds") tile = self.tile_map.get_tile(new_pt) if tile.terrain.terrain_type not in self.traversable_terrain_types: message = "This unit cannot traverse " message += str(tile.terrain.terrain_type) raise UnitException(message) self.pt = new_pt def add_building_factory(self, building_factory): if building_factory.product.name in self.building_factories: message = "A factory for that building has already been added" raise UnitException(message) factory_key = building_factory.product.name self.building_factories[factory_key] = building_factory def receive_cargo(self, resource_type, quantity): return self.container.load_cargo(resource_type, quantity) def deliver_cargo(self, resource_type, quantity): return self.container.unload_cargo(resource_type, quantity) def can_construct_building(self, building): if self.tile_map is None: return False if building.name not in self.building_factories: return False factory = self.building_factories[building.name] if not factory.can_consume(self.container): return False if (building.name == "iron mine" and self.tile.terrain_improvement.name != "iron ore deposit"): # TODO make this more generalizable return False return True def construct_building(self, building): if building.name not in self.building_factories: raise UnitException("This unit cannot build that building") return self.building_factories[building.name].digest(self.container) def act(self, dt): if len(self.action_queue) == 0: return action = self.action_queue.pop(0) if not action.is_possible(self, dt): return action.execute(self, dt) if action.is_complete(self, dt): action.finish(self, dt) else: self.add_immediate_action(action.next_action(self, dt)) def add_action(self, action): self.action_queue.append(action) def add_immediate_action(self, action): self.action_queue.insert(0, action) def clear_actions(self): self.action_queue = []