예제 #1
0
 def _update_children(self, prosp):
     mortality = self._mortality["children"] * Utils.opposite(prosp)
     n_children = self._children
     [dead, grown] = Utils.rsplit(n_children, mortality)
     [men, women] = Utils.rsplit(grown, self._grown_rates["men-women"])
     # print("Dead children: " + str(dead))
     return [-dead, men, women, 0, 0]
예제 #2
0
 def _get_men_availability_factor(young_men, young_women):
     if young_women > 0:
         men_factor = young_men / young_women
         res = (men_factor * 0.5) / 2
         return Utils.saturate(Utils.saturate(res, 1.0), men_factor * 3)
     else:
         return 0
예제 #3
0
 def _update_births(self, prosp):
     n_young_men = self._young_men
     n_young_women = self._young_women
     men_availability_factor = self._get_men_availability_factor(n_young_men, n_young_women)
     women_fertility = n_young_women * self._grown_rates["women-fertility"] * Utils.perturbate_high(prosp)
     births = round(women_fertility * men_availability_factor)
     return [births, 0, 0, 0, 0]
예제 #4
0
def migrate(group, world, information, verbose):
    """
    This event checks if a group migrates from it's current position.

    If the event occurs a fact is added to the group.

    :param group: The group to check.
    :param world: The world.
    :param information: A dictionary with the information for the events.
    :param verbose: True if the event has to register into facts, False otherwise
    """
    if random.random() < chance_to_migrate(group, world, information["occupied_positions"]):
        positions = land_cells_around(world, group.position, group.migration_radius, information["occupied_positions"])
        prosperity = ([Utils.perturbate_low(group.get_prosperity(world, p)), p] for p in positions)
        best = max(prosperity)
        group.position = best[1]
        fact = "{} is moving to better lands {}.".format(group.name, best[1])
        if verbose:
            if information["turn"] in group.facts:
                group.facts[information["turn"]].append(fact)
            else:
                group.facts[information["turn"]] = [fact]

        if information["turn"] in group.file_facts:
            group.file_facts[information["turn"]]['pos'] = best[1]
        else:
            group.file_facts[information["turn"]] = {'pos': best[1]}
예제 #5
0
def chance_to_discover_agriculture(group, world):
    if group.nomadism != "nomadic" and not ("Agriculture" in group.activities):
        agr_prosp = group.get_base_prosperity_per_activity("Agriculture", world, group.position)
        p = (agr_prosp - 0.75) * 6.0
        p *= discovery_population_factor(group.total_persons, 200)
        return Utils.saturate(max(0.0, p), 0.3)
    else:
        return 0
예제 #6
0
def chance_to_become_sedentary(group):
    if group.nomadism == "semi-sedentary" and "Agriculture" in group.activities:
        prosperity = group.prosperity
        if prosperity > 0.72:
            return Utils.saturate((prosperity - 0.75) / 1.5, 0.2)
        else:
            return 0
    else:
        return 0
예제 #7
0
 def get_prosperity_per_activity(self, world, position):
     """
     This function returns the prosperity of each activity of group in the given position.
     :param world: The world in which the group lives.
     :param position: The position to check.
     :return: A list with the prosperity for each activity of the group.
     """
     prosperity = []
     for activity in self.activities:
         base = self.get_base_prosperity_per_activity(activity, world, position)
         crowding = self._get_crowding_per_activity(activity)
         prosperity.append(Utils.saturate(base * crowding, 1.0))
     return prosperity
예제 #8
0
def chance_to_develop_trade(group, occupied_positions):
    if group.nomadism == "sedentary" and not group.knows_trade:
        neighbours = groups_around(group.position, group.trade_radius, occupied_positions)
        if neighbours > 0:
            prosperity = group.prosperity
            if prosperity > 0.8:
                return Utils.saturate((prosperity - 0.78) / 1.3, 0.3)
            else:
                return 0.05
        else:
            return 0
    else:
        return 0
예제 #9
0
 def _update_old(self, prosp):
     mortality_men = Utils.saturate(self._mortality["old-men"] * Utils.opposite(prosp), 1.0)
     mortality_women = Utils.saturate(self._mortality["old-women"] * Utils.opposite(prosp), 1.0)
     n_old_men = self._old_men
     n_old_women = self._old_women
     [m_dead, m_alive] = Utils.rsplit(n_old_men, mortality_men)
     [w_dead, w_alive] = Utils.rsplit(n_old_women, mortality_women)
     # print("Dead old men: " + str(m_dead) + " dead old women: " + str(w_dead))
     return [0, 0, 0, -m_dead, -w_dead]
