bot.py 3.4 KB

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