def begin(self):
        from grid import singleton_grid, grid_from_description
        from resource import singleton_resource

        singleton_grid.squares = grid_from_description(self.grid)
        self.time_remaining = self.duration
        singleton_resource.restore_defaults()
        show_warning("")
 def kill_worker(self):
     ''' Kill a worker.  Idle workers are killed first, otherwise kill a
     random worker from the grid. '''
     from grid import singleton_grid
     
     if not self.spend({'Unemployed': 1}):
         singleton_grid.kill_worker_on_grid()
     
     total_workers = self.get('Unemployed') + singleton_grid.num_workers_on_grid()
     if total_workers != 0:
         show_warning("Your workers are starving! Plant some crops and place workers on them.")
     self.dead_workers += 1
     if self.dead_workers == 4: #add a graveyard to the map
         self.dead_workers = 0
         singleton_grid.add_grave()
 def enforce_worker_limit(self):
     ''' Cap the worker count based on the number of house. If there are more
     than capacity, 'kill' off the extra workers (they are 'leaving' because
     there is no space).'''
     from grid import singleton_grid
     busy_workers = singleton_grid.num_workers_on_grid()
     idle_workers = self.get('Unemployed')
     total_workers = self.get_total_workers()
     capacity = singleton_grid.population_limit()
     if total_workers > capacity:
         # First, remove fractional worker, if any
         self.resources['Unemployed'] = math.floor(idle_workers)
         total_workers = busy_workers + self.get('Unemployed')
         show_warning("There is a housing crunch. Build houses before more people will come to your city.")
         # If still over capacity, kill workers
         for i in range(int(total_workers - capacity)):
             self.kill_worker()
    def update(self):
        """Consumes some amount of food based on the number of workers"""
        from grid import singleton_grid
        
        # Feed workers.
        total_workers = self.get('Unemployed') + singleton_grid.num_workers_on_grid()
        cost = {'Food': total_workers*0.005}
        # If there isn't enough food, then kill one off.
        if not self.spend(cost) and total_workers > 0.0:
            death_rate = 0.001
            if random.random() < death_rate*total_workers:
                self.kill_worker()
            self.resources['Food'] = 0.0
        else: 
            show_warning("")
            #self.give({'food': 100}) # cannibalism
        
        # Attract workers if gold income is high. Every time they a total of 100 gold, 
        # they get an extra worker.
        min_gold_income_per_incoming_worker = 100
        
        # calculate the extra workers added
        extra_workers = (self.get('Gold') - self.previous_resources['Gold']) \
                        / min_gold_income_per_incoming_worker

        if extra_workers > 0:
            if self.get('Food') > 0:
                if self.get('Unemployed') < 5:
                    self.give({'Unemployed': extra_workers})
                    show_warning("")
                else:
                    show_warning("There are too many unemployed workers. Assign them before more people will come to your city.")
            else:
                show_warning("Your workers are starving! Build some farms and place workers on them.")  
        if self.get('Total Workers') == 0.0:
            show_warning("All of your workers have died! Now would be a good time to restart the level.")
        # update the record of past resources
        self.diff = dict(((name, self.resources[name] - self.previous_resources[name]) for name in self.resources))
        self.previous_resources = copy.copy(self.resources)

        self.enforce_worker_limit()
        self.resources['Total Workers'] = self.get_total_workers()
 def add_grave(self):
     '''adds a grave to the map. If there are no available squares it destrays a random destroyable building'''
     from message import show_warning
     if self.num_houses() != 0:
         not_assigned = True
         if self.is_full():
             while not_assigned:
                 r = random.randint(0, rows-1)
                 c = random.randint(0,cols-1)
                 if self.squares[r][c].destroyable() or self.destroyables < 2:
                     if self.demolish(r,c):
                         self.squares[r][c] = Grave()
                         not_assigned = False
         else:
             while not_assigned:
                 r = random.randint(0, rows-1)
                 c = random.randint(0,cols-1)
                 if self.squares[r][c].buildable():
                     self.squares[r][c] = Grave()
                     not_assigned = False
     else:
         from message import show_warning
         show_warning("Your whole town is one big Cemetery! This might be a good time to restart the level.")
 def begin(self):
     super(SandboxLevel, self).begin()
     show_warning("You're on your own, now. Have fun.")