| | import pyautogui
|
| | import chess
|
| | import time
|
| | import math
|
| |
|
| | class MirrorHandler:
|
| | def __init__(self):
|
| |
|
| | pyautogui.FAILSAFE = True
|
| | pyautogui.PAUSE = 0.1
|
| |
|
| | def execute_move(self, move, region, is_flipped=False):
|
| | """
|
| | Execute a chess move on the screen region using mouse drag.
|
| |
|
| | Args:
|
| | move (chess.Move): The move to execute.
|
| | region (dict): {'left', 'top', 'width', 'height'} of the target board.
|
| | is_flipped (bool): If True, board is viewed from Black's perspective (rank 1 at top).
|
| | """
|
| | if not region or not move:
|
| | return
|
| |
|
| | start_sq = move.from_square
|
| | end_sq = move.to_square
|
| |
|
| |
|
| | start_x, start_y = self._get_square_center(start_sq, region, is_flipped)
|
| | end_x, end_y = self._get_square_center(end_sq, region, is_flipped)
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | pyautogui.moveTo(start_x, start_y)
|
| |
|
| | pyautogui.dragTo(end_x, end_y, button='left')
|
| |
|
| |
|
| | if move.promotion:
|
| |
|
| |
|
| |
|
| |
|
| | time.sleep(0.1)
|
| | pyautogui.click()
|
| |
|
| | def _get_square_center(self, square, region, is_flipped):
|
| | """
|
| | Calculate center x, y for a given square index (0-63).
|
| | """
|
| | file_idx = chess.square_file(square)
|
| | rank_idx = chess.square_rank(square)
|
| |
|
| | if is_flipped:
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | col = 7 - file_idx
|
| | row = rank_idx
|
| | else:
|
| |
|
| |
|
| | col = file_idx
|
| | row = 7 - rank_idx
|
| |
|
| | sq_w = region['width'] / 8
|
| | sq_h = region['height'] / 8
|
| |
|
| | center_x = region['left'] + (col * sq_w) + (sq_w / 2)
|
| | center_y = region['top'] + (row * sq_h) + (sq_h / 2)
|
| |
|
| | return center_x, center_y
|
| |
|