def test_weighted_random_choice(self, mock_random): class _ItemWithWeight(object): def __init__(self, value, weight): self.value = value self.weight = weight items = [ _ItemWithWeight('abc', 0.1), _ItemWithWeight('def', 0.3), _ItemWithWeight('klm', 0.6), ] mock_random.return_value = 0.05 observed = utils.weighted_random_choice(items) self.assertEqual('abc', observed.value) mock_random.return_value = 0.25 observed = utils.weighted_random_choice(items) self.assertEqual('def', observed.value) mock_random.return_value = 0.5 observed = utils.weighted_random_choice(items) self.assertEqual('klm', observed.value)
def produce_task(world, actions): available_action_items = {} # action -> (items) for action in actions: item_types = action.get_depends_on() world_items = world.filter_items(item_types) filtered_items = list(action.filter_items(world_items)) if not filtered_items: continue # LOG.debug('Available action: %s, item-types: %s, filtered_items: %s', # action, item_types, filtered_items) # check that filtered_items contain items of *all* item_types filtered_item_types = set(i.item_type for i in filtered_items) if item_types and filtered_item_types != item_types: continue available_action_items[action] = filtered_items if available_action_items: available_actions = list(available_action_items.keys()) chosen_action = utils.weighted_random_choice(available_actions) available_items = available_action_items[chosen_action] # pick one random item per type items_per_type = collections.defaultdict(list) for item in available_items: items_per_type[item.item_type].append(item) chosen_items = [random.choice(v) for v in items_per_type.values()] chosen_action.reserve_items(chosen_items) task = Task(id=utils.make_id(), action=chosen_action, items=chosen_items) LOG.info('Produced task: %s', task) return task else: LOG.debug('No actions available') return None