Fix: 修复一些bug

- 修复了删除空列时, 边缘仍然存在, 导致网格定位出错的问题
- 修复了在边缘外有错误的内部线时, 会把边缘删除的问题
- 调整了一图的边缘识别参数
- 修复了紧急委托过多时, 会触发同一按钮点击过多停止的问题
  委托列表拖动方式从 拖动-点击 改为 拖拽抖动
  独立出random_rectangle_vector函数
  增加random_line_segments函数
- 更改: 索敌时默认使用地图权重
- 修复了收菜获取物品过多时会卡住的问题
- 写死了1-1的相机移动, 防止因为地图太小导致透视识别错误
This commit is contained in:
LmeSzinc 2020-04-13 16:07:32 +08:00
parent 061077c690
commit 5b3dc4ec85
9 changed files with 99 additions and 28 deletions

View File

@ -2,6 +2,8 @@ from module.campaign.campaign_base import CampaignBase
from module.map.map_base import CampaignMap from module.map.map_base import CampaignMap
from module.map.map_grids import SelectedGrids, RoadGrids from module.map.map_grids import SelectedGrids, RoadGrids
from module.logger import logger from module.logger import logger
from module.map.exception import CampaignEnd
MAP = CampaignMap() MAP = CampaignMap()
MAP.shape = 'G1' MAP.shape = 'G1'
@ -16,6 +18,7 @@ MAP.spawn_data = [
A1, B1, C1, D1, E1, F1, G1, \ A1, B1, C1, D1, E1, F1, G1, \
= MAP.flatten() = MAP.flatten()
class Config: class Config:
FLEET_2 = 0 FLEET_2 = 0
SUBMARINE = 0 SUBMARINE = 0
@ -25,9 +28,16 @@ class Config:
'prominence': 10, 'prominence': 10,
'distance': 35, 'distance': 35,
} }
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
'height': (255 - 40, 255),
'prominence': 10,
'distance': 50,
'wlen': 1000
}
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40 INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40
EDGE_LINES_HOUGHLINES_THRESHOLD = 40 EDGE_LINES_HOUGHLINES_THRESHOLD = 40
class Campaign(CampaignBase): class Campaign(CampaignBase):
MAP = MAP MAP = MAP
@ -36,3 +46,7 @@ class Campaign(CampaignBase):
def battle_1(self): def battle_1(self):
return self.clear_boss() return self.clear_boss()
def handle_boss_appear_refocus(self):
self.map_swipe((-3, 0))
return super().handle_boss_appear_refocus()

View File

