Added laptop config
This commit is contained in:
BIN
laptop_conf.zip
Normal file
BIN
laptop_conf.zip
Normal file
Binary file not shown.
@@ -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)
|
||||||
|
|||||||
@@ -18,17 +18,24 @@ 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")
|
||||||
screenshot_file = Path(screenshot_dir) / "screenshot.png"
|
screenshot_file = Path(screenshot_dir) / "screenshot.png"
|
||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user