예제 #10
0
 def _update_young(self, prosp):
     mortality_men = self._mortality["young-men"] * Utils.opposite(prosp)
     mortality_women = self._mortality["young-women"] * Utils.opposite(prosp)
     n_young_men = self._young_men
     n_young_women = self._young_women
     [m_dead, m_alive] = Utils.rsplit(n_young_men, mortality_men)
     [w_dead, w_alive] = Utils.rsplit(n_young_women, mortality_women)
     [m_grown, m_rest] = Utils.rsplit(m_alive, self._grown_rates["old-men"])
     [w_grown, w_rest] = Utils.rsplit(w_alive, self._grown_rates["old-women"])
     # print("Dead young men: " + str(m_dead) + " dead young women: " + str(w_dead))
     return [0, -1 * (m_dead + m_grown), -1 * (w_dead + w_grown), m_grown, w_grown]
예제 #11
0
    def __init__(self, position, tribe, default, id):
        """
        This will create a group in the given position, and with the given parameters.

        The tribe parameters will be merged with the default ones.

        :param position: The position to set the group.
        :param tribe: A dictionary containing all the custom parameters for the group.
        :param default: A dictionary containing all the default parameters for all the groups.
        """
        self._position = position
        self.id = id
        mix_tribe = copy.deepcopy(tribe)
        def_tribe = copy.deepcopy(default)
        mix_tribe = Utils.update(mix_tribe, def_tribe)
        self._tribe = mix_tribe
        self.name = eval(mix_tribe["Name"])(mix_tribe["Name-rules"])
        self.type = mix_tribe["Type"]
        self._children = random.randrange(0, mix_tribe["Max-initial-population"]["children"])
        self._young_men = random.randrange(0, mix_tribe["Max-initial-population"]["young-men"])
        self._young_women = random.randrange(0, mix_tribe["Max-initial-population"]["young-women"])
        self._old_men = random.randrange(0, mix_tribe["Max-initial-population"]["old-men"])
        self._old_women = random.randrange(0, mix_tribe["Max-initial-population"]["old-women"])
        self.activities = mix_tribe["Start-activities"]
        self._max_populations = mix_tribe["Max-population-for-activity"]
        self._biomes_prosperity_per_activity = mix_tribe["Biomes-prosperity-per-activity"]
        self._crowding_per_activity = mix_tribe["Crowding-for-activity"]
        self._mortality = mix_tribe["Mortality-rates"]
        self._grown_rates = mix_tribe["Grown-rates"]
        self._last_prosperity = 0
        self.nomadism = "nomadic"
        self._events = mix_tribe["Events"]
        self._migration_radius = mix_tribe["Migration-radius"]
        self._migration_rate = mix_tribe["Migration-rate"]
        self.facts = {}
        self.file_facts = {}
        self._wealth = 0
        self._wealth_base_multiplier = mix_tribe["Wealth-base-multiplier"]
        self._trade_radius = mix_tribe["Trade-base-radius"]
        self.knows_trade = False
        self.file_facts[0] = {'pos': self._position, 'nomadism': 'nomadic'}
예제 #12
0
def groups_around_info(pos, radius, groups):
    rad = range(-radius, radius + 1)
    positions = itertools.product(rad, rad)
    occupied = [g.position for g in groups]
    g_positions = [Utils.add_list(pos, p) for p in positions if Utils.add_list(pos, p) in occupied and not p == (0, 0)]
    return [g for g in groups if g.position in g_positions]
예제 #13
0
def groups_around(pos, radius, occupied_positions):
    rad = range(-radius, radius + 1)
    positions = itertools.product(rad, rad)
    return len([p for p in positions if Utils.add_list(pos, p) in occupied_positions and not p == (0, 0)])
예제 #14
0
def land_cells_around(world, pos, radius, occupied_positions):
    rad = range(-radius, radius + 1)
    positions = itertools.product(rad, rad)
    filtered = (Utils.add_list(pos, p) for p in positions if inside_world(world, Utils.add_list(pos, p)))
    land = (p for p in filtered if is_land(world, p))
    return (p for p in land if p not in occupied_positions)
예제 #15
0
def chance_to_become_semi_sedentary(group):
    prosperity = group.prosperity
    if group.nomadism == "nomadic" and prosperity > 0.6:
        return Utils.saturate((prosperity - 0.75) / 1.5, 0.1)
    else:
        return 0
예제 #16
0
def chance_to_trade(group, information):
    if group.knows_trade:
        neighbours = groups_around_info(group.position, group.trade_radius, information["groups"])
        chance = Utils.saturate(len(neighbours) / (group.trade_radius * group.trade_radius - 1), 0.8)
        return [chance, neighbours]
    return [0, 0]