diff --git a/campaign/campaign_main/campaign_1_1.py b/campaign/campaign_main/campaign_1_1.py index 072bfee0f..50e7f7c80 100644 --- a/campaign/campaign_main/campaign_1_1.py +++ b/campaign/campaign_main/campaign_1_1.py @@ -2,6 +2,8 @@ from module.campaign.campaign_base import CampaignBase from module.map.map_base import CampaignMap from module.map.map_grids import SelectedGrids, RoadGrids from module.logger import logger +from module.map.exception import CampaignEnd + MAP = CampaignMap() MAP.shape = 'G1' @@ -16,6 +18,7 @@ MAP.spawn_data = [ A1, B1, C1, D1, E1, F1, G1, \ = MAP.flatten() + class Config: FLEET_2 = 0 SUBMARINE = 0 @@ -25,9 +28,16 @@ class Config: 'prominence': 10, 'distance': 35, } + EDGE_LINES_FIND_PEAKS_PARAMETERS = { + 'height': (255 - 40, 255), + 'prominence': 10, + 'distance': 50, + 'wlen': 1000 + } INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 EDGE_LINES_HOUGHLINES_THRESHOLD = 40 + class Campaign(CampaignBase): MAP = MAP @@ -36,3 +46,7 @@ class Campaign(CampaignBase): def battle_1(self): return self.clear_boss() + + def handle_boss_appear_refocus(self): + self.map_swipe((-3, 0)) + return super().handle_boss_appear_refocus() diff --git a/module/base/utils.py b/module/base/utils.py index 3b51b50e9..da6fec396 100644 --- a/module/base/utils.py +++ b/module/base/utils.py @@ -43,7 +43,7 @@ def random_rectangle_point(area): """Choose a random point in an area. Args: - area (tuple): (upper_left_x, upper_left_y, bottom_right_x, bottom_right_y). + area: (upper_left_x, upper_left_y, bottom_right_x, bottom_right_y). Returns: int: x @@ -54,6 +54,44 @@ def random_rectangle_point(area): return x, y +def random_rectangle_vector(vector, box, random_range=(0, 0, 0, 0), padding=15): + """Place a vector in a box randomly. + + Args: + vector: (x, y) + box: (upper_left_x, upper_left_y, bottom_right_x, bottom_right_y). + random_range (tuple): Add a random_range to vector. (x_min, y_min, x_max, y_max). + padding (int): + + Returns: + tuple(int), tuple(int): start_point, end_point. + """ + vector = np.array(vector) + random_rectangle_point(random_range) + vector = np.round(vector).astype(np.int) + half_vector = np.round(vector / 2).astype(np.int) + box = np.array(box) + np.append(np.abs(half_vector) + padding, -np.abs(half_vector) - padding) + center = random_rectangle_point(box) + start_point = center - half_vector + end_point = start_point + vector + return tuple(start_point), tuple(end_point) + + +def random_line_segments(p1, p2, n, random_range=(0, 0, 0, 0)): + """Cut a line into multiple segments. + + Args: + p1: (x, y). + p2: (x, y). + n: Number of slice. + random_range: Add a random_range to points. + + Returns: + list[tuple]: [(x0, y0), (x1, y1), (x2, y2)] + """ + return [tuple((((n - index) * p1 + index * p2) / n).astype(int) + random_rectangle_point(random_range)) + for index in range(0, n + 1)] + + def area_offset(area, offset): """ @@ -278,9 +316,10 @@ def color_bar_percentage(image, area, prev_color, reverse=False, starter=0, thre Args: image: area: + prev_color: reverse: True if bar goes from right to left. starter: - prev_color: + threshold: Returns: float: 0 to 1. diff --git a/module/combat/combat.py b/module/combat/combat.py index d1b0ba01b..190688f81 100644 --- a/module/combat/combat.py +++ b/module/combat/combat.py @@ -1,7 +1,7 @@ import numpy as np from module.base.timer import Timer -from module.base.utils import color_bar_percentage, get_color +from module.base.utils import color_bar_percentage from module.combat.assets import * from module.combat.combat_auto import CombatAuto from module.combat.combat_manual import CombatManual @@ -79,7 +79,7 @@ class Combat(HPBalancer, UrgentCommissionHandler, EnemySearchingHandler, Retirem Returns: bool: """ - return self.appear(PAUSE) and np.mean(get_color(self.device.image, PAUSE_DOUBLE_CHECK.area)) < 153 + return self.appear(PAUSE) and np.max(self.device.image.crop(PAUSE_DOUBLE_CHECK.area)) < 153 def handle_combat_automation_confirm(self): if self.appear(AUTOMATION_CONFIRM_CHECK, interval=1): diff --git a/module/device/control.py b/module/device/control.py index 5eb05747f..d042846c5 100644 --- a/module/device/control.py +++ b/module/device/control.py @@ -106,21 +106,11 @@ class Control(Connection): duration(int, float, tuple): """ duration = ensure_time(duration) - vector = np.array(vector) + random_rectangle_point(random_range) - vector = np.round(vector).astype(np.int) - half_vector = np.round(vector / 2).astype(np.int) - box = np.array(box) + np.append(np.abs(half_vector) + padding, -np.abs(half_vector) - padding) - center = random_rectangle_point(box) - start_point = center - half_vector - end_point = start_point + vector + start, end = random_rectangle_vector(vector, box, random_range=random_range, padding=padding) logger.info( - 'Swipe %s -> %s, %s' % (self._point2str(*start_point), self._point2str(*end_point), duration) + 'Swipe %s -> %s, %s' % (self._point2str(*start), self._point2str(*end), duration) ) - fx, fy, tx, ty = np.append(start_point, end_point).tolist() - if fx < 0 or tx < 0: - logger.warning('Swipe Error. vector: %s, box: %s, center: %s, half_vector: %s' % ( - str(vector), str(box), str(center), str(half_vector) - )) + fx, fy, tx, ty = np.append(start, end).tolist() self.device.swipe(fx, fy, tx, ty, duration=duration) def drag_along(self, path): @@ -162,13 +152,29 @@ class Control(Connection): logger.info(self._point2str(x, y) + ' move') self.sleep(second) - def drag(self, p1, p2, shake=(0, 15), point_random=(-10, -10, 10, 10), shake_random=(-5, -5, 5, 5), + def drag(self, p1, p2, segments=1, shake=(0, 15), point_random=(-10, -10, 10, 10), shake_random=(-5, -5, 5, 5), swipe_duration=0.25, shake_duration=0.1): + """Drag and shake, like: + /\ + +-----------+ + + + \/ + A simple swipe or drag don't work well, because it only has two points. + Add some way point to make it more like swipe. + + Args: + p1 (tuple): Start point, (x, y). + p2 (tuple): End point, (x, y). + segments (int): + shake (tuple): Shake after arrive end point. + point_random: Add random to start point and end point. + shake_random: Add random to shake array. + swipe_duration: Duration between way points. + shake_duration: Duration between shake points. + """ p1 = np.array(p1) - random_rectangle_point(point_random) p2 = np.array(p2) - random_rectangle_point(point_random) - path = [ - (*p1, swipe_duration), - (*p2, shake_duration), + path = [(x, y, swipe_duration) for x, y in random_line_segments(p1, p2, n=segments, random_range=point_random)] + path += [ (*p2 + shake + random_rectangle_point(shake_random), shake_duration), (*p2 - shake - random_rectangle_point(shake_random), shake_duration), (*p2, shake_duration) diff --git a/module/map/grids.py b/module/map/grids.py index a3dda91c9..67118cc17 100644 --- a/module/map/grids.py +++ b/module/map/grids.py @@ -34,6 +34,10 @@ class Grids(Perspective): diff = len(self.vertical) - len(vertical) if diff > 0: logger.info(f' Grids offset: {(diff, 0)}') + if leave[0] > 0: + self.left_edge = None + if leave[-1] + 2 < len(self.vertical): + self.right_edge = None self.vertical = vertical self.grids = {} for grid in self._gen(): diff --git a/module/map/map.py b/module/map/map.py index f13d865bd..d48106170 100644 --- a/module/map/map.py +++ b/module/map/map.py @@ -61,7 +61,7 @@ class Map(Fleet): @staticmethod def select_grids(grids, nearby=False, is_accessible=True, scale=(), strongest=False, weakest=False, cost=True, - weight=False, ignore=None): + weight=True, ignore=None): """ Args: grids (SelectedGrids): diff --git a/module/map/perspective.py b/module/map/perspective.py index 1d4857706..08dedfc9e 100644 --- a/module/map/perspective.py +++ b/module/map/perspective.py @@ -256,7 +256,9 @@ class Perspective: threshold(int): Returns: - np.ndarray + np.ndarray: All correct lines.mid in DETECTING_AREA. Such as: + [ 147.52489312 276.64750191 405.77011071 534.89271951 664.0153283 + 793.1379371 922.2605459 1051.38315469 1180.50576349 1309.62837229] """ right_distant_point = (self.vanish_point[0] * 2 - self.distant_point[0], self.distant_point[1]) @@ -343,7 +345,9 @@ class Perspective: # Cleansing edge edge = edge.mid inner = inner.mid - edge = edge[(edge > np.max(inner) - threshold) | (edge < np.min(inner) + threshold)] + inner_clean = [l for l in inner if np.any(np.abs(l - clean) < 5)] # Use correct inner to delete wrong edge. + if len(inner_clean) > 0: + edge = edge[(edge > np.max(inner_clean) - threshold) | (edge < np.min(inner_clean) + threshold)] edge = [c for c in clean if np.any(np.abs(c - edge) < 5)] # Separate edges diff --git a/module/reward/commission.py b/module/reward/commission.py index 3a6be626b..ef728d084 100644 --- a/module/reward/commission.py +++ b/module/reward/commission.py @@ -7,7 +7,7 @@ from scipy import signal from module.base.ocr import Ocr from module.base.timer import Timer -from module.base.utils import area_offset, get_color +from module.base.utils import area_offset, get_color, random_rectangle_vector from module.handler.info_bar import InfoBarHandler from module.logger import logger from module.reward.assets import * @@ -309,10 +309,10 @@ class RewardCommission(UI, InfoBarHandler): return True - def _commission_swipe(self, distance=180): + def _commission_swipe(self, distance=300): # Distance of two commission is 146px - self.device.swipe((0, -distance), box=(620, 67, 1154, 692), random_range=(-20, -5, 20, 5)) - self.device.click(COMMISSION_STOP_SCROLLING) + p1, p2 = random_rectangle_vector((0, -distance), box=(620, 67, 1154, 692), random_range=(-20, -5, 20, 5)) + self.device.drag(p1, p2, segments=2, shake=(25, 0), point_random=(0, 0, 0, 0), shake_random=(-5, 0, 5, 0)) self.device.sleep(0.3) self.device.screenshot() diff --git a/module/reward/reward.py b/module/reward/reward.py index c4e6c0739..108c84449 100644 --- a/module/reward/reward.py +++ b/module/reward/reward.py @@ -85,6 +85,10 @@ class Reward(RewardCommission): reward = True continue + if not self.appear(page_reward.check_button): + exit_timer.reset() + continue + # End if exit_timer.reached(): break