bot.py 3.2 KB

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