bot.py 3.1 KB

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