コード例 #1
0
    def grow_up(self):

        info('%s grew up (%d years)' % (self, self.age + 1),
             village=self.village.name)

        # Simulates growing up and updates stats

        self.age += 1
        self.baby = self.age <= config['age']['baby']
        self.adult = self.age >= config['age']['adulthood']
        self.retired = self.age >= config['age']['retirement']
        self.calculate_stats()
        self.actual_stats()

        # When reaches adulthood, gets into job selection

        if self.adult and not self.retired and self.job is None:
            self.job_selection()
        elif self.adult:
            # If adult, old and has job, time for retirement, otherwise another year of service

            if self.job is not None:
                if self.retired:
                    self.job = None
                else:
                    self.job.year_service()

        # Calculates mortality risk

        self.mortality_risk()
コード例 #2
0
 def day_pass(self):
     # Simulates a day passed in the world
     
     info('DAY: %d  YEAR: %d' % (self.date['day'], self.date['year']), village=self.name)
     
     # Day start
     
     self.village1.day_start()
     self.village2.day_start()
     
     # Resolves every action
     
     for i in range(config['action-extra']['actions-per-day']):
         self.village1.population_activities()
         self.village2.population_activities()
         self.resolve_actions()
         self.village1.remove_dead()
         self.village2.remove_dead()
     
     # Day end
     
     self.village1.day_end()
     self.village2.day_end()
     self.date_update()
     
     # Checks if day limit reached
     
     cmd_args = get_cmd_args()
     
     if 'until' in cmd_args:
         if self.date['days'] >= cmd_args['until']:
             # Stops the simulation
             
             stop()
コード例 #3
0
    def die(self):
        # Makes villager die

        info('%s died' % self, village=self.village.name)

        self.alive = False
        self.actual_health = 0
コード例 #4
0
    def run(self):
        while True:
            if not self.should_run:
                # Should stop
                break

            # Waits at barrier before updating again

            self.barrier.wait()

            try:
                self.world_obj.day_pass()

                if get_cmd_args()['victory']:
                    if len(self.world_obj.village1.population) == 0:
                        info('%s wins' % self.world_obj.village2.name,
                             village=self.world_obj.name)
                        close_dump_file()
                        exit(0)
                    elif len(self.world_obj.village2.population) == 0:
                        info('%s wins' % self.world_obj.village1.name,
                             village=self.world_obj.name)
                        close_dump_file()
                        exit(0)
            except Exception as exc:
                # Exception occurred, simulation is over

                raise SimulationError(
                    'Exception occurred during simulation %s' %
                    exc.__class__.__name__, exc)

        close_dump_file()
コード例 #5
0
 def generate(self, village):
     # Gets generated list and instantiates villagers and to be appended on the village population
     
     to_generate = self.generate_list()
     
     for i in to_generate:
         
         v = Villager(i['sex'], village, age=i['age'])
         
         if 'job' in i:
             v.job = self.job = Job.get_job(i['job'])
             info('Generated %s: %s and %d years old (%s)' % (v, v.sex, v.age, v.job), village='Gen')
         else:
             info('Generated %s: %s and %d years old' % (v, v.sex, v.age), village='Gen')
         
         # Puts the generated villager in the population
         
         village.population.append(v)
コード例 #6
0
def process_healing(villager1, villager2, villager_index):
    # Simulates a healing made by the healer on other villager
    
    info('%s heals %s' % (villager1, villager2),
         village=villager1.village.name)
    
    # Calculates the amount to be healed
    
    healing_amount = config['jobs']['healer']['healing-base'] * villager1.actual_intelligence
    
    if (villager2.actual_health + healing_amount) > villager2.health:
        # If healing more than health, health becomes full instead
        
        villager2.actual_health = villager2.health
    else:
        # Otherwise, heals the patient by the amount
        
        villager2.actual_health += healing_amount
    
    return villager_index,
コード例 #7
0
def process_rest(villager, target_index):
    # Simulates resting
    
    info('%s rests' % villager.name, village=villager.village.name)
    
    if not villager.alive:
        return target_index
    
    # Calculates amount to heal
    
    heal_amount = int(villager.health * config['action-extra']['rest-percentage'] / 100)
    print('heal', heal_amount)
    # If life will be full, sets to full life instead
    
    if (villager.actual_health + heal_amount) > villager.health:
        villager.actual_health = villager.health
    else:
        villager.actual_health += heal_amount
    
    villager.actual_stats()
    
    return ()
コード例 #8
0
    def job_selection(self):
        # Simulates a job selection process

        sex_map = {'male': 'man', 'female': 'woman'}
        selected = None
        jobs = config['jobs']['names']
        job_probabilities = []

        for i in range(len(jobs)):
            job_probabilities.append(
                config['jobs']['selection'][sex_map[self.sex]][i] +
                reduce(lambda a, b: a + b, job_probabilities[:i + 1], 0))

        rand_num = randint(0, 100)

        # Selects job based on the probabilities of each sex

        for i in range(len(job_probabilities)):
            if rand_num <= job_probabilities[i]:
                selected = jobs[i]
                break

        info('%s became %s' % (self, selected), village=self.village.name)
        self.job = Job.get_job(selected)
