Guest User

Untitled

a guest
Jan 4th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.72 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import math
  4. import os
  5. import subprocess
  6. import time
  7. import matplotlib.animation as animation
  8. import matplotlib.pyplot as plt
  9. import numpy as np
  10. import skimage
  11. from PIL import Image
  12. ADB_PATH = r'C:\adb\adb.exe'
  13. PWD = os.path.dirname(__file__)
  14. si = subprocess.STARTUPINFO()
  15. si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
  16. #si.wShowWindow = subprocess.SW_HIDE # default
  17. class JUMP():
  18. def __init__(self):
  19. self.img = None
  20. self.update_data()
  21. self.update = True
  22. self.index = 0
  23. self.cor = [0, 0]
  24. self.update = True
  25. self.click_count = 0
  26. self.jump_speed = 1.393
  27. self.cor = []
  28. def start(self):
  29. self.fig = plt.figure()
  30. self.im = plt.imshow(self.img, animated=True)
  31. self.fig.canvas.mpl_connect('button_press_event', self.onClick)
  32. self.ani = animation.FuncAnimation(
  33. self.fig, self.updatefig, interval=50, blit=True)
  34. plt.show()
  35. def start_auto(self):
  36. self.fig = plt.figure()
  37. self.ax_im = plt.imshow(self.img)
  38. self.ax_line = plt.plot([0,0],[0,0])
  39. plt.show(block=False)
  40. while True:
  41. # 获取棋子和 board 的位置
  42. piece_x, piece_y, board_x, board_y = self.find_piece_and_board(
  43. self.img)
  44. ts = int(time.time())
  45. print(ts, piece_x, piece_y, board_x, board_y)
  46. self.ax_im.set_array(self.update_data())
  47. plt.plot([piece_x, piece_y], [board_x, board_y])
  48. plt.draw()
  49. plt.pause(0.001)
  50. self.jump(math.sqrt(abs(board_x - piece_x) **
  51. 2 + abs(board_y - piece_y) ** 2))
  52. time.sleep(1.5) # 为了保证截图的时候应落稳了,多延迟一会儿
  53. def pull_image(self):
  54. subprocess.call(
  55. f'{ADB_PATH} shell screencap -p /sdcard/screen.png', startupinfo=si)
  56. subprocess.call(f'{ADB_PATH} pull /sdcard/screen.png', startupinfo=si)
  57. subprocess.call(
  58. f'{ADB_PATH} shell rm /sdcard/screen.png', startupinfo=si)
  59. def read_image(self, delete=True):
  60. self.pull_image()
  61. img_path = os.path.join(PWD, 'screen.png')
  62. with Image.open(img_path, mode='r') as img_file:
  63. img = np.array(img_file)
  64. if delete == True:
  65. subprocess.call(f'rm -f {img_path}', startupinfo=si)
  66. return img
  67. def jump(self, distance):
  68. press_time = distance * self.jump_speed
  69. press_time = max(press_time, 200)
  70. press_time = int(press_time)
  71. cmd = f'{ADB_PATH} shell input swipe 500 1600 500 1601 ' + \
  72. str(press_time)
  73. print(cmd)
  74. subprocess.call(cmd, startupinfo=si)
  75. def update_data(self):
  76. self.img = self.read_image()
  77. return self.img
  78. def updatefig(self, *args):
  79. if self.update:
  80. time.sleep(1)
  81. self.im.set_array(self.update_data())
  82. self.update = False
  83. return self.im,
  84. def find_piece_and_board(self, img):
  85. im = Image.fromarray(img)
  86. w, h = im.size
  87. piece_x_sum = 0
  88. piece_x_c = 0
  89. piece_y_max = 0
  90. board_x = 0
  91. board_y = 0
  92. for i in range(h):
  93. for j in range(w):
  94. pixel = im.getpixel((j, i))
  95. # 根据棋子的最低行的颜色判断,找最后一行那些点的平均值
  96. if (50 < pixel[0] < 60) and (53 < pixel[1] < 63) and (95 < pixel[2] < 110):
  97. piece_x_sum += j
  98. piece_x_c += 1
  99. piece_y_max = max(i, piece_y_max)
  100. if not all((piece_x_sum, piece_x_c)):
  101. return 0, 0, 0, 0
  102. piece_x = piece_x_sum / piece_x_c
  103. # TODO: 大小根据截图的 size 来计算
  104. piece_y = piece_y_max - 20 # 上移棋子底盘高度的一半
  105. for i in range(h):
  106. if i < 300:
  107. continue
  108. last_pixel = im.getpixel((0, i))
  109. if board_x or board_y:
  110. break
  111. board_x_sum = 0
  112. board_x_c = 0
  113. for j in range(w):
  114. pixel = im.getpixel((j, i))
  115. # 修掉脑袋比下一个小格子还高的情况的 bug
  116. if abs(j - piece_x) < 70:
  117. continue
  118. # 修掉圆顶的时候一条线导致的小 bug
  119. if abs(pixel[0] - last_pixel[0]) + abs(pixel[1] - last_pixel[1]) + abs(pixel[2] - last_pixel[2]) > 10:
  120. board_x_sum += j
  121. board_x_c += 1
  122. if board_x_sum:
  123. board_x = board_x_sum / board_x_c
  124. # 按实际的角度来算,找到接近下一个 board 中心的坐标
  125. board_y = piece_y + abs(board_x - piece_x) * \
  126. abs(1122 - 831) / abs(813 - 310)
  127. if not all((board_x, board_y)):
  128. return 0, 0, 0, 0
  129. return piece_x, piece_y, board_x, board_y
  130. def onClick(self, event):
  131. # next screenshot
  132. self.ix, self.iy = event.xdata, event.ydata
  133. self.coords = []
  134. self.coords.append((self.ix, self.iy))
  135. piece_x, piece_y, board_x, board_y = self.find_piece_and_board(
  136. self.img)
  137. print('now = ', self.coords)
  138. self.cor.append(self.coords)
  139. cor1 = self.cor.pop()
  140. cor2 = [(piece_x, piece_y)]
  141. distance = (cor1[0][0] - cor2[0][0])**2 + \
  142. (cor1[0][1] - cor2[0][1])**2
  143. distance = distance ** 0.5
  144. print('distance = ', distance)
  145. self.jump(distance)
  146. self.update = True
  147. def main(auto=False):
  148. jump = JUMP()
  149. if auto:
  150. jump.start_auto()
  151. else:
  152. jump.start()
  153. if __name__ == "__main__":
  154. import sys
  155. auto = False
  156. if len(sys.argv) != 1:
  157. auto = True
  158. main(auto)
Add Comment
Please, Sign In to add comment