#!/usr/bin/env python3 import os import time from collections import deque from itertools import count from Xlib import error from strategy import State from interaction import get_exapunks_window, focus_window, screenshot_board, \ press_keys, listen_keys, KEY_DELAY MAX_SPEED_ROWS = 3 def save_screenshot(win): board = screenshot_board(win).convert('RGB') os.makedirs('screens', exist_ok=True) for i in count(1): path = 'screens/board%d.png' % i if not os.path.exists(path): print('save screenshot in', path) board.save(path) break if __name__ == '__main__': import sys verbose = '-q' not in sys.argv[1:] try: win = get_exapunks_window() focus_window(win) listen_keys({'s': lambda: save_screenshot(win)}) solutions = deque([], maxlen=3) def vprint(*args, **kwargs): if verbose: print(*args, **kwargs) def vprint_state(state): if verbose: state.print() while True: try: board = screenshot_board(win) state = State.detect(board) vprint('\033c', 'parsed:', sep='') vprint_state(state) vprint() start = time.time() solution = state.solve() end = time.time() vprint('thought for', round((end - start) * 1000, 1), 'milliseconds') except (TypeError, AssertionError): vprint('\rerror during parsing, wait for a bit...', end='') time.sleep(0.050) continue except error.BadMatch: vprint('\rEXAPUNKS window lost, wait for a bit...', end='') time.sleep(0.500) continue if len(solutions) == 3 and solution.loops(solutions.popleft()): vprint('\rloop detected, wait for a bit...', end='') time.sleep(0.03) elif solution.moves: vprint('moves:', solution.keys()) vprint(' score:', solution.score) if solutions: vprint('prev score:', solutions[-1].score) vprint() vprint('target after moves:') vprint_state(solution.newstate) press_keys(win, solution.keys()) keys_delay = len(solution.moves) * 2 * KEY_DELAY moves_delay = max(0, solution.delay() - keys_delay) vprint('wait for', moves_delay, 'ms') time.sleep(moves_delay / 1000) elif state.nrows() - 2 <= MAX_SPEED_ROWS: vprint('no moves, speed up') press_keys(win, 'l') time.sleep(0.030) else: vprint('no moves') solutions.append(solution) except KeyboardInterrupt: print('interrupted, quitting')