mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-23 09:01:45 +00:00
Merge pull request #3 from LmeSzinc/master
Add: Map logic fleet_2_push_forward, better support 7-1
This commit is contained in:
commit
1244f9a6f1
@ -6,19 +6,33 @@ from module.logger import logger
|
|||||||
|
|
||||||
MAP = CampaignMap()
|
MAP = CampaignMap()
|
||||||
MAP.map_data = '''
|
MAP.map_data = '''
|
||||||
-- -- -- -- -- -- ++ ++
|
-- ME ME MM ME -- ++ ++
|
||||||
-- -- ++ ++ -- -- ++ ++
|
SP ME ++ ++ ME ME ++ ++
|
||||||
-- -- ++ ++ -- -- -- --
|
SP -- ++ ++ -- ME ME MB
|
||||||
'''
|
'''
|
||||||
MAP.camera_data = ['D2', 'E2']
|
MAP.camera_data = ['C1', 'E1']
|
||||||
|
MAP.weight_data = '''
|
||||||
|
40 30 21 20 17 15 50 50
|
||||||
|
40 40 50 50 16 13 50 50
|
||||||
|
40 40 50 50 14 12 11 10
|
||||||
|
'''
|
||||||
|
MAP.spawn_data = [
|
||||||
|
{'battle': 0, 'enemy': 3},
|
||||||
|
{'battle': 1, 'enemy': 2},
|
||||||
|
{'battle': 2, 'enemy': 2},
|
||||||
|
{'battle': 3, 'enemy': 1, 'mystery': 1},
|
||||||
|
{'battle': 4},
|
||||||
|
{'battle': 5, 'boss': 1},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
SUBMARINE = 0
|
SUBMARINE = 0
|
||||||
POOR_MAP_DATA = True
|
FLEET_BOSS = 2
|
||||||
|
|
||||||
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 30
|
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40
|
||||||
EDGE_LINES_HOUGHLINES_THRESHOLD = 30
|
EDGE_LINES_HOUGHLINES_THRESHOLD = 40
|
||||||
|
COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1.5
|
||||||
MID_DIFF_RANGE_H = (140 - 3, 140 + 3)
|
MID_DIFF_RANGE_H = (140 - 3, 140 + 3)
|
||||||
MID_DIFF_RANGE_V = (143 - 3, 143 + 3)
|
MID_DIFF_RANGE_V = (143 - 3, 143 + 3)
|
||||||
|
|
||||||
@ -39,3 +53,22 @@ class Config:
|
|||||||
|
|
||||||
class Campaign(CampaignBase):
|
class Campaign(CampaignBase):
|
||||||
MAP = MAP
|
MAP = MAP
|
||||||
|
MAP_AMBUSH_OVERLAY_TRANSPARENCY_THRESHOLD = 0.45
|
||||||
|
MAP_AIR_RAID_OVERLAY_TRANSPARENCY_THRESHOLD = 0.45
|
||||||
|
|
||||||
|
def battle_0(self):
|
||||||
|
self.clear_all_mystery()
|
||||||
|
self.fleet_2_push_forward()
|
||||||
|
|
||||||
|
return self.battle_default()
|
||||||
|
|
||||||
|
def battle_5(self):
|
||||||
|
self.clear_all_mystery()
|
||||||
|
|
||||||
|
return self.fleet_2.brute_clear_boss()
|
||||||
|
|
||||||
|
def handle_boss_appear_refocus(self):
|
||||||
|
for data in self.map.spawn_data:
|
||||||
|
if data.get('battle') == self.battle_count and data.get('boss', 0):
|
||||||
|
self.map_swipe((-3, -2))
|
||||||
|
return super().handle_boss_appear_refocus()
|
||||||
|
@ -7,9 +7,7 @@ from module.base.utils import extract_letters, area_offset
|
|||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.template.assets import TEMPLATE_STAGE_CLEAR, TEMPLATE_STAGE_PERCENT, Button
|
from module.template.assets import TEMPLATE_STAGE_CLEAR, TEMPLATE_STAGE_PERCENT, Button
|
||||||
from module.exception import CampaignNameError
|
from module.exception import CampaignNameError
|
||||||
|
from module.base.decorator import Config
|
||||||
stage_clear_color = tuple(np.mean(np.mean(TEMPLATE_STAGE_CLEAR.image, axis=0), axis=0))
|
|
||||||
stage_percentage_color = tuple(np.mean(np.mean(TEMPLATE_STAGE_PERCENT.image, axis=0), axis=0))
|
|
||||||
|
|
||||||
|
|
||||||
def ensure_chapter_index(name):
|
def ensure_chapter_index(name):
|
||||||
@ -33,6 +31,8 @@ def ensure_chapter_index(name):
|
|||||||
|
|
||||||
def ocr_result_process(result):
|
def ocr_result_process(result):
|
||||||
result = result.lower().replace('--', '-')
|
result = result.lower().replace('--', '-')
|
||||||
|
if result.startswith('-'):
|
||||||
|
result = result[1:]
|
||||||
if len(result) == 2 and result[0].isdigit():
|
if len(result) == 2 and result[0].isdigit():
|
||||||
result = '-'.join(result)
|
result = '-'.join(result)
|
||||||
return result
|
return result
|
||||||
@ -58,41 +58,55 @@ def separate_name(name):
|
|||||||
|
|
||||||
|
|
||||||
class CampaignOcr:
|
class CampaignOcr:
|
||||||
stage = {}
|
stage_entrance = {}
|
||||||
chapter = 0
|
campaign_chapter = 0
|
||||||
|
|
||||||
def extract_campaign_name_image(self, image):
|
def campaign_match_multi(self, template, image, name_offset=(75, 9), name_size=(60, 16),
|
||||||
result = TEMPLATE_STAGE_CLEAR.match_multi(image, similarity=0.95)
|
name_letter=(255, 255, 255), name_back=(102, 102, 102)):
|
||||||
# np.sort(result.flatten())[-10:]
|
"""
|
||||||
# array([0.8680386 , 0.8688129 , 0.8693155 , 0.86967576, 0.87012905,
|
Args:
|
||||||
# 0.8705039 , 0.99954903, 0.99983317, 0.99996626, 1. ],
|
template (Template):
|
||||||
# dtype=float32)
|
image: Screenshot
|
||||||
|
name_offset (tuple[int]):
|
||||||
|
name_size (tuple[int]):
|
||||||
|
name_letter (tuple[int]):
|
||||||
|
name_back (tuple[int]):
|
||||||
|
|
||||||
name_offset = (75, 9)
|
Returns:
|
||||||
name_size = (60, 16)
|
list[Button]: Stage clear buttons.
|
||||||
name_letter = (255, 255, 255)
|
"""
|
||||||
name_back = (102, 102, 102)
|
|
||||||
digits = []
|
digits = []
|
||||||
for point in result:
|
color = tuple(np.mean(np.mean(template.image, axis=0), axis=0))
|
||||||
point = point[::-1]
|
result = template.match_multi(image, similarity=0.95)
|
||||||
button = tuple(np.append(point, point + TEMPLATE_STAGE_CLEAR.image.shape[:2][::-1]))
|
|
||||||
point = point + name_offset
|
|
||||||
name = image.crop(np.append(point, point + name_size))
|
|
||||||
name = extract_letters(name, letter=name_letter, back=name_back)
|
|
||||||
stage = self.extract_stage_name(name)
|
|
||||||
digits.append(Button(area=area_offset(stage, point), color=stage_clear_color, button=button, name='stage'))
|
|
||||||
|
|
||||||
result = TEMPLATE_STAGE_PERCENT.match_multi(image, similarity=0.95)
|
|
||||||
name_offset = (48, 0)
|
|
||||||
for point in result:
|
for point in result:
|
||||||
point = point[::-1]
|
point = point[::-1]
|
||||||
button = tuple(np.append(point, point + TEMPLATE_STAGE_PERCENT.image.shape[:2][::-1]))
|
button = tuple(np.append(point, point + template.image.shape[:2][::-1]))
|
||||||
point = point + name_offset
|
point = point + name_offset
|
||||||
name = image.crop(np.append(point, point + name_size))
|
name = image.crop(np.append(point, point + name_size))
|
||||||
name = extract_letters(name, letter=name_letter, back=name_back)
|
name = extract_letters(name, letter=name_letter, back=name_back)
|
||||||
stage = self.extract_stage_name(name)
|
stage = self._extract_stage_name(name)
|
||||||
digits.append(
|
digits.append(
|
||||||
Button(area=area_offset(stage, point), color=stage_percentage_color, button=button, name='stage'))
|
Button(area=area_offset(stage, point), color=color, button=button, name='stage'))
|
||||||
|
|
||||||
|
return digits
|
||||||
|
|
||||||
|
@Config.when(SERVER='en')
|
||||||
|
def campaign_extract_name_image(self, image):
|
||||||
|
digits = []
|
||||||
|
digits += self.campaign_match_multi(TEMPLATE_STAGE_CLEAR, image, name_offset=(70, 12), name_size=(60, 14))
|
||||||
|
digits += self.campaign_match_multi(TEMPLATE_STAGE_PERCENT, image, name_offset=(45, 3), name_size=(60, 14))
|
||||||
|
|
||||||
|
if len(digits) == 0:
|
||||||
|
logger.warning('No stage found.')
|
||||||
|
|
||||||
|
return digits
|
||||||
|
|
||||||
|
@Config.when(SERVER=None)
|
||||||
|
def campaign_extract_name_image(self, image):
|
||||||
|
digits = []
|
||||||
|
digits += self.campaign_match_multi(TEMPLATE_STAGE_CLEAR, image, name_offset=(75, 9), name_size=(60, 16))
|
||||||
|
digits += self.campaign_match_multi(TEMPLATE_STAGE_PERCENT, image, name_offset=(48, 0), name_size=(60, 16))
|
||||||
|
|
||||||
if len(digits) == 0:
|
if len(digits) == 0:
|
||||||
logger.warning('No stage found.')
|
logger.warning('No stage found.')
|
||||||
@ -100,7 +114,7 @@ class CampaignOcr:
|
|||||||
return digits
|
return digits
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def extract_stage_name(image):
|
def _extract_stage_name(image):
|
||||||
x_skip = 10
|
x_skip = 10
|
||||||
interval = 5
|
interval = 5
|
||||||
x_color = np.convolve(np.mean(image, axis=0), np.ones(interval), 'valid') / interval
|
x_color = np.convolve(np.mean(image, axis=0), np.ones(interval), 'valid') / interval
|
||||||
@ -111,7 +125,7 @@ class CampaignOcr:
|
|||||||
return 0, 0, x_list[0] + 1 + x_skip, image.shape[0]
|
return 0, 0, x_list[0] + 1 + x_skip, image.shape[0]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def name_separate(image):
|
def _name_separate(image):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
image (np.ndarray): (height, width)
|
image (np.ndarray): (height, width)
|
||||||
@ -144,9 +158,9 @@ class CampaignOcr:
|
|||||||
|
|
||||||
return chapter, stage
|
return chapter, stage
|
||||||
|
|
||||||
def get_stage_name(self, image):
|
def _get_stage_name(self, image):
|
||||||
self.stage = {}
|
self.stage_entrance = {}
|
||||||
buttons = self.extract_campaign_name_image(image)
|
buttons = self.campaign_extract_name_image(image)
|
||||||
|
|
||||||
ocr = Ocr(buttons, lang='stage', letter=(255, 255, 255), back=(102, 102, 102), threshold=180)
|
ocr = Ocr(buttons, lang='stage', letter=(255, 255, 255), back=(102, 102, 102), threshold=180)
|
||||||
result = ocr.ocr(image)
|
result = ocr.ocr(image)
|
||||||
@ -156,23 +170,23 @@ class CampaignOcr:
|
|||||||
|
|
||||||
chapter = [separate_name(res)[0] for res in result]
|
chapter = [separate_name(res)[0] for res in result]
|
||||||
counter = collections.Counter(chapter)
|
counter = collections.Counter(chapter)
|
||||||
self.chapter = counter.most_common()[0][0]
|
self.campaign_chapter = counter.most_common()[0][0]
|
||||||
|
|
||||||
for name, button in zip(result, buttons):
|
for name, button in zip(result, buttons):
|
||||||
button.area = button.button
|
button.area = button.button
|
||||||
button.name = name
|
button.name = name
|
||||||
self.stage[name] = button
|
self.stage_entrance[name] = button
|
||||||
|
|
||||||
logger.attr('Chapter', self.chapter)
|
logger.attr('Chapter', self.campaign_chapter)
|
||||||
logger.attr('Stage', ', '.join(self.stage.keys()))
|
logger.attr('Stage', ', '.join(self.stage_entrance.keys()))
|
||||||
|
|
||||||
def get_chapter_index(self, image):
|
def get_chapter_index(self, image):
|
||||||
"""
|
"""
|
||||||
A tricky method for ui_ensure_index
|
A tricky method for ui_ensure_index
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.get_stage_name(image)
|
self._get_stage_name(image)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise CampaignNameError
|
raise CampaignNameError
|
||||||
|
|
||||||
return ensure_chapter_index(self.chapter)
|
return ensure_chapter_index(self.campaign_chapter)
|
||||||
|
@ -10,9 +10,7 @@ from module.exception import CampaignNameError
|
|||||||
STAGE_SHOWN_WAIT = (1, 1.2)
|
STAGE_SHOWN_WAIT = (1, 1.2)
|
||||||
|
|
||||||
|
|
||||||
class CampaignUI(UI):
|
class CampaignUI(UI, CampaignOcr):
|
||||||
campaign_ocr = CampaignOcr()
|
|
||||||
|
|
||||||
def campaign_ensure_chapter(self, index):
|
def campaign_ensure_chapter(self, index):
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
@ -21,7 +19,7 @@ class CampaignUI(UI):
|
|||||||
index = ensure_chapter_index(index)
|
index = ensure_chapter_index(index)
|
||||||
|
|
||||||
# A tricky way to use ui_ensure_index.
|
# A tricky way to use ui_ensure_index.
|
||||||
self.ui_ensure_index(index, letter=self.campaign_ocr.get_chapter_index,
|
self.ui_ensure_index(index, letter=self.get_chapter_index,
|
||||||
prev_button=CHAPTER_PREV, next_button=CHAPTER_NEXT,
|
prev_button=CHAPTER_PREV, next_button=CHAPTER_NEXT,
|
||||||
fast=True, skip_first_screenshot=True, step_sleep=STAGE_SHOWN_WAIT, finish_sleep=0)
|
fast=True, skip_first_screenshot=True, step_sleep=STAGE_SHOWN_WAIT, finish_sleep=0)
|
||||||
|
|
||||||
@ -65,10 +63,10 @@ class CampaignUI(UI):
|
|||||||
Returns:
|
Returns:
|
||||||
Button:
|
Button:
|
||||||
"""
|
"""
|
||||||
if name not in self.campaign_ocr.stage:
|
if name not in self.stage_entrance:
|
||||||
logger.warning(f'Stage not found: {name}')
|
logger.warning(f'Stage not found: {name}')
|
||||||
raise CampaignNameError
|
raise CampaignNameError
|
||||||
return self.campaign_ocr.stage[name]
|
return self.stage_entrance[name]
|
||||||
|
|
||||||
def ensure_campaign_ui(self, name, mode='normal'):
|
def ensure_campaign_ui(self, name, mode='normal'):
|
||||||
"""
|
"""
|
||||||
|
@ -219,12 +219,20 @@ class Fleet(Camera, MapOperation, AmbushHandler):
|
|||||||
else:
|
else:
|
||||||
self._goto(location, expected=expected)
|
self._goto(location, expected=expected)
|
||||||
|
|
||||||
def find_path_initial(self):
|
def find_path_initial(self, grid=None):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
grid (tuple, GridInfo): Current fleet grid
|
||||||
|
"""
|
||||||
|
if grid is None:
|
||||||
|
grid = self.fleet_current
|
||||||
|
else:
|
||||||
|
grid = location_ensure(grid)
|
||||||
if self.fleet_1_location:
|
if self.fleet_1_location:
|
||||||
self.map[self.fleet_1_location].is_fleet = True
|
self.map[self.fleet_1_location].is_fleet = True
|
||||||
if self.fleet_2_location:
|
if self.fleet_2_location:
|
||||||
self.map[self.fleet_2_location].is_fleet = True
|
self.map[self.fleet_2_location].is_fleet = True
|
||||||
self.map.find_path_initial(self.fleet_current, has_ambush=self.config.MAP_HAS_AMBUSH)
|
self.map.find_path_initial(grid, has_ambush=self.config.MAP_HAS_AMBUSH)
|
||||||
|
|
||||||
def show_fleet(self):
|
def show_fleet(self):
|
||||||
fleets = []
|
fleets = []
|
||||||
@ -280,6 +288,15 @@ class Fleet(Camera, MapOperation, AmbushHandler):
|
|||||||
logger.info('Fleet_2 not detected.')
|
logger.info('Fleet_2 not detected.')
|
||||||
if self.config.POOR_MAP_DATA and not self.map.select(is_spawn_point=True):
|
if self.config.POOR_MAP_DATA and not self.map.select(is_spawn_point=True):
|
||||||
self.fleet_1 = fleets[0].location
|
self.fleet_1 = fleets[0].location
|
||||||
|
elif self.map.select(is_spawn_point=True).count == 2:
|
||||||
|
logger.info('Predict fleet to be spawn point')
|
||||||
|
another = self.map.select(is_spawn_point=True).delete(SelectedGrids([fleets[0]]))[0]
|
||||||
|
if fleets[0].is_current_fleet:
|
||||||
|
self.fleet_1 = fleets[0].location
|
||||||
|
self.fleet_2 = another.location
|
||||||
|
else:
|
||||||
|
self.fleet_1 = another.location
|
||||||
|
self.fleet_2 = fleets[0].location
|
||||||
else:
|
else:
|
||||||
self.find_all_fleets()
|
self.find_all_fleets()
|
||||||
elif count == 2:
|
elif count == 2:
|
||||||
|
@ -6,8 +6,8 @@ class GridInfo:
|
|||||||
"""
|
"""
|
||||||
Class that gather basic information of a grid in map_v1.
|
Class that gather basic information of a grid in map_v1.
|
||||||
|
|
||||||
Visit 碧蓝航线WIKI(Chinese Simplified) http://wiki.joyme.com/blhx, to get basic info of a map_v1. For example,
|
Visit 碧蓝航线WIKI(Chinese Simplified) http://wiki.biligame.com/blhx, to get basic info of a map_v1. For example,
|
||||||
visit http://wiki.joyme.com/blhx/7-2, to know more about campaign 7-2, which includes boss point, enemy spawn point.
|
visit http://wiki.biligame.com/blhx/7-2, to know more about campaign 7-2, which includes boss point, enemy spawn point.
|
||||||
|
|
||||||
A grid contains these unchangeable properties which can known from WIKI.
|
A grid contains these unchangeable properties which can known from WIKI.
|
||||||
| print_name | property_name | description |
|
| print_name | property_name | description |
|
||||||
|
@ -68,7 +68,6 @@ class GridPredictor:
|
|||||||
if not self.is_enemy and not self.is_mystery:
|
if not self.is_enemy and not self.is_mystery:
|
||||||
if self.predict_dynamic_red_border():
|
if self.predict_dynamic_red_border():
|
||||||
self.enemy_genre = 'Siren_unknown'
|
self.enemy_genre = 'Siren_unknown'
|
||||||
if self.config.MAP_HAS_MOVABLE_ENEMY:
|
|
||||||
self.is_caught_by_siren = self.predict_siren_caught()
|
self.is_caught_by_siren = self.predict_siren_caught()
|
||||||
|
|
||||||
if self.enemy_genre:
|
if self.enemy_genre:
|
||||||
|
@ -230,7 +230,8 @@ class Map(Fleet):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def clear_boss(self):
|
def clear_boss(self):
|
||||||
"""Clear BOSS.
|
"""This method is deprecated, although it works well in simple map.
|
||||||
|
In a complex map, brute_clear_boss is recommended.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool:
|
bool:
|
||||||
@ -292,6 +293,10 @@ class Map(Fleet):
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return self.fleet_boss.clear_boss()
|
return self.fleet_boss.clear_boss()
|
||||||
|
elif self.map.select(may_boss=True, is_caught_by_siren=True):
|
||||||
|
logger.info('BOSS appear on fleet grid')
|
||||||
|
self.fleet_2.switch_to()
|
||||||
|
self.clear_chosen_enemy(self.map.select(may_boss=True, is_caught_by_siren=True)[0])
|
||||||
else:
|
else:
|
||||||
logger.warning('BOSS not detected, trying all boss spawn point.')
|
logger.warning('BOSS not detected, trying all boss spawn point.')
|
||||||
return self.clear_potential_boss()
|
return self.clear_potential_boss()
|
||||||
@ -356,6 +361,8 @@ class Map(Fleet):
|
|||||||
Returns:
|
Returns:
|
||||||
bool: if clear an enemy.
|
bool: if clear an enemy.
|
||||||
"""
|
"""
|
||||||
|
if not self.config.FLEET_2:
|
||||||
|
return False
|
||||||
for grid in grids:
|
for grid in grids:
|
||||||
if self.fleet_at(grid=grid, fleet=2):
|
if self.fleet_at(grid=grid, fleet=2):
|
||||||
return False
|
return False
|
||||||
@ -376,6 +383,8 @@ class Map(Fleet):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def fleet_2_break_siren_caught(self):
|
def fleet_2_break_siren_caught(self):
|
||||||
|
if not self.config.FLEET_2:
|
||||||
|
return False
|
||||||
if not self.config.MAP_HAS_SIREN or not self.config.MAP_HAS_MOVABLE_ENEMY:
|
if not self.config.MAP_HAS_SIREN or not self.config.MAP_HAS_MOVABLE_ENEMY:
|
||||||
return False
|
return False
|
||||||
if not self.map.select(is_caught_by_siren=True):
|
if not self.map.select(is_caught_by_siren=True):
|
||||||
@ -395,3 +404,41 @@ class Map(Fleet):
|
|||||||
for grid in self.map:
|
for grid in self.map:
|
||||||
grid.is_caught_by_siren = False
|
grid.is_caught_by_siren = False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user