def do_tick(self): """ Performs a tick of the simulation :return Log line """ notifications.clear_received() last_rounds_notifications = notifications.get_last() notifications.clear() self.turn += 1 actions = [ actor.tick_action(last_rounds_notifications) for actor in self.actors ] for action in actions: action() number_notifications = len(last_rounds_notifications.get()) active_interventions = len(CityMap.get_interventions()) self._csv_log([ self.turn, number_notifications, notifications.received, active_interventions, CityMap.moves, len(self.get_ambulances()), len(self.get_policemen()), CityMap.ambulance_moves, CityMap.policeman_moves, len(self.intervening_policemen()), len(self.patroling_policemen()), len(self.assisting_ambulances()) ]) CityMap.clear_moves()
def _by_proximity(ambulances, location): # TODO: Refactor - generalize ( move to map ) ambulance_distances = [(CityMap.get_distance(ambulance.location, location), ambulance) for ambulance in ambulances] ambulance_distances.sort(key=lambda x: x[0]) return [tpl[1] for tpl in ambulance_distances]
def insert_random_intervention(sim_manager): from smart_intervention.globals import CityMap from smart_intervention.events.intervention_event import InterventionEvent def generate_random_intervention(): locations = CityMap.get_locations() forbidden_locations = [ *sim_manager.police_outposts, sim_manager.ambulance_hq ] free_locations = [ location for location in locations if not location.intervention_event and location not in forbidden_locations ] if not free_locations: return danger = round(random(), 2) health_index = random() * 10 location = pick_random(free_locations) location.intervention_event = InterventionEvent( danger, health_index, location) print( f'Generated event: Location: {id(location)}, Health: {health_index}, Danger: {danger}', flush=True) active_interventions = len(CityMap.get_interventions()) if active_interventions >= 2: return elif active_interventions == 1 and random_decision(0.2): generate_random_intervention() elif active_interventions == 0 and random_decision(0.4): generate_random_intervention()
def _by_proximity(units, location): policemen_distances = [ (CityMap.get_distance(policeman.location, location), policeman) for policeman in units ] policemen_distances.sort(key=lambda x: (x[0], -x[1].efficiency)) return [tpl[1] for tpl in policemen_distances]
def create_intervention(sim_manager): from smart_intervention.globals import CityMap from smart_intervention.events.intervention_event import InterventionEvent locations = CityMap.get_locations() forbidden_locations = [ *sim_manager.police_outposts, sim_manager.ambulance_hq ] free_locations = [ location for location in locations if not location.intervention_event and location not in forbidden_locations ] if not free_locations: print( 'All of locations have an event, unable to create one. Aborting...', flush=True) autogen = input('Do you want to auto generate event? y/n\n') if autogen == 'y': danger = round(random(), 2) health_index = round(random() * 10, 0) location = pick_random(free_locations) print( f'Generated event: \n\tLocation: {id(location)}\n\tHealth: {health_index}\n\tDanger: {danger}\n', flush=True) else: location_id = input( f'Pick a location from this list:\n\t{id_list(free_locations)}\n') try: location = validate_and_get_user_choice(free_locations, location_id) except RuntimeError: print('ERROR: Invalid location chosen', flush=True) return danger = input( 'Pick danger index (floating point 0-1), which indicates how likely the event is to break out into gunfight:\n' ) try: danger = float(danger) except ValueError: print(f'Invalid value chosen as danger level!: {danger}', flush=True) return health_index = input( 'Pick events health index (number), which indicates how difficult it is for policemen to finish:\n' ) try: health_index = float(health_index) except ValueError: print( f'Invalid value chosen as health_index level!: {health_index}', flush=True) return location.intervention_event = InterventionEvent(danger, health_index, location)
def move_forward(self, route: List): """ Method which moves the actor towards end of the route If actor is not on an edge adjacent to beginning of the route, it routes him towards the beginning, with most optimal route :return: """ try: first_waypoint = route.pop(0) except IndexError: raise RoutingError('Cannot move forward, empty route') if CityMap.are_neighbors(first_waypoint, self.location): self.move_to(first_waypoint) else: route_to_waypoint = CityMap.route(self.location, first_waypoint) try: self.move_to(route_to_waypoint[0]) except IndexError: raise RoutingError('Cannot find route to waypoint') if hasattr(self, 'log'): self.log.info(f'Moving to {id(first_waypoint)}')
def action(): processable_len = len(processable_notifications.get()) self.log.debug(f'Received {processable_len} processable notifications') notifications.declare_received(processable_len) ManagementCenterNotificationProcessor(self).process(processable_notifications) interventions = CityMap.get_interventions() not_gunfight_interventions = [ intervention for intervention in interventions if not intervention.armed_combat and intervention.active ] not_gunfight_interventions.sort( key=lambda intervention: len(self._resource_monitor.get_dispatched_and_intervening(intervention)) ) self._process_interventions(not_gunfight_interventions)
def random_route(): from smart_intervention.globals import CityMap locations = CityMap.get_locations() route_length = pick_random(range(1, len(locations) - 3)) route = [] for i in range(route_length): if i == 0: route.append(pick_random(locations)) else: next_locations_candidates = [ location for location in locations if location != route[i - 1] ] route.append(pick_random(next_locations_candidates)) return route
def declare_move(self): CityMap.declare_move() actor_class = self.__class__.__name__ if actor_class == 'Policeman': CityMap.declare_policeman_move() elif actor_class == 'Ambulance': CityMap.declare_ambulance_move() else: raise RuntimeError('Did not recognise geo actor class')
def generate_environment_and_actors(): from smart_intervention.models.actors.policeman.policeman import Policeman from smart_intervention.models.actors.ambulance.ambulance import Ambulance from smart_intervention.models.actors.ambulance_headquarter.ambulance_headquarter import AmbulanceHeadquarter from smart_intervention.models.actors.management_center.management_center import ManagementCenter from smart_intervention.globals import CityMap locations = CityMap.get_locations() police_outposts = [pick_random(locations), pick_random(locations)] ambulance_hq = pick_random(locations) print('Starting parameters:', flush=True) def gen_policeman(_): hq = pick_random(police_outposts) policeman = Policeman(purpose=PolicemanPurpose.IDLE, location=hq, efficiency=round(random(), 2), policeman_hq=hq) print( f'Policeman:\n\tEfficiency: {policeman.efficiency}\n\tPolice outpost: {id(policeman.policeman_hq)}', flush=True) return policeman policemen = generate_n(gen_policeman, n=POLICEMEN_COUNT) def gen_ambulance(_): amb = Ambulance(purpose=AmbulancePurpose.IDLE, location=ambulance_hq, efficiency=round(random(), 2), ambulance_hq=ambulance_hq) print( f'Ambulance:\n\tEfficiency: {amb.efficiency}\n\tHeadquarter: {id(amb.ambulance_hq)}', flush=True) return amb ambulances = generate_n(gen_ambulance, n=AMBULANCES_COUNT) MC = ManagementCenter(policemen) AHQ = AmbulanceHeadquarter(ambulances) print('', flush=True) return [ *policemen, *ambulances, MC, AHQ, ], police_outposts, ambulance_hq
def generate_random_intervention(): locations = CityMap.get_locations() forbidden_locations = [ *sim_manager.police_outposts, sim_manager.ambulance_hq ] free_locations = [ location for location in locations if not location.intervention_event and location not in forbidden_locations ] if not free_locations: return danger = round(random(), 2) health_index = random() * 10 location = pick_random(free_locations) location.intervention_event = InterventionEvent( danger, health_index, location) print( f'Generated event: Location: {id(location)}, Health: {health_index}, Danger: {danger}', flush=True)
def get_route_from_user(): from smart_intervention.globals import CityMap locations = CityMap.get_locations() route = [] pick_location_command = f'Pick a location from this list, or "f" to finish creating route:\n\t{id_list(locations)}\n' location_id = input(pick_location_command) while location_id != 'f': try: location = validate_and_get_user_choice(locations, location_id) except RuntimeError: if location_id == 'f': break else: return route.append(location) location_id = input(pick_location_command) return route
def _route_with_purpose( self, location, purpose ): # TODO: Refactor - abstract out to geolocated + purposeful actor self._route_to(CityMap.route(self.location, location)) self.re_purpose(purpose)
def route_with_purpose(self, location, purpose): self._route_to(CityMap.route(self.location, location)) self.re_purpose(purpose)