bot.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. start = time.time()
  46. newstate = state.solve()
  47. end = time.time()
  48. vprint('thought for', round((end - start) * 1000, 1), 'ms')
  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. if state.held == NOBLOCK and any(map(newstate.loops, buf)):
  58. vprint('\rloop detected, wait for a bit...', end='')
  59. time.sleep(0.03)
  60. elif newstate.moves:
  61. vprint('moves:', newstate.keys())
  62. vprint(' score:', newstate.score)
  63. if buf:
  64. vprint('prev score:', buf[-1].score)
  65. vprint()
  66. vprint('target after moves:')
  67. vprint_state(newstate)
  68. press_keys(win, newstate.keys())
  69. #keys_delay = len(newstate.moves) * 2 * KEY_DELAY
  70. #moves_delay = max(0, newstate.delay() - keys_delay)
  71. #vprint('wait for', moves_delay, 'ms')
  72. #time.sleep(moves_delay / 1000)
  73. time.sleep(0.075)
  74. elif state.nrows - 2 <= MAX_SPEED_ROWS:
  75. vprint('no moves, speed up')
  76. press_keys(win, 'l')
  77. time.sleep(0.030)
  78. else:
  79. vprint('no moves')
  80. buf.append(newstate)
  81. except KeyboardInterrupt:
  82. print('interrupted, quitting')