diff --git a/assets/template/TEMPLATE_ENEMY_CARRIER.png b/assets/template/TEMPLATE_ENEMY_CARRIER.png new file mode 100644 index 000000000..126c7ab11 Binary files /dev/null and b/assets/template/TEMPLATE_ENEMY_CARRIER.png differ diff --git a/assets/template/TEMPLATE_ENEMY_LIGHT.png b/assets/template/TEMPLATE_ENEMY_LIGHT.png new file mode 100644 index 000000000..92d98f961 Binary files /dev/null and b/assets/template/TEMPLATE_ENEMY_LIGHT.png differ diff --git a/assets/template/TEMPLATE_ENEMY_MAIN.png b/assets/template/TEMPLATE_ENEMY_MAIN.png new file mode 100644 index 000000000..2f169a782 Binary files /dev/null and b/assets/template/TEMPLATE_ENEMY_MAIN.png differ diff --git a/assets/template/TEMPLATE_ENEMY_TREASURE.png b/assets/template/TEMPLATE_ENEMY_TREASURE.png new file mode 100644 index 000000000..b8bf91b08 Binary files /dev/null and b/assets/template/TEMPLATE_ENEMY_TREASURE.png differ diff --git a/assets/template/TEMPLATE_SIREN_1.png b/assets/template/TEMPLATE_SIREN_1.png new file mode 100644 index 000000000..63c1ebbba Binary files /dev/null and b/assets/template/TEMPLATE_SIREN_1.png differ diff --git a/assets/template/TEMPLATE_SIREN_2.png b/assets/template/TEMPLATE_SIREN_2.png new file mode 100644 index 000000000..c5ac71a31 Binary files /dev/null and b/assets/template/TEMPLATE_SIREN_2.png differ diff --git a/assets/template/TEMPLATE_SIREN_3.png b/assets/template/TEMPLATE_SIREN_3.png new file mode 100644 index 000000000..b1169b640 Binary files /dev/null and b/assets/template/TEMPLATE_SIREN_3.png differ diff --git a/campaign/event_20200521_cn/a1.py b/campaign/event_20200521_cn/a1.py index 725651382..7bd6acbe1 100644 --- a/campaign/event_20200521_cn/a1.py +++ b/campaign/event_20200521_cn/a1.py @@ -24,7 +24,7 @@ class Config: MAP_HAS_FLEET_STEP = True MAP_HAS_MOVABLE_ENEMY = True MAP_HAS_SIREN = True - MAP_HAS_DYNAMIC_RED_BORDER = True + MAP_HAS_DYNAMIC_RED_BORDER = False MAP_HAS_MAP_STORY = True MAP_SIREN_COUNT = 2 diff --git a/campaign/event_20200521_cn/c1.py b/campaign/event_20200521_cn/c1.py index 725651382..7bd6acbe1 100644 --- a/campaign/event_20200521_cn/c1.py +++ b/campaign/event_20200521_cn/c1.py @@ -24,7 +24,7 @@ class Config: MAP_HAS_FLEET_STEP = True MAP_HAS_MOVABLE_ENEMY = True MAP_HAS_SIREN = True - MAP_HAS_DYNAMIC_RED_BORDER = True + MAP_HAS_DYNAMIC_RED_BORDER = False MAP_HAS_MAP_STORY = True MAP_SIREN_COUNT = 2 diff --git a/module/map/grid.py b/module/map/grid.py index 41919a317..d9f91c7da 100644 --- a/module/map/grid.py +++ b/module/map/grid.py @@ -6,7 +6,7 @@ from module.map.grid_predictor import GridPredictor class Grid(GridPredictor, GridInfo): - def __init__(self, location, image, corner): + def __init__(self, location, image, corner, config): """ Args: @@ -18,7 +18,7 @@ class Grid(GridPredictor, GridInfo): (x2, y2) +-------------+ (x3, y3) """ self.location = location - super().__init__(location, image, corner) + super().__init__(location, image, corner, config) self.corner = corner.flatten() @property diff --git a/module/map/grid_info.py b/module/map/grid_info.py index 8b193ee77..970cb3d02 100644 --- a/module/map/grid_info.py +++ b/module/map/grid_info.py @@ -43,7 +43,7 @@ class GridInfo: is_siren = False # SI enemy_scale = 0 - enemy_type = 'Enemy' # Light, Main, Carrier, Treasure, Enemy(unknown) + enemy_type = None # Light, Main, Carrier, Treasure, Enemy(unknown) is_cleared = False is_ambush_save = False @@ -76,16 +76,15 @@ class GridInfo: dic = { '++': 'is_land', 'BO': 'is_boss', - 'SI': 'is_siren' } for key, value in dic.items(): if self.__getattribute__(value): return key + if self.is_siren: + return ''.join([text[0] for text in self.enemy_type.split('_')]).upper() + if self.is_enemy: - # if self.may_siren: - # return 'SI' - # else: return '%s%s' % (self.enemy_scale, self.enemy_type[0].upper()) dic = { @@ -143,6 +142,7 @@ class GridInfo: flag &= not self.is_cleared if flag: self.__setattr__('is_' + item, True) + self.enemy_type = info.enemy_type return True else: logger.info(f'Wrong Prediction. Grid: {self}, Attr: is_{item}') @@ -184,7 +184,7 @@ class GridInfo: """ self.is_enemy = False self.enemy_scale = 0 - self.enemy_type = 'Enemy' + self.enemy_type = None self.is_mystery = False self.is_boss = False self.is_ammo = False diff --git a/module/map/grid_predictor.py b/module/map/grid_predictor.py index f1d74ba0f..a1a1067cc 100644 --- a/module/map/grid_predictor.py +++ b/module/map/grid_predictor.py @@ -3,6 +3,7 @@ from PIL import Image from skimage.color import rgb2hsv from module.base.utils import color_similarity_2d +from module.config.config import AzurLaneConfig from module.template.assets import * @@ -10,14 +11,25 @@ class GridPredictor: ENEMY_SCALE_IMAGE_SIZE = (50, 50) ENEMY_PERSPECTIVE_IMAGE_SIZE = (50, 50) RED_BORDER_IGNORE_TOP = 10 + DIC_ENEMY_TYPE = { + 'Siren_1': TEMPLATE_SIREN_1, + 'Siren_2': TEMPLATE_SIREN_2, + 'Siren_3': TEMPLATE_SIREN_3, + 'Light': TEMPLATE_ENEMY_LIGHT, + 'Main': TEMPLATE_ENEMY_MAIN, + 'Carrier': TEMPLATE_ENEMY_CARRIER, + 'Treasure': TEMPLATE_ENEMY_TREASURE, + } - def __init__(self, location, image, corner): + def __init__(self, location, image, corner, config): """ Args: location: image: corner: + config (AzurLaneConfig) """ + self.config = config self.location = location self.image = image self.corner = corner.flatten() @@ -41,20 +53,35 @@ class GridPredictor: def predict(self): self.image_transform = self.image.transform(self.ENEMY_PERSPECTIVE_IMAGE_SIZE, Image.PERSPECTIVE, self._perspective) - # self.image_hole = self.get_relative_image((-1, -1, 1, 1)) - self.is_enemy = self.predict_static_red_border() self.enemy_scale = self.predict_enemy_scale() - if self.enemy_scale > 0: - self.is_enemy = True + self.enemy_type = self.predict_enemy_type() + self.is_mystery = self.predict_mystery() - if not self.is_enemy and not self.is_mystery: - self.is_siren = self.predict_dynamic_red_border() self.is_fleet = self.predict_fleet() if self.is_fleet: self.is_current_fleet = self.predict_current_fleet() self.is_boss = self.predict_boss() - # self.caught_by_siren = self.predict_siren_caught() + + if self.config.MAP_HAS_DYNAMIC_RED_BORDER: + if not self.is_enemy and not self.is_mystery: + if self.predict_dynamic_red_border(): + self.enemy_type = 'Siren_unknown' + # self.caught_by_siren = self.predict_siren_caught() + + if self.enemy_type: + self.is_enemy = True + if self.enemy_scale: + self.is_enemy = True + if not self.is_enemy: + self.is_enemy = self.predict_static_red_border() + if self.is_enemy and not self.enemy_type: + self.enemy_type = 'Enemy' + if self.config.MAP_HAS_SIREN: + if self.enemy_type is not None and self.enemy_type.startswith('Siren'): + self.is_siren = True + self.enemy_scale = 0 + # self.image_perspective = color_similarity_2d( # self.image.transform(self.ENEMY_PERSPECTIVE_IMAGE_SIZE, Image.PERSPECTIVE, self._perspective) # , color=(255, 36, 82) @@ -224,3 +251,14 @@ class GridPredictor: def predict_siren_caught(self): image = self.get_relative_image((-1, -1.5, 1, 0.5), output_shape=(120, 120)) return TEMPLATE_CAUGHT_BY_SIREN.match(image, similarity=0.6) + + def predict_enemy_type(self): + image = self.get_relative_image((-1, -1, 1, 0), output_shape=(120, 60)) + for name, template in self.DIC_ENEMY_TYPE.items(): + if not self.config.MAP_HAS_SIREN and name.startswith('Siren'): + continue + if template.match(image): + return name + + return None + diff --git a/module/map/grids.py b/module/map/grids.py index 0520acefd..a308e8402 100644 --- a/module/map/grids.py +++ b/module/map/grids.py @@ -82,7 +82,7 @@ class Grids(Perspective): area = np.append(cross[0], cross[3]) if area_in_area(area, self.config.DETECTING_AREA): - grid = Grid(location=(x, y), image=self.image, corner=cross.points) + grid = Grid(location=(x, y), image=self.image, corner=cross.points, config=self.config) yield grid def show(self): @@ -93,9 +93,6 @@ class Grids(Perspective): def predict(self): for grid in self: grid.predict() - if not self.config.MAP_HAS_DYNAMIC_RED_BORDER: - for grid in self: - grid.is_siren = False # for grid in self: # if grid.is_enemy and grid.enemy_scale == 0: diff --git a/module/template/assets.py b/module/template/assets.py index 243c4a017..3a3d67475 100644 --- a/module/template/assets.py +++ b/module/template/assets.py @@ -8,13 +8,20 @@ TEMPLATE_AMBUSH_EVADE_FAILED = Template(file='./assets/template/TEMPLATE_AMBUSH_ TEMPLATE_AMBUSH_EVADE_SUCCESS = Template(file='./assets/template/TEMPLATE_AMBUSH_EVADE_SUCCESS.png') TEMPLATE_CAUGHT_BY_SIREN = Template(file='./assets/template/TEMPLATE_CAUGHT_BY_SIREN.png') TEMPLATE_ENEMY_BOSS = Template(file='./assets/template/TEMPLATE_ENEMY_BOSS.png') +TEMPLATE_ENEMY_CARRIER = Template(file='./assets/template/TEMPLATE_ENEMY_CARRIER.png') TEMPLATE_ENEMY_L = Template(file='./assets/template/TEMPLATE_ENEMY_L.png') +TEMPLATE_ENEMY_LIGHT = Template(file='./assets/template/TEMPLATE_ENEMY_LIGHT.png') TEMPLATE_ENEMY_M = Template(file='./assets/template/TEMPLATE_ENEMY_M.png') +TEMPLATE_ENEMY_MAIN = Template(file='./assets/template/TEMPLATE_ENEMY_MAIN.png') TEMPLATE_ENEMY_S = Template(file='./assets/template/TEMPLATE_ENEMY_S.png') +TEMPLATE_ENEMY_TREASURE = Template(file='./assets/template/TEMPLATE_ENEMY_TREASURE.png') TEMPLATE_FLEET_AMMO = Template(file='./assets/template/TEMPLATE_FLEET_AMMO.png') TEMPLATE_FORMATION_1 = Template(file='./assets/template/TEMPLATE_FORMATION_1.png') TEMPLATE_FORMATION_2 = Template(file='./assets/template/TEMPLATE_FORMATION_2.png') TEMPLATE_FORMATION_3 = Template(file='./assets/template/TEMPLATE_FORMATION_3.png') TEMPLATE_MAP_WALK_OUT_OF_STEP = Template(file='./assets/template/TEMPLATE_MAP_WALK_OUT_OF_STEP.png') +TEMPLATE_SIREN_1 = Template(file='./assets/template/TEMPLATE_SIREN_1.png') +TEMPLATE_SIREN_2 = Template(file='./assets/template/TEMPLATE_SIREN_2.png') +TEMPLATE_SIREN_3 = Template(file='./assets/template/TEMPLATE_SIREN_3.png') TEMPLATE_STAGE_CLEAR = Template(file='./assets/template/TEMPLATE_STAGE_CLEAR.png') TEMPLATE_STAGE_PERCENT = Template(file='./assets/template/TEMPLATE_STAGE_PERCENT.png')