Made it work again, automatic goal moves messing with me though
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import time
|
||||
from typing import List, Tuple, Dict, Any
|
||||
from typing import List, Tuple, Dict, Any, Union
|
||||
|
||||
import pyautogui
|
||||
import shenzhen_solitaire.board as board
|
||||
@@ -8,6 +8,10 @@ import shenzhen_solitaire.card_detection.configuration as configuration
|
||||
import warnings
|
||||
|
||||
from dataclasses import dataclass
|
||||
from shenzhen_solitaire.board import SpecialCard
|
||||
|
||||
DRAG_DURATION = 0.4
|
||||
CLICK_DURATION = 0.5
|
||||
|
||||
|
||||
def drag(
|
||||
@@ -18,39 +22,18 @@ def drag(
|
||||
pyautogui.dragTo(
|
||||
x=dst[0] + offset[0],
|
||||
y=dst[1] + offset[1],
|
||||
duration=0.4,
|
||||
duration=DRAG_DURATION,
|
||||
tween=lambda x: 0 if x < 0.5 else 1,
|
||||
)
|
||||
|
||||
|
||||
def dragSquare(
|
||||
src: Tuple[int, int, int, int],
|
||||
dst: Tuple[int, int, int, int],
|
||||
offset: Tuple[int, int] = (0, 0),
|
||||
) -> None:
|
||||
drag(
|
||||
(src[0] + (src[2] - src[0]) // 2, src[1] + (src[3] - src[1]) // 2),
|
||||
(dst[0] + (dst[2] - dst[0]) // 2, dst[1] + (dst[3] - dst[1]) // 2),
|
||||
offset,
|
||||
)
|
||||
|
||||
|
||||
def click(point: Tuple[int, int], offset: Tuple[int, int] = (0, 0)) -> None:
|
||||
pyautogui.moveTo(x=point[0] + offset[0], y=point[1] + offset[1])
|
||||
pyautogui.mouseDown()
|
||||
time.sleep(0.2)
|
||||
time.sleep(CLICK_DURATION)
|
||||
pyautogui.mouseUp()
|
||||
|
||||
|
||||
def clickSquare(
|
||||
field: Tuple[int, int, int, int], offset: Tuple[int, int] = (0, 0)
|
||||
) -> None:
|
||||
click(
|
||||
(field[0] + (field[2] - field[0]) // 2, field[1] + (field[3] - field[1]) // 2),
|
||||
offset,
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class DragAction:
|
||||
source: Tuple[int, int]
|
||||
@@ -70,12 +53,20 @@ def _parse_field(
|
||||
field: Dict[str, Any], conf: configuration.Configuration
|
||||
) -> Tuple[int, int]:
|
||||
return (
|
||||
int(field["column"]) * conf.field_adjustment.dx + conf.field_adjustment.x,
|
||||
int(field["row"]) * conf.field_adjustment.dy + conf.field_adjustment.y,
|
||||
int(field["column"]) * conf.field_adjustment.dx
|
||||
+ conf.field_adjustment.x
|
||||
+ conf.field_adjustment.w // 2,
|
||||
int(field["row"]) * conf.field_adjustment.dy
|
||||
+ conf.field_adjustment.y
|
||||
+ conf.field_adjustment.h // 2,
|
||||
)
|
||||
|
||||
|
||||
def parse_action(action: Dict[str, Any], conf: configuration.Configuration):
|
||||
def parse_action(
|
||||
action: Dict[str, Any],
|
||||
conf: configuration.Configuration,
|
||||
goal_values: Dict[str, int],
|
||||
) -> Union[DragAction, ClickAction, WaitAction]:
|
||||
assert len(action) == 1
|
||||
action_name, info = next(iter(action.items()))
|
||||
action_name = action_name.lower()
|
||||
@@ -83,8 +74,9 @@ def parse_action(action: Dict[str, Any], conf: configuration.Configuration):
|
||||
field = _parse_field(info["field_position"], conf)
|
||||
bunker = (
|
||||
int(info["bunker_slot_index"]) * conf.bunker_adjustment.dx
|
||||
+ conf.bunker_adjustment.x,
|
||||
conf.bunker_adjustment.y,
|
||||
+ conf.bunker_adjustment.x
|
||||
+ conf.bunker_adjustment.w // 2,
|
||||
conf.bunker_adjustment.y + conf.bunker_adjustment.h // 2,
|
||||
)
|
||||
if str(info["to_bunker"]).lower() == "true":
|
||||
return DragAction(source=field, destination=bunker)
|
||||
@@ -93,23 +85,50 @@ def parse_action(action: Dict[str, Any], conf: configuration.Configuration):
|
||||
elif action_name == "move":
|
||||
return DragAction(
|
||||
source=_parse_field(info["source"], conf),
|
||||
destination=_parse_field(info["source"], conf),
|
||||
destination=_parse_field(info["destination"], conf),
|
||||
)
|
||||
elif action_name == "dragonkill":
|
||||
return ClickAction()
|
||||
dragon_sequence = [SpecialCard.Zhong, SpecialCard.Fa, SpecialCard.Bai]
|
||||
dragon_name_map = {
|
||||
"zhong": SpecialCard.Zhong,
|
||||
"fa": SpecialCard.Fa,
|
||||
"bai": SpecialCard.Bai,
|
||||
}
|
||||
card_type = dragon_name_map[info["card"].lower()]
|
||||
dragon_id = dragon_sequence.index(card_type)
|
||||
return ClickAction(
|
||||
destination=(
|
||||
conf.special_button_adjustment.x
|
||||
+ conf.special_button_adjustment.w // 2,
|
||||
conf.special_button_adjustment.y
|
||||
+ dragon_id * conf.special_button_adjustment.dy
|
||||
+ conf.special_button_adjustment.h // 2,
|
||||
)
|
||||
)
|
||||
elif action_name == "goal":
|
||||
obvious = (
|
||||
goal_values[info["card"]["suit"].lower()] <= min(goal_values.values()) + 1
|
||||
)
|
||||
assert (goal_values[info["card"]["suit"].lower()] == 0) or (
|
||||
goal_values[info["card"]["suit"].lower()] + 1 == info["card"]["value"]
|
||||
)
|
||||
goal_values[info["card"]["suit"].lower()] = info["card"]["value"]
|
||||
if obvious:
|
||||
return WaitAction()
|
||||
goal = (
|
||||
int(info["goal_slot_index"]) * conf.goal_adjustment.dx
|
||||
+ conf.goal_adjustment.x,
|
||||
conf.goal_adjustment.y,
|
||||
+ conf.goal_adjustment.x
|
||||
+ conf.goal_adjustment.w // 2,
|
||||
conf.goal_adjustment.y + conf.goal_adjustment.h // 2,
|
||||
)
|
||||
if "Field" in info["source"]:
|
||||
source = _parse_field(info["source"]["Field"], conf)
|
||||
else:
|
||||
source = (
|
||||
int(info["source"]["Bunker"]["slot_index"]) * conf.bunker_adjustment.dx
|
||||
+ conf.bunker_adjustment.x,
|
||||
conf.bunker_adjustment.y,
|
||||
+ conf.bunker_adjustment.x
|
||||
+ conf.bunker_adjustment.w // 2,
|
||||
conf.bunker_adjustment.y + conf.bunker_adjustment.h // 2,
|
||||
)
|
||||
return DragAction(source=source, destination=goal)
|
||||
elif action_name == "huakill":
|
||||
@@ -121,13 +140,15 @@ def handle_actions(
|
||||
offset: Tuple[int, int],
|
||||
conf: configuration.Configuration,
|
||||
) -> None:
|
||||
automatic_count = 0
|
||||
for action in actions:
|
||||
print(action)
|
||||
if isinstance(action, board_actions.HuaKillAction):
|
||||
automatic_count += 1
|
||||
else:
|
||||
time.sleep(0.5 * automatic_count)
|
||||
automatic_count = 0
|
||||
handle_action(action, offset, conf)
|
||||
time.sleep(0.5 * automatic_count)
|
||||
goal_values = {"red": 0, "black": 0, "green": 0}
|
||||
action_tuples = [
|
||||
(action, parse_action(action, conf, goal_values)) for action in actions
|
||||
]
|
||||
for name, action in action_tuples:
|
||||
print(name)
|
||||
if isinstance(action, DragAction):
|
||||
drag(action.source, action.destination, offset)
|
||||
elif isinstance(action, ClickAction):
|
||||
click(action.destination, offset)
|
||||
elif isinstance(action, WaitAction):
|
||||
time.sleep(2)
|
||||
|
||||
@@ -42,7 +42,7 @@ def solve(conf: configuration.Configuration) -> None:
|
||||
board = parse_start_board(image, conf)
|
||||
assert board.check_correct()
|
||||
actions = extern_solve(board)
|
||||
assert 0
|
||||
print(actions)
|
||||
print(f"Solved in {len(actions)} steps")
|
||||
clicker.handle_actions(actions, OFFSET, conf)
|
||||
print("Solved")
|
||||
|
||||
@@ -75,6 +75,10 @@ def main() -> None:
|
||||
conf.hua_adjustment = adjustment.adjust_squares(
|
||||
image, count_x=1, count_y=1, adjustment=copy.deepcopy(conf.hua_adjustment)
|
||||
)
|
||||
print("Special button")
|
||||
conf.special_button_adjustment = adjustment.adjust_squares(
|
||||
image, count_x=1, count_y=3, adjustment=copy.deepcopy(conf.special_button_adjustment)
|
||||
)
|
||||
|
||||
configuration.save(conf, args.config)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user