def __init__(self, name=None): self.name = name self.grids = {} self._shape = (0, 0) self._map_data = '' self._map_data_loop = '' self._weight_data = '' self._wall_data = '' self._portal_data = [] self._land_based_data = [] self._spawn_data = [] self._spawn_data_stack = [] self._spawn_data_loop = [] self._spawn_data_use_loop = False self._camera_data = [] self._camera_data_spawn_point = [] self._map_covered = SelectedGrids([]) self.in_map_swipe_preset_data = None self.poor_map_data = False self.camera_sight = (-3, -1, 3, 2) self.grid_connection = {}
def clear_roadblocks(self, roads, **kwargs): """Clear roadblocks. Args: roads(list[RoadGrids]): Returns: bool: True if clear an enemy. """ grids = SelectedGrids([]) for road in roads: grids = grids.add(road.roadblocks()) grids = self.select_grids(grids, **kwargs) if grids: logger.hr('Clear roadblock') self.show_select_grids(grids, **kwargs) self.clear_chosen_enemy(grids[0]) return True return False
def clear_potential_roadblocks(self, roads, **kwargs): """Avoid roadblock that only has one grid empty. Args: roads(list[RoadGrids]): Returns: bool: True if clear an enemy. """ grids = SelectedGrids([]) for road in roads: grids = grids.add(road.potential_roadblocks()) grids = self.select_grids(grids, **kwargs) if grids: logger.hr('Avoid potential roadblock') self.show_select_grids(grids, **kwargs) self.clear_chosen_enemy(grids[0]) return True return False
def clear_first_roadblocks(self, roads, **kwargs): """Ensure every roadblocks have one grid with is_cleared=True. Args: roads(list[RoadGrids]): Returns: bool: True if clear an enemy. """ grids = SelectedGrids([]) for road in roads: grids = grids.add(road.first_roadblocks()) grids = self.select_grids(grids, **kwargs) if grids: logger.hr('Clear first roadblock') self.show_select_grids(grids, **kwargs) self.clear_chosen_enemy(grids[0]) return True return False
def fleet_2_push_forward(self): """Move fleet 2 to the grid with lower grid.weight This will reduce the possibility of Boss fleet get stuck by enemies, especially for those one-way-road map from chapter 7 to chapter 9. Know more (in Chinese simplified): 9章道中战最小化路线规划 (Route Planning for battle minimization in chapter 9) https://wiki.biligame.com/blhx/9%E7%AB%A0%E9%81%93%E4%B8%AD%E6%88%98%E6%9C%80%E5%B0%8F%E5%8C%96%E8%B7%AF%E7%BA%BF%E8%A7%84%E5%88%92 Returns: bool: If pushed forward. """ if not self.config.FLEET_2: return False logger.info('Fleet_2 push forward') grids = self.map.select(is_land=False).sort(cost=True, weight=True) if self.map[self.fleet_2_location].weight <= grids[0].weight: logger.info('Fleet_2 pushed to destination') return False self.find_path_initial(self.fleet_2_location) fleets = SelectedGrids( [self.map[self.fleet_1_location], self.map[self.fleet_2_location]]) grids = grids.select(is_accessible=True, is_sea=True).delete(fleets) self.find_path_initial() if not grids: logger.info('Fleet_2 has no where to push') return False if self.map[self.fleet_2_location].weight <= grids[0].weight: logger.info('Fleet_2 pushed to closest grid') return False logger.info(f'Grids: {grids}') logger.info(f'Push forward: {grids[0]}') self.fleet_2.goto(grids[0]) self.fleet_1.switch_to() return True
def get_sea_grids(self): """ Get sea grids on current view Returns: SelectedGrids: """ sea = [] for local in self.view: if not local.predict_sea() or local.predict_current_fleet(): continue # local = np.array(location) - self.camera + self.view.center_loca location = np.array(local.location) + self.camera - self.view.center_loca location = tuple(location.tolist()) if location == self.fleet_current or location not in self.map: continue sea.append(self.map[location]) if len(self.fleet_current): center = self.fleet_current else: center = self.camera return SelectedGrids(sea).sort_by_camera_distance(center)
def get_boss_leave_button(self): for grid in self.view: if grid.predict_current_fleet(): return None grids = [grid for grid in self.view if grid.predict_caught_by_siren()] if len(grids) == 1: center = grids[0] elif len(grids) > 1: logger.warning( f'Found multiple fleets in boss ({grids}), use the center one') center = SelectedGrids(grids).sort_by_camera_distance( self.view.center_loca)[0] else: logger.warning('No fleet in boss, use camera center instead') center = self.view[self.view.center_loca] logger.info(f'Fleet in boss: {center}') # The left half grid next to the center grid. area = corner2inner( center.grid2screen(area2corner((1, 0.25, 1.5, 0.75)))) button = Button(area=area, color=(), button=area, name='BOSS_LEAVE') return button
def commission_detect(self, trial=1, area=None, skip_first_screenshot=True): """ Args: trial (int): Retry if has one invalid commission, usually because info_bar didn't disappear completely. area (tuple): skip_first_screenshot (bool): Returns: SelectedGrids: """ commissions = SelectedGrids([]) for _ in range(trial): if skip_first_screenshot: skip_first_screenshot = False else: self.device.screenshot() image = self.device.image if area is not None: image = crop(image, area) commissions = self._commission_detect(image) if commissions.count >= 2 and commissions.select( valid=False).count == 1: logger.info( 'Found 1 invalid commission, retry commission detect') continue else: return commissions logger.info('trials of commission detect exhausted, stop') return commissions
'battle': 5 }, { 'battle': 6, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, I1, \ A2, B2, C2, D2, E2, F2, G2, H2, I2, \ A3, B3, C3, D3, E3, F3, G3, H3, I3, \ A4, B4, C4, D4, E4, F4, G4, H4, I4, \ A5, B5, C5, D5, E5, F5, G5, H5, I5, \ A6, B6, C6, D6, E6, F6, G6, H6, I6, \ = MAP.flatten() step_on = SelectedGrids([E4, D3, G4, C3]) road_main = RoadGrids([D5, E4, D3, C3, A2, G4, H5, G3, G2]) roadblocks_d4 = RoadGrids([[D5, E6], E4, D3]) class Config: pass class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(step_on, roadblocks=[roadblocks_d4]): return True
def map_covered(self, nodes): """ Args: nodes (list): Contains str. """ self._map_covered = SelectedGrids([self[node2location(node)] for node in nodes])
def camera_data_spawn_point(self, nodes): """ Args: nodes (list): Contains str. """ self._camera_data_spawn_point = SelectedGrids([self[node2location(node)] for node in nodes])
MAP.spawn_data = [ {'battle': 0, 'enemy': 3}, {'battle': 1, 'enemy': 2, 'mystery': 1}, {'battle': 2, 'enemy': 2, 'mystery': 1}, {'battle': 3, 'enemy': 1, 'mystery': 2}, {'battle': 4, 'enemy': 1}, {'battle': 5, 'boss': 1}, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5 = MAP.flatten() ROAD_MAIN = RoadGrids([A3, [C3, B4, C5], [F1, G2, G3]]) GRIDS_FOR_FASTER = SelectedGrids([A3, C3, E3, G3]) FLEET_2_STEP_ON = SelectedGrids([A3, G3, C3, E3]) class Config: SUBMARINE = 0 class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(FLEET_2_STEP_ON, roadblocks=[ROAD_MAIN]): return True ignore = None
COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { 'height': (150, 255 - 24), 'width': (0.9, 10), 'prominence': 10, 'distance': 35, } EDGE_LINES_FIND_PEAKS_PARAMETERS = { 'height': (255 - 24, 255), 'prominence': 10, 'distance': 50, 'width': (0, 10), 'wlen': 1000, } step_on = SelectedGrids([A7, B1, B7, C7, D2, D3, G7, J2, K4, K6]) road_main = RoadGrids([A7, B1, B7, C7, D2, D3, [G7, J2], K4, K6]) class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(step_on, roadblocks=[road_main]): return True if self.clear_roadblocks([road_main]): return True if self.clear_potential_roadblocks([road_main]): return True return self.battle_default()
def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): """ Delay the NextRun of all OpSi tasks. Args: recon_scan (bool): True to delay all tasks requiring recon scan 30 min. submarine_call (bool): True to delay all tasks requiring submarine call 60 min. ap_limit (bool): True to delay all tasks requiring action points 360 min. """ if not recon_scan and not submarine_call and not ap_limit: return None kv = dict_to_kv({ 'recon_scan': recon_scan, 'submarine_call': submarine_call, 'ap_limit': ap_limit }) def delay_tasks(task_list, minutes): next_run = datetime.now().replace(microsecond=0) + timedelta( minutes=minutes) for task in task_list: keys = f'{task}.Scheduler.NextRun' current = deep_get(self.data, keys=keys, default=datetime(2020, 1, 1, 0, 0)) if current < next_run: logger.info(f'Delay task `{task}` to {next_run} ({kv})') self.modified[keys] = next_run def is_submarine_call(task): return deep_get(self.data, keys=f'{task}.OpsiFleet.Submarine', default=False) \ or 'submarine' in deep_get(self.data, keys=f'{task}.OpsiFleetFilter.Filter', default='').lower() def is_force_run(task): return deep_get(self.data, keys=f'{task}.OpsiExplore.ForceRun', default=False) \ or deep_get(self.data, keys=f'{task}.OpsiObscure.ForceRun', default=False) \ or deep_get(self.data, keys=f'{task}.OpsiAbyssal.ForceRun', default=False) \ or deep_get(self.data, keys=f'{task}.OpsiStronghold.ForceRun', default=False) def is_special_radar(task): return deep_get(self.data, keys=f'{task}.OpsiExplore.SpecialRadar', default=False) if recon_scan: tasks = SelectedGrids( ['OpsiExplore', 'OpsiObscure', 'OpsiStronghold']) tasks = tasks.delete(tasks.filter(is_force_run)).delete( tasks.filter(is_special_radar)) delay_tasks(tasks, minutes=30) if submarine_call: tasks = SelectedGrids([ 'OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiStronghold', 'OpsiMeowfficerFarming' ]) tasks = tasks.filter(is_submarine_call).delete( tasks.filter(is_force_run)) delay_tasks(tasks, minutes=60) if ap_limit: tasks = SelectedGrids([ 'OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiStronghold', 'OpsiMeowfficerFarming' ]) if get_os_reset_remain() > 0: delay_tasks(tasks, minutes=360) else: logger.info( 'Just less than 1 day to OpSi reset, delay 2.5 hours') delay_tasks(tasks, minutes=150) self.update()
def zones(self): """ Returns: SelectedGrids: """ return SelectedGrids([Zone(zone_id, info) for zone_id, info in DIC_OS_MAP.items()])
{ 'battle': 4, 'enemy': 1, 'mystery': 1, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ A6, B6, C6, D6, E6, F6, G6, H6, \ = MAP.flatten() step_on = SelectedGrids([C4, F4, A5, H4, F6]) road_boss = RoadGrids([B6, A6, A5, A4, B4, C4, D4, D5, E5, F5, F6, F4, G4, H4]) class Config: FLEET_BOSS = 1 MAP_MYSTERY_HAS_CARRIER = True INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 class Campaign(CampaignBase): MAP = MAP
A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ A6, B6, C6, D6, E6, F6, G6, H6, \ = MAP.flatten() # road_a1 = RoadGrids([[A2, B1], [A2, B3], [B3, A4], [A4, B3, D2, E1], [C4, B3, D2, E1]]) road_a1 = RoadGrids([[A2, B1], [A2, B3], [B3, A4], [B3, C4]])\ .combine(RoadGrids([A2, [E1, D2]])) road_c6 = RoadGrids([B6, A6, A4, [B3, C4]]) road_h1 = RoadGrids([[H2, G1], [G1, F2], [F2, E1]]) road_h5 = RoadGrids([H6, G6, [E6, F5]]) roads = [road_a1, road_c6, road_h1, road_h5] fleet_2_step_on = SelectedGrids([A4, B3, E1, F5]) class Config: INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(fleet_2_step_on, roadblocks=roads): return True
'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ = MAP.flatten() road_A1 = RoadGrids([[A2, B1], [B1, B2, B3], [A2, B2, C2], [B3, C2], D3]) road_H1 = RoadGrids([[F1, G2, H3], [F1, G2, G3], [F2, G2, H3], [F2, G3], E3]) road_MY = RoadGrids([A4, [A2, B3]]) road_middle = RoadGrids([E5, [D5, E4], D3]) \ .combine(RoadGrids([H4, H3, [F1, G2, G3], [F2, G3], E3])) step_on = SelectedGrids([D3, E3]) class Config(ConfigBase): HOMO_EDGE_HOUGHLINES_THRESHOLD = 210 class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(step_on, roadblocks=[road_middle]): return True self.clear_all_mystery()
'battle': 6, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \ A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \ A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \ A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \ A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \ A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \ A7, B7, C7, D7, E7, F7, G7, H7, I7, J7, \ A8, B8, C8, D8, E8, F8, G8, H8, I8, J8, \ = MAP.flatten() step_on = SelectedGrids([C3]) road_boss = RoadGrids([C3, H4, [C5, C7], G6, G8]) class Config: pass # INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 # COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 # INTERNAL_LINES_FIND_PEAKS_PARAMETERS = { # 'height': (150, 255 - 24), # 'width': (0.9, 10), # 'prominence': 10, # 'distance': 35, # } # EDGE_LINES_FIND_PEAKS_PARAMETERS = {
def select_grids(grids, nearby=False, is_accessible=True, scale=(), genre=(), strongest=False, weakest=False, sort=('weight', 'cost'), ignore=None): """ Args: grids (SelectedGrids): nearby (bool): is_accessible (bool): scale (tuple[int], list[int]): Tuple: select out of order, list: select in order. genre (tuple[str], list[str]): light, main, carrier, treasure. (Case insensitive). strongest (bool): weakest (bool): sort (tuple(str)): ignore (SelectedGrids): Returns: SelectedGrids: """ if nearby: grids = grids.select(is_nearby=True) if is_accessible: grids = grids.select(is_accessible=True) if ignore is not None: grids = grids.delete(grids=ignore) if len(scale): enemy = SelectedGrids([]) for enemy_scale in scale: enemy = enemy.add(grids.select(enemy_scale=enemy_scale)) if isinstance(scale, list) and enemy: break grids = enemy if len(genre): enemy = SelectedGrids([]) for enemy_genre in genre: enemy = enemy.add( grids.select(enemy_genre=enemy_genre.capitalize())) if isinstance(genre, list) and enemy: break grids = enemy if strongest: for scale in [3, 2, 1, 0]: enemy = grids.select(enemy_scale=scale) if enemy: grids = enemy break if weakest: for scale in [1, 2, 3, 0]: enemy = grids.select(enemy_scale=scale) if enemy: grids = enemy break if grids: grids = grids.sort(*sort) return grids
{ 'battle': 4, 'enemy': 1, 'mystery': 1, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ = MAP.flatten() step_on = SelectedGrids([E4, G2, C3, C4, F3]) road_boss = RoadGrids([ A1, [B1, A2], B2, [C2, B3], [B3, C3], [B4, C3], [C3, C4], [C4, D3], D4, # A1 - D4 [G3, H4], [G3, G4], G3, [F3, G4], F4,
def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): """ Delay the NextRun of all OpSi tasks. Args: recon_scan (bool): True to delay all tasks requiring recon scan 30 min. submarine_call (bool): True to delay all tasks requiring submarine call 60 min. ap_limit (bool): True to delay all tasks requiring action points 360 min. """ if not recon_scan and not submarine_call and not ap_limit: return None kv = dict_to_kv({ "recon_scan": recon_scan, "submarine_call": submarine_call, "ap_limit": ap_limit, }) def delay_tasks(task_list, minutes): next_run = datetime.now().replace(microsecond=0) + timedelta( minutes=minutes) for task in task_list: keys = f"{task}.Scheduler.NextRun" current = deep_get(self.data, keys=keys, default=DEFAULT_TIME) if current < next_run: logger.info(f"Delay task `{task}` to {next_run} ({kv})") self.modified[keys] = next_run def is_submarine_call(task): return (deep_get( self.data, keys=f"{task}.OpsiFleet.Submarine", default=False) or "submarine" in deep_get( self.data, keys=f"{task}.OpsiFleetFilter.Filter", default="").lower()) def is_force_run(task): return (deep_get( self.data, keys=f"{task}.OpsiExplore.ForceRun", default=False) or deep_get(self.data, keys=f"{task}.OpsiObscure.ForceRun", default=False) or deep_get(self.data, keys=f"{task}.OpsiAbyssal.ForceRun", default=False) or deep_get(self.data, keys=f"{task}.OpsiStronghold.ForceRun", default=False)) def is_special_radar(task): return deep_get(self.data, keys=f"{task}.OpsiExplore.SpecialRadar", default=False) if recon_scan: tasks = SelectedGrids( ["OpsiExplore", "OpsiObscure", "OpsiStronghold"]) tasks = tasks.delete(tasks.filter(is_force_run)).delete( tasks.filter(is_special_radar)) delay_tasks(tasks, minutes=27) if submarine_call: tasks = SelectedGrids([ "OpsiExplore", "OpsiDaily", "OpsiObscure", "OpsiAbyssal", "OpsiStronghold", "OpsiMeowfficerFarming", ]) tasks = tasks.filter(is_submarine_call).delete( tasks.filter(is_force_run)) delay_tasks(tasks, minutes=60) if ap_limit: tasks = SelectedGrids([ "OpsiExplore", "OpsiDaily", "OpsiObscure", "OpsiAbyssal", "OpsiStronghold", "OpsiMeowfficerFarming", ]) if get_os_reset_remain() > 0: delay_tasks(tasks, minutes=360) else: logger.info( "Just less than 1 day to OpSi reset, delay 2.5 hours") delay_tasks(tasks, minutes=150) self.update()
}, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ A6, B6, C6, D6, E6, F6, G6, H6, \ = MAP.flatten() road_a1 = RoadGrids([[A2, B1], [C3, D2]]) road_g6 = RoadGrids([F6, E5, E4]) \ .combine(RoadGrids([[G4, H5], [G4, H3]])) roads = [road_a1, road_g6] fleet_2_step_on = SelectedGrids([G4, D2, C3, E4]) road_a5 = RoadGrids([A4, A2, [C3, D2]]) \ .combine(RoadGrids([D6, E5, E4])) class Config: INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 # EDGE_LINES_HOUGHLINES_THRESHOLD = 40 COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(fleet_2_step_on, roadblocks=[road_a5]):
{ 'battle': 4, 'enemy': 1, 'mystery': 1, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ = MAP.flatten() step_on = SelectedGrids([E3, C3, G4, D2]) road_boss = RoadGrids( [C1, C2, [C3, D2], D4, E4, [E3, F4], F3, G3, H3, [G4, H4]]) road_mystery = RoadGrids([[C4, D5], D4, G2, [G1, H2]]) class Config: FLEET_BOSS = 1 MAP_MYSTERY_HAS_CARRIER = True class Campaign(CampaignBase): MAP = MAP def battle_0(self): if self.fleet_2_step_on(step_on, roadblocks=[road_boss]):
{ 'battle': 4, 'enemy': 1, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ A6, B6, C6, D6, E6, F6, G6, H6, \ = MAP.flatten() road_middle = RoadGrids([D5, F3]) step_on = SelectedGrids([D5, F3]) # There's one enemy spawn along with boss, so have to make sure there are multiple roads are cleared. # Here use separate roads instead of RoadGrids.combine(). road_H1 = RoadGrids([F3, [F1, G2, H3]]) road_A6 = RoadGrids([D5, [B5, C6]]) road_A1_left = RoadGrids([A4, A3]) road_A1_upper = RoadGrids([F1, E1, D1, C1]) road_H6_bottom = RoadGrids([D6, E6, F6]) road_H6_right = RoadGrids([[H3, G4], [G4, H4], [H4, G5]]) road_MY = RoadGrids([[B2, C1]]) class Config(ConfigBase): pass
{ 'battle': 5, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ = MAP.flatten() # Might have wrong prediction on D5 MAP.ignore_prediction(D5, enemy_scale=1, enemy_genre='Enemy') road_main = RoadGrids([B3, D3, [D5, E4], F5, G5, [G4, H5], H4, E3, F3, F2, F1]) step_on = SelectedGrids([F3, E4]) class Config: SUBMARINE = 0 INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 EDGE_LINES_HOUGHLINES_THRESHOLD = 40 COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5 HOMO_EDGE_HOUGHLINES_THRESHOLD = 210 MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' class Campaign(CampaignBase): MAP = MAP def battle_0(self):
}, { 'battle': 5, 'boss': 1 }, ] A1, B1, C1, D1, E1, F1, G1, H1, \ A2, B2, C2, D2, E2, F2, G2, H2, \ A3, B3, C3, D3, E3, F3, G3, H3, \ A4, B4, C4, D4, E4, F4, G4, H4, \ A5, B5, C5, D5, E5, F5, G5, H5, \ A6, B6, C6, D6, E6, F6, G6, H6, \ = MAP.flatten() step_on = SelectedGrids([C2, C3, D4, F3, G4]) road_boss = RoadGrids([ [A5, B6], [A4, B5, B6], C4, C5, [C3, D4], D3, # A6 - D3 [C5, D3], # D5 - D3 [B1, B2], [B1, C2], [C1, C2], [C2, D1], [C2, D2], # A2 - D3 [H3, G4], [G3, G4],
'boss': 1 }, # {'battle': 1, 'enemy': 2}, # {'battle': 2, 'enemy': 1}, # {'battle': 3, 'enemy': 1, 'mystery': 1}, # {'battle': 4, 'enemy': 1}, ] A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, \ A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, \ A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, \ A4, B4, C4, D4, E4, F4, G4, H4, I4, J4, \ A5, B5, C5, D5, E5, F5, G5, H5, I5, J5, \ A6, B6, C6, D6, E6, F6, G6, H6, I6, J6, \ = MAP.flatten() mechanism = SelectedGrids([C6, E2, G5]) class Config: # ===== Start of generated config ===== MAP_HAS_MAP_STORY = False MAP_HAS_FLEET_STEP = True MAP_HAS_AMBUSH = False MAP_HAS_LAND_BASED = True # ===== End of generated config ===== STAR_REQUIRE_1 = 0 STAR_REQUIRE_2 = 0 STAR_REQUIRE_3 = 0 MAP_IS_ONE_TIME_STAGE = True