bot.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/env python3
  2. import os
  3. import time
  4. from collections import deque
  5. from itertools import count
  6. from Xlib import error
  7. from strategy import State
  8. from interaction import get_exapunks_window, focus_window, screenshot_board, \
  9. press_keys, listen_keys, KEY_DELAY
  10. MAX_SPEED_ROWS = 3
  11. def save_screenshot(win):
  12. board = screenshot_board(win).convert('RGB')
  13. os.makedirs('screens', exist_ok=True)
  14. for i in count(1):
  15. path = 'screens/board%d.png' % i
  16. if not os.path.exists(path):
  17. print('save screenshot in', path)
  18. board.save(path)
  19. break
  20. if __name__ == '__main__':
  21. import sys
  22. verbose = '-q' not in sys.argv[1:]
  23. try:
  24. win = get_exapunks_window()
  25. focus_window(win)
  26. listen_keys({'s': lambda: save_screenshot(win)})
  27. solutions = deque([], maxlen=3)
  28. def vprint(*args, **kwargs):
  29. if verbose:
  30. print(*args, **kwargs)
  31. def vprint_state(state):
  32. if verbose:
  33. state.print()
  34. while True:
  35. try:
  36. board = screenshot_board(win)
  37. state = State.detect(board)
  38. vprint('\033c', 'parsed:', sep='')
  39. vprint_state(state)
  40. vprint()
  41. start = time.time()
  42. solution = state.solve()
  43. end = time.time()
  44. vprint('thought for', round((end - start) * 1000, 1), 'milliseconds')
  45. except (TypeError, AssertionError):
  46. vprint('\rerror during parsing, wait for a bit...', end='')
  47. time.sleep(0.050)
  48. continue
  49. except error.BadMatch:
  50. vprint('\rEXAPUNKS window lost, wait for a bit...', end='')
  51. time.sleep(0.500)
  52. continue
  53. if len(solutions) == 3 and solution.loops(solutions.popleft()):
  54. vprint('\rloop detected, wait for a bit...', end='')
  55. time.sleep(0.03)
  56. elif solution.moves:
  57. vprint('moves:', solution.keys())
  58. vprint(' score:', solution.score)
  59. if solutions:
  60. vprint('prev score:', solutions[-1].score)
  61. vprint()
  62. vprint('target after moves:')
  63. vprint_state(solution.newstate)
  64. press_keys(win, solution.keys())
  65. keys_delay = len(solution.moves) * 2 * KEY_DELAY
  66. moves_delay = max(0, solution.delay() - keys_delay)
  67. vprint('wait for', moves_delay, 'ms')
  68. time.sleep(moves_delay / 1000)
  69. elif state.nrows() - 2 <= MAX_SPEED_ROWS:
  70. vprint('no moves, speed up')
  71. press_keys(win, 'l')
  72. time.sleep(0.030)
  73. else:
  74. vprint('no moves')
  75. solutions.append(solution)
  76. except KeyboardInterrupt:
  77. print('interrupted, quitting')