Skip to content

Commit

Permalink
style: format code with black
Browse files Browse the repository at this point in the history
  • Loading branch information
NateScarlet committed Jun 7, 2021
1 parent fc7b853 commit 2e4c9e7
Show file tree
Hide file tree
Showing 39 changed files with 7,160 additions and 14,795 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/python-app.yml
Expand Up @@ -27,3 +27,6 @@ jobs:
- name: Test
run: |
make test
- name: Lint
run: |
make lint
8 changes: 5 additions & 3 deletions Makefile
@@ -1,7 +1,9 @@
.PHONY: test default
.PHONY: default test lint


default:
default: test lint

test:
py -3.8 -m pytest auto_derby

lint:
py -3.8 -m black -t py38 --check .
27 changes: 18 additions & 9 deletions auto_derby/__main__.py
Expand Up @@ -36,14 +36,22 @@ def main():
job = avaliable_jobs.get(args.job)

if not job:
LOGGER.error("unknown job: %s\navaliable jobs:\n %s",
args.job, "\n ".join(avaliable_jobs.keys()))
LOGGER.error(
"unknown job: %s\navaliable jobs:\n %s",
args.job,
"\n ".join(avaliable_jobs.keys()),
)
exit(1)

h_wnd = window.get_game()
if not h_wnd:
if win32gui.MessageBox(0, "Launch DMM umamusume?", "Can not found window", win32con.MB_YESNO) == 6:
webbrowser.open('dmmgameplayer://umamusume/cl/general/umamusume')
if (
win32gui.MessageBox(
0, "Launch DMM umamusume?", "Can not found window", win32con.MB_YESNO
)
== 6
):
webbrowser.open("dmmgameplayer://umamusume/cl/general/umamusume")
while not h_wnd:
time.sleep(1)
LOGGER.info("waiting game launch")
Expand All @@ -63,20 +71,21 @@ def is_admin():
return False


if __name__ == '__main__':
if __name__ == "__main__":
logging.basicConfig(
format="%(levelname)-6s[%(asctime)s]:%(name)s:%(lineno)d: %(message)s",
level=logging.INFO,
datefmt="%H:%M:%S",
)
LOG_PATH = os.getenv("AUTO_DERBY_LOG_PATH", 'auto_derby.log')
LOG_PATH = os.getenv("AUTO_DERBY_LOG_PATH", "auto_derby.log")
if LOG_PATH and LOG_PATH != "-":
handler = logging.handlers.RotatingFileHandler(
LOG_PATH, backupCount=3, encoding="utf-8")
LOG_PATH, backupCount=3, encoding="utf-8"
)
handler.doRollover()
formatter = logging.Formatter(
"%(levelname)-6s[%(asctime)s]:%(name)s:%(lineno)d: %(message)s",
'%Y-%m-%d %H:%M:%S',
"%Y-%m-%d %H:%M:%S",
)
handler.setFormatter(formatter)
logging.root.addHandler(handler)
Expand All @@ -88,7 +97,7 @@ def is_admin():

