Added laptop config

This commit is contained in:
Lukas Wölfer
2020-06-14 00:56:31 +02:00
parent 63d4348f94
commit 1fb5a92de4
3 changed files with 63 additions and 32 deletions

BIN
laptop_conf.zip Normal file

Binary file not shown.

View File

@@ -10,28 +10,36 @@ import warnings
from dataclasses import dataclass from dataclasses import dataclass
from shenzhen_solitaire.board import SpecialCard from shenzhen_solitaire.board import SpecialCard
DRAG_DURATION = 0.4 DRAG_DURATION = 0.2
CLICK_DURATION = 0.5 CLICK_DURATION = 1
DRAGON_WAIT = 1
HUA_WAIT = 1
GOAL_WAIT = 0.4
def drag( def drag(
src: Tuple[int, int], dst: Tuple[int, int], offset: Tuple[int, int] = (0, 0) src: Tuple[int, int], dst: Tuple[int, int], offset: Tuple[int, int] = (0, 0)
) -> None: ) -> None:
time.sleep(DRAG_DURATION / 3)
pyautogui.moveTo(x=src[0] + offset[0], y=src[1] + offset[1]) pyautogui.moveTo(x=src[0] + offset[0], y=src[1] + offset[1])
pyautogui.dragTo( pyautogui.mouseDown()
x=dst[0] + offset[0], time.sleep(DRAG_DURATION / 3)
y=dst[1] + offset[1], pyautogui.moveTo(
duration=DRAG_DURATION, x=dst[0] + offset[0], y=dst[1] + offset[1],
tween=lambda x: 0 if x < 0.5 else 1,
) )
pyautogui.mouseUp()
time.sleep(DRAG_DURATION / 3)
def click(point: Tuple[int, int], offset: Tuple[int, int] = (0, 0)) -> None: def click(point: Tuple[int, int], offset: Tuple[int, int] = (0, 0)) -> None:
time.sleep(CLICK_DURATION / 3)
pyautogui.moveTo(x=point[0] + offset[0], y=point[1] + offset[1]) pyautogui.moveTo(x=point[0] + offset[0], y=point[1] + offset[1])
pyautogui.mouseDown() pyautogui.mouseDown()
time.sleep(CLICK_DURATION) time.sleep(CLICK_DURATION / 3)
pyautogui.mouseUp() pyautogui.mouseUp()
time.sleep(CLICK_DURATION / 3)
time.sleep(DRAGON_WAIT)
@dataclass @dataclass
@@ -44,9 +52,9 @@ class DragAction:
class ClickAction: class ClickAction:
destination: Tuple[int, int] destination: Tuple[int, int]
@dataclass
class WaitAction: class WaitAction:
pass duration: float
def _parse_field( def _parse_field(
@@ -106,15 +114,24 @@ def parse_action(
) )
) )
elif action_name == "goal": elif action_name == "goal":
obvious = (
goal_values[info["card"]["suit"].lower()] <= min(goal_values.values()) + 1 current_value = goal_values[info["card"]["suit"].lower()]
) proposed_value = info["card"]["value"]
assert (goal_values[info["card"]["suit"].lower()] == 0) or (
goal_values[info["card"]["suit"].lower()] + 1 == info["card"]["value"] assert (current_value == 0) or (current_value + 1 == proposed_value)
)
goal_values[info["card"]["suit"].lower()] = info["card"]["value"] if proposed_value == min(goal_values.values()) + 1:
obvious = True
elif proposed_value == 2:
obvious = True
else:
obvious = False
goal_values[info["card"]["suit"].lower()] = proposed_value
if obvious: if obvious:
return WaitAction() return WaitAction(duration=GOAL_WAIT)
goal = ( goal = (
int(info["goal_slot_index"]) * conf.goal_adjustment.dx int(info["goal_slot_index"]) * conf.goal_adjustment.dx
+ conf.goal_adjustment.x + conf.goal_adjustment.x
@@ -132,7 +149,9 @@ def parse_action(
) )
return DragAction(source=source, destination=goal) return DragAction(source=source, destination=goal)
elif action_name == "huakill": elif action_name == "huakill":
return WaitAction() return WaitAction(duration=HUA_WAIT)
else:
assert 0
def handle_actions( def handle_actions(
@@ -141,9 +160,9 @@ def handle_actions(
conf: configuration.Configuration, conf: configuration.Configuration,
) -> None: ) -> None:
goal_values = {"red": 0, "black": 0, "green": 0} goal_values = {"red": 0, "black": 0, "green": 0}
action_tuples = [ action_tuples = (
(action, parse_action(action, conf, goal_values)) for action in actions (action, parse_action(action, conf, goal_values)) for action in actions
] )
for name, action in action_tuples: for name, action in action_tuples:
print(name) print(name)
if isinstance(action, DragAction): if isinstance(action, DragAction):
@@ -151,4 +170,4 @@ def handle_actions(
elif isinstance(action, ClickAction): elif isinstance(action, ClickAction):
click(action.destination, offset) click(action.destination, offset)
elif isinstance(action, WaitAction): elif isinstance(action, WaitAction):
time.sleep(2) time.sleep(action.duration)

View File

@@ -18,16 +18,23 @@ from shenzhen_solitaire.card_detection.board_parser import parse_start_board
OFFSET = (0, 0) OFFSET = (0, 0)
# SIZE = (2560, 1440) # SIZE = (2560, 1440)
SIZE = (1366, 768) SIZE = (1366, 768)
NEW_BUTTON = (1900, 1100) # NEW_BUTTON = (1900, 1100)
NEW_BUTTON = (1340, 750)
SAVE_UNSOLVED = False SAVE_UNSOLVED = False
UNSOLVED_DIR = "E:/shenzhen-solitaire/unsolved" UNSOLVED_DIR = "E:/shenzhen-solitaire/unsolved"
SOLVER_PATH = '/home/lukas/documents/coding/rust/shenzhen-solitaire/target/release/solver' SOLVER_PATH = (
"/home/lukas/documents/coding/rust/shenzhen-solitaire/target/release/solver"
)
def extern_solve(board: Board) -> List[Dict[str, Any]]: def extern_solve(board: Board) -> List[Dict[str, Any]]:
result = subprocess.run([SOLVER_PATH], input=board.to_json(), capture_output=True, text=True) result = subprocess.run(
[SOLVER_PATH], input=board.to_json(), capture_output=True, text=True
)
return json.loads(result.stdout) return json.loads(result.stdout)
def take_screenshot(): def take_screenshot():
with tempfile.TemporaryDirectory(prefix="shenzhen_solitaire") as screenshot_dir: with tempfile.TemporaryDirectory(prefix="shenzhen_solitaire") as screenshot_dir:
print("Taking screenshot") print("Taking screenshot")
@@ -37,6 +44,7 @@ def take_screenshot() :
image = cv2.imread(str(screenshot_file)) image = cv2.imread(str(screenshot_file))
return image return image
def solve(conf: configuration.Configuration) -> None: def solve(conf: configuration.Configuration) -> None:
image = take_screenshot() image = take_screenshot()
board = parse_start_board(image, conf) board = parse_start_board(image, conf)
@@ -52,16 +60,20 @@ def solve(conf: configuration.Configuration) -> None:
def main() -> None: def main() -> None:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(description="Solve board")
description="Solve board" parser.add_argument(
"config_path", type=str, help="Config path",
) )
parser.add_argument( parser.add_argument(
"config_path", "--no-failsafe",
type=str, dest="no_failsafe",
help="Config path", action="store_false",
help="Enable 0.1 second delay between all actions to allow user to interrupt",
) )
args = parser.parse_args() args = parser.parse_args()
if not args.no_failsafe:
pyautogui.PAUSE = 0
time.sleep(3) time.sleep(3)
conf = configuration.load(args.config_path) conf = configuration.load(args.config_path)
while True: while True: