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)
예제 #5
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 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)
예제 #13
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 = []