if not is_admin():
LOGGER.error(
"admin permission is required, otherwise mouse event will be ignored by the game.",
"admin permission is required, otherwise mouse event will be ignored by the game."
)
exit(1)
try:
Expand Down
33 changes: 23 additions & 10 deletions auto_derby/action.py
Expand Up @@ -58,10 +58,12 @@ def match_image_until_disappear(
break


def wait_image(*tmpl: Union[Text, template.Specification]) -> Tuple[template.Specification, Tuple[int, int]]:
def wait_image(
*tmpl: Union[Text, template.Specification]
) -> Tuple[template.Specification, Tuple[int, int]]:
while True:
try:
return next(template.match(template.screenshot(max_age=0), *tmpl,))
return next(template.match(template.screenshot(max_age=0), *tmpl))
except StopIteration:
time.sleep(0.01)

Expand All @@ -75,7 +77,9 @@ def wait_image_disappear(*tmpl: Union[Text, template.Specification]) -> None:
break


def click_image(name: Union[Text, template.Specification], *, x: int = 0, y: int = 0) -> bool:
def click_image(
name: Union[Text, template.Specification], *, x: int = 0, y: int = 0
) -> bool:
try:
name, pos = next(template.match(template.screenshot(), name))
click((pos[0] + x, pos[1] + y))
Expand All @@ -84,12 +88,14 @@ def click_image(name: Union[Text, template.Specification], *, x: int = 0, y: int
return False


def wait_click_image(name: Union[Text, template.Specification], *, x: int = 0, y: int = 0) -> None:
def wait_click_image(
name: Union[Text, template.Specification], *, x: int = 0, y: int = 0
) -> None:
_, pos = wait_image(name)
click((pos[0]+x, pos[1]+y))
click((pos[0] + x, pos[1] + y))


def move_at_window(h_wnd: int, point: Tuple[int, int]):
def move_at_window(h_wnd: int, point: Tuple[int, int]):
x, y = win32gui.ClientToScreen(h_wnd, point)
mouse.move(x, y)

Expand All @@ -112,10 +118,12 @@ def wheel(delta: int) -> None:
template.invalidate_screeshot()


def drag_at_window(h_wnd: int, point: Tuple[int, int], *, dx: int, dy: int, duration: float = 1):
def drag_at_window(
h_wnd: int, point: Tuple[int, int], *, dx: int, dy: int, duration: float = 1
):
x, y = win32gui.ClientToScreen(h_wnd, point)
with window.topmost(h_wnd), window.recover_foreground(), recover_cursor():
mouse.drag(x, y, x+dx, y+dy, duration=duration)
mouse.drag(x, y, x + dx, y + dy, duration=duration)


def drag(point: Tuple[int, int], *, dx: int = 0, dy: int = 0, duration: float = 0.03):
Expand All @@ -132,7 +140,9 @@ def pressing_mouse(button: Text = "left"):
mouse.release(button)


def drag_through_at_window(h_wnd: int, *points: Tuple[int, int], duration: float = 0.05) -> Iterator[Tuple[int, int]]:
def drag_through_at_window(
h_wnd: int, *points: Tuple[int, int], duration: float = 0.05
) -> Iterator[Tuple[int, int]]:
with recover_cursor(), window.recover_foreground():
window.set_forground(h_wnd)
move_at_window(h_wnd, points[0])
Expand All @@ -143,7 +153,10 @@ def drag_through_at_window(h_wnd: int, *points: Tuple[int, int], duration: float
mouse.move(x, y, duration=duration)
yield p

def drag_through(*points: Tuple[int, int], duration: float = 0.02) -> Iterator[Tuple[int, int]]:

def drag_through(
*points: Tuple[int, int], duration: float = 0.02
) -> Iterator[Tuple[int, int]]:
for i in drag_through_at_window(window.get_game(), *points, duration=duration):
template.invalidate_screeshot()
yield i
84 changes: 43 additions & 41 deletions auto_derby/imagetools.py
Expand Up @@ -70,22 +70,37 @@ def pil_image(img: np.ndarray) -> Image:
return fromarray(img)


def compare_color(a: Union[Tuple[int, ...], int], b: Union[Tuple[int, ...], int], *, bit_size: int = 8) -> float:
def compare_color(
a: Union[Tuple[int, ...], int], b: Union[Tuple[int, ...], int], *, bit_size: int = 8
) -> float:
max_value = (1 << bit_size) - 1
t_a = tuple(cast.list_(a, (int,)))
t_b = tuple(cast.list_(b, (int,)))
if len(t_a) != len(t_b):
return 0

return max(1 - _cast_float(np.sqrt(_cast_float(np.sum((np.array(t_a)-np.array(t_b)) ** 2, axis=0)))) / max_value, 0)
return max(
1
- _cast_float(
np.sqrt(_cast_float(np.sum((np.array(t_a) - np.array(t_b)) ** 2, axis=0)))
)
/ max_value,
0,
)


def level(img: np.ndarray, black: np.ndarray, white: np.ndarray, *, bit_size: int = 8) -> np.ndarray:
def level(
img: np.ndarray, black: np.ndarray, white: np.ndarray, *, bit_size: int = 8
) -> np.ndarray:
max_value = (1 << bit_size) - 1
return np.clip((img - black) / (white - black) * max_value, 0, max_value).astype(img.dtype)
return np.clip((img - black) / (white - black) * max_value, 0, max_value).astype(
img.dtype
)


def color_key(img: np.ndarray, color: np.ndarray, threshold: float = 0.8, bit_size: int = 8) -> np.ndarray:
def color_key(
img: np.ndarray, color: np.ndarray, threshold: float = 0.8, bit_size: int = 8
) -> np.ndarray:
max_value = (1 << bit_size) - 1
assert img.shape == color.shape, (img.shape, color.shape)

Expand All @@ -95,12 +110,15 @@ def color_key(img: np.ndarray, color: np.ndarray, threshold: float = 0.8, bit_si

# do this is somehow faster than
# `numpy.linalg.norm(img.astype(int) - color.astype(int), axis=2,).clip(0, 255).astype(np.uint8)`
diff_img = np.asarray(np.sqrt(
np.asarray(np.sum(
(img.astype(int) - color.astype(int)) ** 2,
axis=2,
)),
)).clip(0, 255).astype(img.dtype)
diff_img = (
np.asarray(
np.sqrt(
np.asarray(np.sum((img.astype(int) - color.astype(int)) ** 2, axis=2))
)
)
.clip(0, 255)
.astype(img.dtype)
)

ret = max_value - diff_img
if threshold > 0:
Expand All @@ -111,15 +129,14 @@ def color_key(img: np.ndarray, color: np.ndarray, threshold: float = 0.8, bit_si
return ret


def constant_color_key(img: np.ndarray, *colors: Tuple[int, ...], threshold: float = 0.8, bit_size: int = 8) -> np.ndarray:
def constant_color_key(
img: np.ndarray, *colors: Tuple[int, ...], threshold: float = 0.8, bit_size: int = 8
) -> np.ndarray:
ret = np.zeros(img.shape[:2])

for color in colors:
match_img = color_key(
img,
np.full_like(img, color),
threshold=threshold,
bit_size=bit_size,
img, np.full_like(img, color), threshold=threshold, bit_size=bit_size
)
ret = np.array(np.maximum(ret, match_img))

Expand All @@ -128,23 +145,17 @@ def constant_color_key(img: np.ndarray, *colors: Tuple[int, ...], threshold: flo

def sharpen(img: np.ndarray, size: int = 1, *, bit_size: int = 8) -> np.ndarray:
return cv2.filter2D(
img,
bit_size,
np.array(
(
(-1, -1, -1),
(-1, 9, -1),
(-1, -1, -1),
),
) * size
img, bit_size, np.array(((-1, -1, -1), (-1, 9, -1), (-1, -1, -1))) * size
)


def mix(a: np.ndarray, b: np.ndarray, a_mix: float) -> np.ndarray:
total_ratio = 10000
a_ratio = int(a_mix * 10000)
b_ratio = total_ratio - a_ratio
return ((a.astype(int) * a_ratio + b.astype(int) * b_ratio) / total_ratio).astype(a.dtype)
return ((a.astype(int) * a_ratio + b.astype(int) * b_ratio) / total_ratio).astype(
a.dtype
)


def bg_mask_by_outline(outline_img: np.ndarray) -> np.ndarray:
Expand All @@ -153,25 +164,17 @@ def bg_mask_by_outline(outline_img: np.ndarray) -> np.ndarray:
border_points = (
*((0, i) for i in range(h)),
*((i, 0) for i in range(w)),
*((w-1, i) for i in range(h)),
*((i, h-1) for i in range(w)),
*((w - 1, i) for i in range(h)),
*((i, h - 1) for i in range(w)),
)

fill_mask_img = cv2.copyMakeBorder(
outline_img, 1, 1, 1, 1, cv2.BORDER_CONSTANT)
fill_mask_img = cv2.copyMakeBorder(outline_img, 1, 1, 1, 1, cv2.BORDER_CONSTANT)
bg_mask_img = np.zeros_like(outline_img)
for i in border_points:
x, y = i
if outline_img[y, x] != 0:
continue
cv2.floodFill(
bg_mask_img,
fill_mask_img,
(x, y),
(255, ),
0,
0,
)
cv2.floodFill(bg_mask_img, fill_mask_img, (x, y), (255,), 0, 0)

return bg_mask_img

Expand All @@ -185,9 +188,7 @@ def resize_by_heihgt(img: Image, height: int) -> Image:

def fill_area(img: np.ndarray, color: Tuple[int, ...], *, size_lt: int):
contours, _ = cv2.findContours(
(img * 255).astype(np.uint8),
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE,
(img * 255).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE
)
for i in contours:
size = cv2.contourArea(i)
Expand All @@ -214,6 +215,7 @@ def _run():
break
finally:
cv2.destroyWindow(title)

t = threading.Thread(target=_run, daemon=True)
t.start()

Expand Down
21 changes: 11 additions & 10 deletions auto_derby/imagetools_test.py
@@ -1,16 +1,17 @@


import pytest
from . import imagetools


@pytest.mark.parametrize('a,b,expected', [
(0, 0, 1),
(0, 255, 0),
((0, 0, 0), (0, 0, 0), 1),
((0, 0, 0), (255, 255, 255), 0),
((0, 0, 0), (10, 10, 10), 0.9320764389188676),
((0, 0, 0), (10, 0, 0), 0.9607843137254902),
])
@pytest.mark.parametrize(
"a,b,expected",
[
(0, 0, 1),
(0, 255, 0),
((0, 0, 0), (0, 0, 0), 1),
((0, 0, 0), (255, 255, 255), 0),
((0, 0, 0), (10, 10, 10), 0.9320764389188676),
((0, 0, 0), (10, 0, 0), 0.9607843137254902),
],
)
def test_compare_color(a, b, expected):
assert imagetools.compare_color(a, b) == expected
3 changes: 1 addition & 2 deletions auto_derby/jobs/limited_sale.py
Expand Up @@ -8,8 +8,7 @@ def buy_everything():
action.wait_click_image(templates.GO_TO_LIMITED_SALE)
action.wait_image(templates.CLOSE_NOW_BUTTON)
for _, pos in action.match_image_until_disappear(
templates.EXCHANGE_BUTTON,
sort=lambda x: sorted(x, key=lambda i: i[1][1])
templates.EXCHANGE_BUTTON, sort=lambda x: sorted(x, key=lambda i: i[1][1])
):
action.click(pos)
action.wait_click_image(templates.EXCHANGE_CONFIRM_BUTTON)
Expand Down

0 comments on commit 2e4c9e7

Please sign in to comment.