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 shenzhen_solitaire.board import SpecialCard
|
||||
|
||||
DRAG_DURATION = 0.4
|
||||
CLICK_DURATION = 0.5
|
||||
DRAG_DURATION = 0.2
|
||||
CLICK_DURATION = 1
|
||||
DRAGON_WAIT = 1
|
||||
HUA_WAIT = 1
|
||||
GOAL_WAIT = 0.4
|
||||
|
||||
|
||||
def drag(
|
||||
src: Tuple[int, int], dst: Tuple[int, int], offset: Tuple[int, int] = (0, 0)
|
||||
) -> None:
|
||||
|
||||
time.sleep(DRAG_DURATION / 3)
|
||||
pyautogui.moveTo(x=src[0] + offset[0], y=src[1] + offset[1])
|
||||
pyautogui.dragTo(
|
||||
x=dst[0] + offset[0],
|
||||
y=dst[1] + offset[1],
|
||||
duration=DRAG_DURATION,
|
||||
tween=lambda x: 0 if x < 0.5 else 1,
|
||||
pyautogui.mouseDown()
|
||||
time.sleep(DRAG_DURATION / 3)
|
||||
pyautogui.moveTo(
|
||||
x=dst[0] + offset[0], y=dst[1] + offset[1],
|
||||
)
|
||||
pyautogui.mouseUp()
|
||||
time.sleep(DRAG_DURATION / 3)
|
||||
|
||||
|
||||
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.mouseDown()
|
||||
time.sleep(CLICK_DURATION)
|
||||
time.sleep(CLICK_DURATION / 3)
|
||||
pyautogui.mouseUp()
|
||||
time.sleep(CLICK_DURATION / 3)
|
||||
time.sleep(DRAGON_WAIT)
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -44,9 +52,9 @@ class DragAction:
|
||||
class ClickAction:
|
||||
destination: Tuple[int, int]
|
||||
|
||||
|
||||
@dataclass
|
||||
class WaitAction:
|
||||
pass
|
||||
duration: float
|
||||
|
||||
|
||||
def _parse_field(
|
||||
@@ -106,15 +114,24 @@ def parse_action(
|
||||
)
|
||||
)
|
||||
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"]
|
||||
|
||||
current_value = goal_values[info["card"]["suit"].lower()]
|
||||
proposed_value = info["card"]["value"]
|
||||
|
||||
assert (current_value == 0) or (current_value + 1 == proposed_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:
|
||||
return WaitAction()
|
||||
return WaitAction(duration=GOAL_WAIT)
|
||||
|
||||
goal = (
|
||||
int(info["goal_slot_index"]) * conf.goal_adjustment.dx
|
||||
+ conf.goal_adjustment.x
|
||||
@@ -132,7 +149,9 @@ def parse_action(
|
||||
)
|
||||
return DragAction(source=source, destination=goal)
|
||||
elif action_name == "huakill":
|
||||
return WaitAction()
|
||||
return WaitAction(duration=HUA_WAIT)
|
||||
else:
|
||||
assert 0
|
||||
|
||||
|
||||
def handle_actions(
|
||||
@@ -141,9 +160,9 @@ def handle_actions(
|
||||
conf: configuration.Configuration,
|
||||
) -> None:
|
||||
goal_values = {"red": 0, "black": 0, "green": 0}
|
||||
action_tuples = [
|
||||
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):
|
||||
@@ -151,4 +170,4 @@ def handle_actions(
|
||||
elif isinstance(action, ClickAction):
|
||||
click(action.destination, offset)
|
||||
elif isinstance(action, WaitAction):
|
||||
time.sleep(2)
|
||||
time.sleep(action.duration)
|
||||
|
||||
@@ -18,16 +18,23 @@ from shenzhen_solitaire.card_detection.board_parser import parse_start_board
|
||||
OFFSET = (0, 0)
|
||||
# SIZE = (2560, 1440)
|
||||
SIZE = (1366, 768)
|
||||
NEW_BUTTON = (1900, 1100)
|
||||
# NEW_BUTTON = (1900, 1100)
|
||||
NEW_BUTTON = (1340, 750)
|
||||
|
||||
SAVE_UNSOLVED = False
|
||||
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]]:
|
||||
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)
|
||||
|
||||
|
||||
def take_screenshot():
|
||||
with tempfile.TemporaryDirectory(prefix="shenzhen_solitaire") as screenshot_dir:
|
||||
print("Taking screenshot")
|
||||
@@ -37,6 +44,7 @@ def take_screenshot() :
|
||||
image = cv2.imread(str(screenshot_file))
|
||||
return image
|
||||
|
||||
|
||||
def solve(conf: configuration.Configuration) -> None:
|
||||
image = take_screenshot()
|
||||
board = parse_start_board(image, conf)
|
||||
@@ -52,16 +60,20 @@ def solve(conf: configuration.Configuration) -> None:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Solve board"
|
||||
parser = argparse.ArgumentParser(description="Solve board")
|
||||
parser.add_argument(
|
||||
"config_path", type=str, help="Config path",
|
||||
)
|
||||
parser.add_argument(
|
||||
"config_path",
|
||||
type=str,
|
||||
help="Config path",
|
||||
"--no-failsafe",
|
||||
dest="no_failsafe",
|
||||
action="store_false",
|
||||
help="Enable 0.1 second delay between all actions to allow user to interrupt",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.no_failsafe:
|
||||
pyautogui.PAUSE = 0
|
||||
time.sleep(3)
|
||||
conf = configuration.load(args.config_path)
|
||||
while True:
|
||||
|
||||
Reference in New Issue
Block a user