@ -43,7 +43,7 @@ def random_rectangle_point(area):
"""Choose a random point in an area. """Choose a random point in an area.
Args: 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: Returns:
int: x int: x
@ -54,6 +54,44 @@ def random_rectangle_point(area):
return x, y 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): def area_offset(area, offset):
""" """
@ -278,9 +316,10 @@ def color_bar_percentage(image, area, prev_color, reverse=False, starter=0, thre
Args: Args:
image: image:
area: area:
prev_color:
reverse: True if bar goes from right to left. reverse: True if bar goes from right to left.
starter: starter:
prev_color: threshold:
Returns: Returns:
float: 0 to 1. float: 0 to 1.

View File

@ -1,7 +1,7 @@
import numpy as np import numpy as np
from module.base.timer import Timer 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.assets import *
from module.combat.combat_auto import CombatAuto from module.combat.combat_auto import CombatAuto
from module.combat.combat_manual import CombatManual from module.combat.combat_manual import CombatManual
@ -79,7 +79,7 @@ class Combat(HPBalancer, UrgentCommissionHandler, EnemySearchingHandler, Retirem
Returns: Returns:
bool: 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): def handle_combat_automation_confirm(self):
if self.appear(AUTOMATION_CONFIRM_CHECK, interval=1): if self.appear(AUTOMATION_CONFIRM_CHECK, interval=1):

View File

@ -106,21 +106,11 @@ class Control(Connection):
duration(int, float, tuple): duration(int, float, tuple):
""" """
duration = ensure_time(duration) duration = ensure_time(duration)
vector = np.array(vector) + random_rectangle_point(random_range) start, end = random_rectangle_vector(vector, box, random_range=random_range, padding=padding)
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
logger.info( 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() fx, fy, tx, ty = np.append(start, end).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)
))
self.device.swipe(fx, fy, tx, ty, duration=duration) self.device.swipe(fx, fy, tx, ty, duration=duration)
def drag_along(self, path): def drag_along(self, path):
@ -162,13 +152,29 @@ class Control(Connection):
logger.info(self._point2str(x, y) + ' move') logger.info(self._point2str(x, y) + ' move')
self.sleep(second) 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): 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) p1 = np.array(p1) - random_rectangle_point(point_random)
p2 = np.array(p2) - random_rectangle_point(point_random) p2 = np.array(p2) - random_rectangle_point(point_random)
path = [ path = [(x, y, swipe_duration) for x, y in random_line_segments(p1, p2, n=segments, random_range=point_random)]
(*p1, swipe_duration), path += [
(*p2, shake_duration),
(*p2 + shake + random_rectangle_point(shake_random), shake_duration), (*p2 + shake + random_rectangle_point(shake_random), shake_duration),
(*p2 - shake - random_rectangle_point(shake_random), shake_duration), (*p2 - shake - random_rectangle_point(shake_random), shake_duration),
(*p2, shake_duration) (*p2, shake_duration)

View File

@ -34,6 +34,10 @@ class Grids(Perspective):
diff = len(self.vertical) - len(vertical) diff = len(self.vertical) - len(vertical)
if diff > 0: if diff > 0:
logger.info(f' Grids offset: {(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.vertical = vertical
self.grids = {} self.grids = {}
for grid in self._gen(): for grid in self._gen():

View File

@ -61,7 +61,7 @@ class Map(Fleet):
@staticmethod @staticmethod
def select_grids(grids, nearby=False, is_accessible=True, scale=(), strongest=False, weakest=False, cost=True, 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: Args:
grids (SelectedGrids): grids (SelectedGrids):

View File

@ -256,7 +256,9 @@ class Perspective:
threshold(int): threshold(int):
Returns: 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]) right_distant_point = (self.vanish_point[0] * 2 - self.distant_point[0], self.distant_point[1])
@ -343,7 +345,9 @@ class Perspective:
# Cleansing edge # Cleansing edge
edge = edge.mid edge = edge.mid
inner = inner.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)] edge = [c for c in clean if np.any(np.abs(c - edge) < 5)]
# Separate edges # Separate edges

View File

@ -7,7 +7,7 @@ from scipy import signal
from module.base.ocr import Ocr from module.base.ocr import Ocr
from module.base.timer import Timer 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.handler.info_bar import InfoBarHandler
from module.logger import logger from module.logger import logger
from module.reward.assets import * from module.reward.assets import *
@ -309,10 +309,10 @@ class RewardCommission(UI, InfoBarHandler):
return True return True
def _commission_swipe(self, distance=180): def _commission_swipe(self, distance=300):
# Distance of two commission is 146px # Distance of two commission is 146px
self.device.swipe((0, -distance), box=(620, 67, 1154, 692), random_range=(-20, -5, 20, 5)) p1, p2 = random_rectangle_vector((0, -distance), box=(620, 67, 1154, 692), random_range=(-20, -5, 20, 5))
self.device.click(COMMISSION_STOP_SCROLLING) 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.sleep(0.3)
self.device.screenshot() self.device.screenshot()

View File

@ -85,6 +85,10 @@ class Reward(RewardCommission):
reward = True reward = True
continue continue
if not self.appear(page_reward.check_button):
exit_timer.reset()
continue
# End # End
if exit_timer.reached(): if exit_timer.reached():
break break