コード例 #9
0
def process_procreating(villager1, villager2, villager_index, partner_index):
    # Simulates procreating between partners
    
    info('%s procreates with %s' % (villager1, villager2),
         village=villager1.village.name)
    
    # If one is sterile, not happening
    if villager1.fertility == 0:
        return villager_index,
    if villager2.fertility == 0:
        return partner_index,
    
    # Gets the average fertility based on both villagers
    
    avg_fertility = (villager1.fertility + villager2.fertility) / 2
    
    chance_reduction = config['jobs']['breeder']['multiple-babies-chance-reduction']
    max_children = config['jobs']['breeder']['maximum-children-per-pregnancy']
    children = []
    stat_range = [1 - config['base-stats']['stat-variation'], 1 + config['base-stats']['stat-variation']]
    
    # Tries fertilization
    
    for i in range(0, max_children):
        if uniform(0, 1) <= avg_fertility * (chance_reduction ** i):
            # Success
            baby_sex = choice(('male', 'female'))
            sex = {'male': 'man', 'female': 'woman'}[baby_sex]
            max_var = config['base-stats']['stat-variation'] + 1
            
            children.append(({
                                 'health': maximum(
                                     int((villager1.base_health + villager2.base_health) / 2 * uniform(*stat_range)),
                                     int(config['base-stats'][sex]['health'] * max_var)),
                                 'strength': maximum(
                                     int((villager1.base_strength + villager2.base_strength) / 2
                                         * uniform(*stat_range)),
                                     int(config['base-stats'][sex]['strength'] * max_var)),
                                 'resistance': maximum(
                                     int((villager1.base_resistance + villager2.base_resistance) / 2
                                         * uniform(*stat_range)),
                                     int(config['base-stats'][sex]['resistance'] * max_var)),
                                 'intelligence': maximum(
                                     int((villager1.base_intelligence + villager2.base_intelligence) / 2
                                         * uniform(*stat_range)),
                                     int(config['base-stats'][sex]['intelligence'] * max_var)),
                                 'accuracy': maximum((villager1.base_accuracy + villager2.base_accuracy) / 2,
                                                     config['base-stats']['base-accuracy'] * max_var)
                             }, baby_sex))
    
    # Sets the baby data on the female villager
    
    if villager1.sex == 'female':
        villager1.pregnant = True
        villager1.pregnant_time = 0
        villager1.children_pregnant = children
    else:
        villager2.pregnant = True
        villager2.pregnant_time = 0
        villager2.children_pregnant = children
    
    return villager_index, partner_index
コード例 #10
0
def process_combat(villager1, villager2, target_off_guard, villager_index, target_index):
    # Simulates a combat between the attacker and the target
    
    info('%s attacks %s' % (villager1, villager2),
         village=villager1.village.name)
    
    not_flee_chance = 1 - config['action-extra']['flee-chance']
    resistance_effect = config['action-extra']['resistance-effect']
    off_guard_penalty = config['action-extra']['off-guard-penalty']
    turns = 0
    
    # Runs loop while there's no fleeing
    # If target is baby, can't flee
    
    # When one or both villagers die, fight is over
    
    while True:
        if not villager1.alive or not villager2.alive:
            break
        
        turns += 1
        
        # Calculates flee chance
        
        if uniform(0, 1) > (1 - not_flee_chance ** turns) and not villager2.baby:
            # Target fled, fight is over
            break
        
        # Villager 1 attacks
        
        if randint(0, 100) <= villager1.actual_accuracy and villager1.alive:

            target_resistance = villager2.actual_resistance
            
            if target_off_guard:
                # Applies off-guard penalty
                
                target_resistance *= 1 - off_guard_penalty
                target_resistance = int(target_resistance)
            
            # Calculates damage
            
            dmg = villager1.actual_strength
            dmg *= ((1 - resistance_effect) ** target_resistance)
            dmg = int(dmg)
            
            # Applies damage
            
            villager2.lose_health(dmg)
        
        if randint(0, 100) <= villager2.actual_accuracy and villager2.alive:

            # If villager is baby, can't do anything
            
            if not villager2.baby:
                # Calculates damage
                
                dmg = villager2.actual_strength
                dmg *= ((1 - resistance_effect) ** villager1.actual_resistance)
                dmg = int(dmg)
                
                # Applies damage
                
                villager1.lose_health(dmg)
    
    return villager_index, target_index
コード例 #11
0
    w = World(v1, v2)

    # Instantiates an updater thread object to deal with day loops

    wu = WorldUpdater(w, barrier)

    # Instantiates plot animation handler

    pl = PlotAnim(config['village-names'], wu, barrier)

    # Starts day loop and plotting

    wu.start()
    pl.start_animation()


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        # If any exception occurs, logs it and exits

        info('')
        info('[EXCEPTION]')
        info('Exception occurred during program execution:\n %s:\n %s' %
             (e, format_exc()))

        print('Exception occurred during program execution:\n %s:\n %s' %
              (e, format_exc()))
        exit(-1)