def test(self): cache = ConnectedAreaCache() self.assertEquals(0, len(cache.areas)) cache.add_area([(0, 0), (1, 1)]) self.assertEquals(2, len(cache.areas)) self.assertEquals(set([(0, 0)]), cache.areas[cache.area_numbers[(0, 0)]]) self.assertEquals(set([(1, 1)]), cache.areas[cache.area_numbers[(1, 1)]]) cache.add_area([(1, 4), (1, 3), (1, 2)]) self.assertEquals(2, len(cache.areas)) self.assertEquals(set([(0, 0)]), cache.areas[cache.area_numbers[(0, 0)]]) self.assertEquals(set([(1, 1), (1, 2), (1, 3), (1, 4)]), cache.areas[cache.area_numbers[(1, 1)]]) cache.add_area([(0, 1)]) self.assertEquals(1, len(cache.areas)) self.assertEquals(set([(0, 0), (0, 1), (1, 1), (1, 2), (1, 3), (1, 4)]), cache.areas[cache.area_numbers[(0, 0)]]) cache.remove_area([(0, 1)]) self.assertEquals(2, len(cache.areas)) self.assertEquals(set([(0, 0)]), cache.areas[cache.area_numbers[(0, 0)]]) self.assertEquals(set([(1, 1), (1, 2), (1, 3), (1, 4)]), cache.areas[cache.area_numbers[(1, 1)]]) cache.remove_area([(0, 0)]) self.assertFalse((0, 0) in cache.area_numbers) self.assertEquals(1, len(cache.areas)) self.assertEquals(set([(1, 1), (1, 2), (1, 3), (1, 4)]), cache.areas[cache.area_numbers[(1, 1)]]) cache.remove_area([(1, 2), (1, 3)]) self.assertEquals(2, len(cache.areas)) self.assertEquals(set([(1, 1)]), cache.areas[cache.area_numbers[(1, 1)]]) self.assertEquals(set([(1, 4)]), cache.areas[cache.area_numbers[(1, 4)]]) cache.remove_area([(1, 1), (1, 4)]) self.assertEquals(0, len(cache.areas))
class PotentialRoadConnectivityCache(object): """ Query whether a toad connection between two sets of coordinates is possible. This class is used by the AI to figure out whether it might be possible to build a road between two sets of coordinates. Potentially because the area contains some part of the AI's plan and the land it has a plan for may be either owned by the AI or not yet owned by anyone. """ def __init__(self, area_builder): self._area_builder = area_builder self._land_manager = area_builder.land_manager self._settlement_ground_map = area_builder.settlement.ground_map self._cache = ConnectedAreaCache() self.area_numbers = self._cache.area_numbers # {(x, y): area id, ...} def modify_area(self, coords_list): """ Refresh the usability of the coordinates in the given list. This function is called with a list of coordinates on which the possibility of building a road may have changed. It figures out whether it is possible to build a road on (x, y) and updates the underlying ConnectedAreaCache accordingly. """ add_list = [] remove_list = [] for coords in coords_list: if coords not in self._settlement_ground_map: if coords in self.area_numbers: remove_list.append(coords) elif coords in self._land_manager.coastline: if coords in self.area_numbers: remove_list.append(coords) elif coords in self._land_manager.roads: if coords not in self.area_numbers: add_list.append(coords) elif coords in self._area_builder.plan: if self._area_builder.plan[coords][0] == BUILDING_PURPOSE.NONE: if coords not in self.area_numbers: add_list.append(coords) else: assert self._area_builder.plan[coords][ 0] != BUILDING_PURPOSE.ROAD if coords in self.area_numbers: remove_list.append(coords) else: if coords in self.area_numbers: remove_list.append(coords) if add_list: self._cache.add_area(add_list) if remove_list: self._cache.remove_area(remove_list) def is_connection_possible(self, coords_set1, coords_set2): """Return True if and only if it is possible to connect the two coordinate sets. More specifically, it returns True if and only if it is possible to build a toad from some (x1, y1) in coords_set1 to some (x2, y2) in coords_set2 entirely within the area. This is done cheaply using the underlying ConnectedAreaCache. """ areas1 = set() for coords in coords_set1: if coords in self.area_numbers: areas1.add(self.area_numbers[coords]) for coords in coords_set2: if coords in self.area_numbers: if self.area_numbers[coords] in areas1: return True return False
class PotentialRoadConnectivityCache(object): """ Query whether a toad connection between two sets of coordinates is possible. This class is used by the AI to figure out whether it might be possible to build a road between two sets of coordinates. Potentially because the area contains some part of the AI's plan and the land it has a plan for may be either owned by the AI or not yet owned by anyone. """ def __init__(self, area_builder): self._area_builder = area_builder self._land_manager = area_builder.land_manager self._settlement_ground_map = area_builder.settlement.ground_map self._cache = ConnectedAreaCache() self.area_numbers = self._cache.area_numbers # {(x, y): area id, ...} def modify_area(self, coords_list): """ Refresh the usability of the coordinates in the given list. This function is called with a list of coordinates on which the possibility of building a road may have changed. It figures out whether it is possible to build a road on (x, y) and updates the underlying ConnectedAreaCache accordingly. """ add_list = [] remove_list = [] for coords in coords_list: if coords not in self._settlement_ground_map: if coords in self.area_numbers: remove_list.append(coords) elif coords in self._land_manager.coastline: if coords in self.area_numbers: remove_list.append(coords) elif coords in self._land_manager.roads: if coords not in self.area_numbers: add_list.append(coords) elif coords in self._area_builder.plan: if self._area_builder.plan[coords][0] == BUILDING_PURPOSE.NONE: if coords not in self.area_numbers: add_list.append(coords) else: assert self._area_builder.plan[coords][0] != BUILDING_PURPOSE.ROAD if coords in self.area_numbers: remove_list.append(coords) else: if coords in self.area_numbers: remove_list.append(coords) if add_list: self._cache.add_area(add_list) if remove_list: self._cache.remove_area(remove_list) def is_connection_possible(self, coords_set1, coords_set2): """Return true if and only if it is possible to connect the two coordinate sets. More specifically, it returns true if and only if it is possible to build a toad from some (x1, y1) in coords_set1 to some (x2, y2) in coords_set2 entirely within the area. This is done cheaply using the underlying ConnectedAreaCache. """ areas1 = set() for coords in coords_set1: if coords in self.area_numbers: areas1.add(self.area_numbers[coords]) for coords in coords_set2: if coords in self.area_numbers: if self.area_numbers[coords] in areas1: return True return False