def fill_places(kb, hero_info, max_distance): places = [] for place in places_storage.all(): path_length = waymarks_storage.look_for_road(places_storage[hero_info.position_place_id], place).length if path_length > max_distance: continue places.append((path_length, place)) places.sort() chosen_places = [] for base_distance, place in places: for chosen_place in chosen_places: path_length = waymarks_storage.look_for_road(chosen_place, place).length if path_length > max_distance: break else: chosen_places.append(place) for place in chosen_places: uid = uids.place(place.id) if uid in kb: continue kb += fact_place(place)
def test_add_del_road(self): self.assertEqual(Road.objects.all().count(), 2) self.r2.exists = False self.r2.save() r3 = RoadPrototype.create(point_1=self.p1, point_2=self.p3) self.assertEqual(Road.objects.all().count(), 3) self.assertEqual(Road.objects.filter(exists=False).count(), 1) self.assertEqual(Road.objects.filter(exists=True).count(), 2) self.assertEqual(Waymark.objects.all().count(), 9) waymark = waymarks_storage.look_for_road(point_from=self.p1.id, point_to=self.p3.id) self.assertEqual(waymark.road.id, self.r1.id) update_waymarks() self.assertEqual(Waymark.objects.all().count(), 9) waymark = waymarks_storage.look_for_road(point_from=self.p1.id, point_to=self.p3.id) self.assertEqual(waymark.road.id, r3.id) self.assertNotEqual(r3.id, self.r1.id)
def fill_places(kb, hero_info, max_distance): places = [] for place in places_storage.all(): path_length = waymarks_storage.look_for_road( places_storage[hero_info.position_place_id], place).length if path_length > max_distance: continue places.append((path_length, place)) places.sort() chosen_places = [] for base_distance, place in places: for chosen_place in chosen_places: path_length = waymarks_storage.look_for_road(chosen_place, place).length if path_length > max_distance: break else: chosen_places.append(place) for place in chosen_places: uid = uids.place(place.id) if uid in kb: continue kb += fact_place(place)
def get_minumum_distance_to(self, destination): from the_tale.game.map.roads.storage import waymarks_storage if self.place: return waymarks_storage.look_for_road(self.place, destination).length if self.is_walking: x = self.coordinates_from[0] + ( self.coordinates_to[0] - self.coordinates_from[0]) * self.percents y = self.coordinates_from[1] + ( self.coordinates_to[1] - self.coordinates_from[1]) * self.percents nearest_place = self.get_nearest_place() return math.hypot( x - nearest_place.x, y - nearest_place.y) + waymarks_storage.look_for_road( nearest_place, destination).length # if on road place_from = self.road.point_1 place_to = self.road.point_2 if self.invert_direction: place_from, place_to = place_to, place_from delta_from = self.road.length * self.percents delta_to = self.road.length * (1 - self.percents) return min( waymarks_storage.look_for_road(place_from, destination).length + delta_from, waymarks_storage.look_for_road(place_to, destination).length + delta_to)
def search_available_connections(person, minimum_distance=None): excluded_persons_ids = storage.social_connections.get_connected_persons_ids(person) persons = storage.persons_storage.filter(state=relations.PERSON_STATE.IN_GAME) candidates = [] if minimum_distance is None: minimum_distance = get_next_connection_minimum_distance(person) for candidate in persons: if candidate.id in excluded_persons_ids: continue if person.place_id == candidate.place_id: continue path_length = waymarks_storage.look_for_road(person.place, candidate.place).length if path_length > c.QUEST_AREA_RADIUS: continue if path_length < minimum_distance: continue candidates.append(candidate) if not candidates: return search_available_connections( person, minimum_distance * conf.settings.SOCIAL_CONNECTIONS_MIN_DISTANCE_DECREASE ) return candidates
def test_search_available_connections(self): # check if distances between places not changed distance_1_2 = waymarks_storage.look_for_road(self.place_1, self.place_2).length distance_2_3 = waymarks_storage.look_for_road(self.place_2, self.place_3).length self.assertTrue( distance_2_3 < distance_1_2 < waymarks_storage.look_for_road( self.place_1, self.place_3).length) # check that every place has more then 1 person self.assertTrue(len(self.place_1.persons) > 1) self.assertTrue(len(self.place_2.persons) > 1) self.assertTrue(len(self.place_3.persons) > 1) self.assertEqual(len(self.place_3.persons), 3) connected_persons = self.place_3.persons[1] test_person = self.place_2.persons[0] logic.create_social_connection( connection_type=relations.SOCIAL_CONNECTION_TYPE.random(), person_1=test_person, person_2=connected_persons) expected_persons = set(person.id for person in self.place_3.persons) - set( (connected_persons.id, )) person_out_game = self.place_3.add_person() person_out_game.move_out_game() person_removed = self.place_3.add_person() person_removed.remove_from_game() with mock.patch('the_tale.game.balance.constants.QUEST_AREA_RADIUS', (distance_1_2 + distance_2_3) / 2): candidates = set( person.id for person in logic.search_available_connections(test_person)) # only ingame persons — no person_out_game and person_removed # no persons from same place — no persons from place_2 # no persons out radius — no persons from place_1 # no connected_persons — no connected_person self.assertEqual(expected_persons, candidates)
def test_diameter(self): self.hero.position.set_place(self.place_2) f_place_2 = logic.fact_place(self.place_2) f_place_3 = logic.fact_place(self.place_3) logic.fill_places(self.knowledge_base, self.get_hero_info(), waymarks_storage.look_for_road(self.place_1, self.place_3).length - 1) self.check_facts(places=[f_place_2, f_place_3])
def test_second_fill(self): self.hero.position.set_place(self.place_1) f_place_1 = logic.fact_place(self.place_1) f_place_2 = logic.fact_place(self.place_2) logic.fill_places(self.knowledge_base, self.get_hero_info(), waymarks_storage.look_for_road(self.place_1, self.place_2).length) self.check_facts(places=[f_place_1, f_place_2])
def test_no_social_connections(self): self.hero.position.set_place(self.place_1) logic.fill_places(self.knowledge_base, self.get_hero_info(), waymarks_storage.look_for_road(self.place_1, self.place_2).length) logic.setup_persons(self.knowledge_base, self.get_hero_info()) logic.setup_social_connections(self.knowledge_base) self.check_facts(places=[logic.fact_place(self.place_1), logic.fact_place(self.place_2)], persons=[logic.fact_person(person) for person in persons_storage.persons_storage.all() if person.place_id != self.place_3.id], locations=[logic.fact_located_in(person) for person in persons_storage.persons_storage.all() if person.place_id != self.place_3.id], social_connections=[])
def update_waymarks(): # pylint: disable=R0912 places = places_storage.all() roads = roads_storage.all_exists_roads() places_len = len(places) paths = [ [ Path() for place in xrange(places_len) ] for i in xrange(places_len)] # pylint: disable=W0612 p2i = dict( (place.id, i) for i, place in enumerate(places)) for i in xrange(len(places)): paths[i][i].update_path(0, None) for road in roads: i = p2i[road.point_1_id] j = p2i[road.point_2_id] paths[i][j].update_path(road.length, road.id) paths[j][i].update_path(road.length, road.id) for k in xrange(places_len): for i in xrange(places_len): for j in xrange(places_len): new_len = min(paths[i][j].length, paths[i][k].length + paths[k][j].length) paths[i][j].update_path(new_len, paths[i][k].road_id) for row in paths: res = [] for el in row: res.append(el.road_id) for i in xrange(places_len): for j in xrange(places_len): if paths[i][j].road_id is not None: road = roads_storage[paths[i][j].road_id] else: road = None waymark = waymarks_storage.look_for_road(point_from=places[i].id, point_to=places[j].id) if waymark: waymark.road = road waymark.length = paths[i][j].length waymark.save() else: waymark = WaymarkPrototype.create(point_from=places[i], point_to=places[j], road=road, length=paths[i][j].length) waymarks_storage.update_version()
def test_add_del_road(self): self.assertEqual(Road.objects.all().count(), 2) self.r2.exists = False self.r2.save() r3 = RoadPrototype.create(point_1=self.p1, point_2=self.p3) self.assertEqual(Road.objects.all().count(), 3) self.assertEqual(Road.objects.filter(exists=False).count(), 1) self.assertEqual(Road.objects.filter(exists=True).count(), 2) self.assertEqual(Waymark.objects.all().count(), 9) waymark = waymarks_storage.look_for_road(point_from=self.p1.id, point_to=self.p3.id) self.assertEqual(waymark.road.id, self.r1.id) update_waymarks() self.assertEqual(Waymark.objects.all().count(), 9) waymark = waymarks_storage.look_for_road(point_from=self.p1.id, point_to=self.p3.id) self.assertEqual(waymark.road.id, r3.id) self.assertNotEqual(r3.id, self.r1.id)
def test_get_next_connection_minimum_distance__distance_calculation(self): person = self.place_1.persons[0] for i in xrange(conf.settings.SOCIAL_CONNECTIONS_MINIMUM - 1): logic.create_missing_connection(person) minimum_distance = conf.settings.SOCIAL_CONNECTIONS_MINIMUM * c.QUEST_AREA_RADIUS * conf.settings.SOCIAL_CONNECTIONS_AVERAGE_PATH_FRACTION for connected_person_id in storage.social_connections.get_connected_persons_ids(person): connected_person = storage.persons_storage[connected_person_id] path_length = waymarks_storage.look_for_road(person.place, connected_person.place).length minimum_distance -= path_length self.assertEqual(minimum_distance, logic.get_next_connection_minimum_distance(person))
def fill_places_for_first_quest(kb, hero_info): best_distance = c.QUEST_AREA_MAXIMUM_RADIUS best_destination = None for place in places_storage.all(): if place.id == hero_info.position_place_id: continue path_length = waymarks_storage.look_for_road(places_storage[hero_info.position_place_id], place).length if path_length < best_distance: best_distance = path_length best_destination = place kb += fact_place(best_destination) kb += fact_place(places_storage[hero_info.position_place_id])
def get_minumum_distance_to(self, destination): from the_tale.game.map.roads.storage import waymarks_storage if self.place: return waymarks_storage.look_for_road(self.place, destination).length if self.is_walking: x = self.coordinates_from[0] + (self.coordinates_to[0] - self.coordinates_from[0]) * self.percents y = self.coordinates_from[1] + (self.coordinates_to[1] - self.coordinates_from[1]) * self.percents nearest_place = self.get_nearest_place() return math.hypot(x-nearest_place.x, y-nearest_place.y) + waymarks_storage.look_for_road(nearest_place, destination).length # if on road place_from = self.road.point_1 place_to = self.road.point_2 if self.invert_direction: place_from, place_to = place_to, place_from delta_from = self.road.length * self.percents delta_to = self.road.length * (1-self.percents) return min(waymarks_storage.look_for_road(place_from, destination).length + delta_from, waymarks_storage.look_for_road(place_to, destination).length + delta_to)
def test_search_available_connections(self): # check if distances between places not changed distance_1_2 = waymarks_storage.look_for_road(self.place_1, self.place_2).length distance_2_3 = waymarks_storage.look_for_road(self.place_2, self.place_3).length self.assertTrue(distance_2_3 < distance_1_2 < waymarks_storage.look_for_road(self.place_1, self.place_3).length) # check that every place has more then 1 person self.assertTrue(len(self.place_1.persons) > 1) self.assertTrue(len(self.place_2.persons) > 1) self.assertTrue(len(self.place_3.persons) > 1) self.assertEqual(len(self.place_3.persons), 3) connected_persons = self.place_3.persons[1] test_person = self.place_2.persons[0] logic.create_social_connection(connection_type=relations.SOCIAL_CONNECTION_TYPE.random(), person_1=test_person, person_2=connected_persons) expected_persons = set(person.id for person in self.place_3.persons) - set((connected_persons.id,)) person_out_game = self.place_3.add_person() person_out_game.move_out_game() person_removed = self.place_3.add_person() person_removed.remove_from_game() with mock.patch('the_tale.game.balance.constants.QUEST_AREA_RADIUS', (distance_1_2 + distance_2_3) / 2): candidates = set(person.id for person in logic.search_available_connections(test_person)) # only ingame persons — no person_out_game and person_removed # no persons from same place — no persons from place_2 # no persons out radius — no persons from place_1 # no connected_persons — no connected_person self.assertEqual(expected_persons, candidates)
def get_next_connection_minimum_distance(person): if conf.settings.SOCIAL_CONNECTIONS_MINIMUM > len( storage.social_connections.get_connected_persons_ids(person)) + 1: return 0 minimum_distance = conf.settings.SOCIAL_CONNECTIONS_MINIMUM * c.QUEST_AREA_RADIUS * conf.settings.SOCIAL_CONNECTIONS_AVERAGE_PATH_FRACTION for connected_person_id in storage.social_connections.get_connected_persons_ids( person): connected_person = storage.persons_storage[connected_person_id] path_length = waymarks_storage.look_for_road( person.place, connected_person.place).length minimum_distance -= path_length return minimum_distance
def fill_places_for_first_quest(kb, hero_info): best_distance = c.QUEST_AREA_MAXIMUM_RADIUS best_destination = None for place in places_storage.all(): if place.id == hero_info.position_place_id: continue path_length = waymarks_storage.look_for_road( places_storage[hero_info.position_place_id], place).length if path_length < best_distance: best_distance = path_length best_destination = place kb += fact_place(best_destination) kb += fact_place(places_storage[hero_info.position_place_id])
def get_next_connection_minimum_distance(person): if conf.settings.SOCIAL_CONNECTIONS_MINIMUM > len(storage.social_connections.get_connected_persons_ids(person)) + 1: return 0 minimum_distance = ( conf.settings.SOCIAL_CONNECTIONS_MINIMUM * c.QUEST_AREA_RADIUS * conf.settings.SOCIAL_CONNECTIONS_AVERAGE_PATH_FRACTION ) for connected_person_id in storage.social_connections.get_connected_persons_ids(person): connected_person = storage.persons_storage[connected_person_id] path_length = waymarks_storage.look_for_road(person.place, connected_person.place).length minimum_distance -= path_length return minimum_distance
def test_get_next_connection_minimum_distance__distance_calculation(self): person = self.place_1.persons[0] for i in xrange(conf.settings.SOCIAL_CONNECTIONS_MINIMUM - 1): logic.create_missing_connection(person) minimum_distance = conf.settings.SOCIAL_CONNECTIONS_MINIMUM * c.QUEST_AREA_RADIUS * conf.settings.SOCIAL_CONNECTIONS_AVERAGE_PATH_FRACTION for connected_person_id in storage.social_connections.get_connected_persons_ids( person): connected_person = storage.persons_storage[connected_person_id] path_length = waymarks_storage.look_for_road( person.place, connected_person.place).length minimum_distance -= path_length self.assertEqual(minimum_distance, logic.get_next_connection_minimum_distance(person))
def search_available_connections(person, minimum_distance=None): excluded_persons_ids = storage.social_connections.get_connected_persons_ids( person) persons = storage.persons_storage.filter( state=relations.PERSON_STATE.IN_GAME) candidates = [] if minimum_distance is None: minimum_distance = get_next_connection_minimum_distance(person) for candidate in persons: if candidate.id in excluded_persons_ids: continue if person.place_id == candidate.place_id: continue path_length = waymarks_storage.look_for_road(person.place, candidate.place).length if path_length > c.QUEST_AREA_RADIUS: continue if path_length < minimum_distance: continue candidates.append(candidate) if not candidates: return search_available_connections( person, minimum_distance * conf.settings.SOCIAL_CONNECTIONS_MIN_DISTANCE_DECREASE) return candidates
def test_social_connections(self): persons_logic.sync_social_connections() self.hero.position.set_place(self.place_1) logic.fill_places(self.knowledge_base, self.get_hero_info(), waymarks_storage.look_for_road(self.place_1, self.place_2).length) logic.setup_persons(self.knowledge_base, self.get_hero_info()) logic.setup_social_connections(self.knowledge_base) expected_connections = [] for person in persons_storage.persons_storage.all(): if person.place_id == self.place_3.id: continue for connection_type, connected_person_id in persons_storage.social_connections.get_person_connections(person): connected_person = persons_storage.persons_storage[connected_person_id] if connected_person.place_id == self.place_3.id: continue expected_connections.append(logic.fact_social_connection(connection_type, uids.person(person.id), uids.person(connected_person.id))) self.check_facts(places=[logic.fact_place(self.place_1), logic.fact_place(self.place_2)], persons=[logic.fact_person(person) for person in persons_storage.persons_storage.all() if person.place_id != self.place_3.id], locations=[logic.fact_located_in(person) for person in persons_storage.persons_storage.all() if person.place_id != self.place_3.id], social_connections=expected_connections)
def test_prerequiries(self): w_1_2 = waymarks_storage.look_for_road(self.place_1, self.place_2).length w_1_3 = waymarks_storage.look_for_road(self.place_1, self.place_3).length w_2_3 = waymarks_storage.look_for_road(self.place_2, self.place_3).length self.assertTrue(w_1_3 > w_1_2 > w_2_3)
def test_maximum_radius(self): self.hero.position.set_place(self.place_1) logic.fill_places(self.knowledge_base, self.get_hero_info(), waymarks_storage.look_for_road(self.place_1, self.place_3).length) self.check_facts(places=[logic.fact_place(self.place_1), logic.fact_place(self.place_2), logic.fact_place(self.place_3)])