Linting
This commit is contained in:
2
Makefile
2
Makefile
@@ -12,4 +12,4 @@ typing:
|
|||||||
mypy --strict ${PROJECTNAME} test
|
mypy --strict ${PROJECTNAME} test
|
||||||
|
|
||||||
linting:
|
linting:
|
||||||
pylint ${PROJECTNAME} test
|
pylint --extension-pkg-whitelist=cv2 ${PROJECTNAME} test
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
from typing import Optional, Tuple
|
from typing import Optional, Tuple
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import numpy # type: ignore
|
import numpy
|
||||||
import cv2 # type: ignore
|
import cv2
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
|
"""Contains parse_board function"""
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from .configuration import Configuration
|
from .configuration import Configuration
|
||||||
from ..board import Board
|
from ..board import Board
|
||||||
from . import card_finder
|
from . import card_finder
|
||||||
import copy
|
|
||||||
|
|
||||||
|
|
||||||
def parse_board(image: np.ndarray, conf: Configuration) -> Board:
|
def parse_board(image: np.ndarray, conf: Configuration) -> Board:
|
||||||
|
"""Parse a screenshot of the game, using a given configuration"""
|
||||||
squares = card_finder.get_field_squares(
|
squares = card_finder.get_field_squares(
|
||||||
image, conf.field_adjustment, count_x=13, count_y=8)
|
image, conf.field_adjustment, count_x=13, count_y=8)
|
||||||
squares = [card_finder.simplify(square)[0] for square in squares]
|
squares = [card_finder.simplify(square)[0] for square in squares]
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ def get_field_squares(image: np.ndarray,
|
|||||||
adjustment: Adjustment,
|
adjustment: Adjustment,
|
||||||
count_x: int,
|
count_x: int,
|
||||||
count_y: int) -> List[np.ndarray]:
|
count_y: int) -> List[np.ndarray]:
|
||||||
|
"""Return all squares in the field, according to the adjustment"""
|
||||||
squares = []
|
squares = []
|
||||||
for index_x, index_y in itertools.product(range(count_y), range(count_x)):
|
for index_x, index_y in itertools.product(range(count_y), range(count_x)):
|
||||||
squares.append(get_square(adjustment, index_x, index_y))
|
squares.append(get_square(adjustment, index_x, index_y))
|
||||||
@@ -46,6 +47,7 @@ GREYSCALE_COLOR = {
|
|||||||
|
|
||||||
|
|
||||||
def simplify(image: np.ndarray) -> Tuple[np.ndarray, Dict[Cardcolor, int]]:
|
def simplify(image: np.ndarray) -> Tuple[np.ndarray, Dict[Cardcolor, int]]:
|
||||||
|
"""Reduce given image to the colors in Cardcolor"""
|
||||||
result_image: np.ndarray = np.zeros(
|
result_image: np.ndarray = np.zeros(
|
||||||
(image.shape[0], image.shape[1]), np.uint8)
|
(image.shape[0], image.shape[1]), np.uint8)
|
||||||
result_dict: Dict[Cardcolor, int] = {c: 0 for c in Cardcolor}
|
result_dict: Dict[Cardcolor, int] = {c: 0 for c in Cardcolor}
|
||||||
@@ -69,40 +71,42 @@ def _find_single_square(search_square: np.ndarray,
|
|||||||
assert search_square.shape[0] >= template_square.shape[0]
|
assert search_square.shape[0] >= template_square.shape[0]
|
||||||
assert search_square.shape[1] >= template_square.shape[1]
|
assert search_square.shape[1] >= template_square.shape[1]
|
||||||
best_result: Optional[Tuple[int, Tuple[int, int]]] = None
|
best_result: Optional[Tuple[int, Tuple[int, int]]] = None
|
||||||
for x, y in itertools.product(
|
for margin_x, margin_y in itertools.product(
|
||||||
range(search_square.shape[0], template_square.shape[0] - 1, -1),
|
range(search_square.shape[0], template_square.shape[0] - 1, -1),
|
||||||
range(search_square.shape[1], template_square.shape[1] - 1, -1)):
|
range(search_square.shape[1], template_square.shape[1] - 1, -1)):
|
||||||
p = search_square[x - template_square.shape[0]:x,
|
search_region = search_square[margin_x -
|
||||||
y - template_square.shape[1]:y] - template_square
|
template_square.shape[0]:margin_x, margin_y -
|
||||||
count = cv2.countNonZero(p)
|
template_square.shape[1]:margin_y]
|
||||||
|
count = cv2.countNonZero(search_region - template_square)
|
||||||
if not best_result or count < best_result[0]:
|
if not best_result or count < best_result[0]:
|
||||||
best_result = (
|
best_result = (
|
||||||
count,
|
count,
|
||||||
(x - template_square.shape[0],
|
(margin_x - template_square.shape[0],
|
||||||
y - template_square.shape[1]))
|
margin_y - template_square.shape[1]))
|
||||||
assert best_result
|
assert best_result
|
||||||
return best_result
|
return best_result
|
||||||
|
|
||||||
|
|
||||||
def find_square(search_square: np.ndarray,
|
def find_square(search_square: np.ndarray,
|
||||||
squares: List[np.ndarray]) -> Tuple[np.ndarray, int]:
|
squares: List[np.ndarray]) -> Tuple[np.ndarray, int]:
|
||||||
|
"""Compare all squares in squares with search_square, return best matching one.
|
||||||
|
Requires all squares to be simplified."""
|
||||||
best_set = False
|
best_set = False
|
||||||
best_square: Optional[np.ndarray] = None
|
best_square: Optional[np.ndarray] = None
|
||||||
best_count = 0
|
best_count = 0
|
||||||
best_coord: Optional[Tuple[int, int]] = None
|
|
||||||
for square in squares:
|
for square in squares:
|
||||||
count, coord = _find_single_square(search_square, square)
|
count, _ = _find_single_square(search_square, square)
|
||||||
if not best_set or count < best_count:
|
if not best_set or count < best_count:
|
||||||
best_set = True
|
best_set = True
|
||||||
best_square = square
|
best_square = square
|
||||||
best_count = count
|
best_count = count
|
||||||
best_coord = coord
|
|
||||||
assert isinstance(best_square, np.ndarray)
|
assert isinstance(best_square, np.ndarray)
|
||||||
return (best_square, best_count)
|
return (best_square, best_count)
|
||||||
|
|
||||||
|
|
||||||
def catalogue_cards(squares: List[np.ndarray]
|
def catalogue_cards(squares: List[np.ndarray]
|
||||||
) -> List[Tuple[np.ndarray, Card]]:
|
) -> List[Tuple[np.ndarray, Card]]:
|
||||||
|
"""Run manual cataloging for given squares"""
|
||||||
cv2.namedWindow("Catalogue", cv2.WINDOW_NORMAL)
|
cv2.namedWindow("Catalogue", cv2.WINDOW_NORMAL)
|
||||||
cv2.waitKey(1)
|
cv2.waitKey(1)
|
||||||
result: List[Tuple[np.ndarray, Card]] = []
|
result: List[Tuple[np.ndarray, Card]] = []
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ def solve(board: Board) -> Iterator[List[board_actions.Action]]:
|
|||||||
stack.push(board)
|
stack.push(board)
|
||||||
|
|
||||||
def _limit_stack_size(stack_size: int) -> None:
|
def _limit_stack_size(stack_size: int) -> None:
|
||||||
if len(stack) == -1:
|
if len(stack) == stack_size:
|
||||||
stack.pop()
|
stack.pop()
|
||||||
assert stack.action_stack[-1] is not None
|
assert stack.action_stack[-1] is not None
|
||||||
stack.action_stack[-1].undo(board)
|
stack.action_stack[-1].undo(board)
|
||||||
|
|||||||
Reference in New Issue
Block a user