def checked_tap(x, y): before = adb.screenshot()[58:101, 10:53] adb.tap(x, y) time.sleep(0.5) after = adb.screenshot()[58:101, 10:53] # if switch disappeared it's ok if not Btn.switch.on_screen(after): return # if ship icon changed -> change it back if img.mean_square(before, after) > 0.001: swap()
def shot(): import cv2 while True: cmd = input("Press enter... ") if cmd == "c": screen = adb.screenshot(False) elif len(cmd) > 0: break else: screen = adb.screenshot() cv2.imwrite(f"screenshots/{time.time()}.png", screen)
def send_girl(): utils.click(121, 159, 27, 24, 3.0) # click first plus for _ in range(3): # swipe to bottom utils.scroll_down() for y in range(3): for x in range(7): utils.click(60 + 84 * x, 60 + 114 * y, 40, 10, 2.0) Btn.commission_select_cancel.click(adb.screenshot()) if not Btn.commission_select_0.on_screen(adb.screenshot()): utils.click(535, 328, 60, 14, 2.0) return adb.back() time.sleep(2.0)
def learn_book(): utils.click(3, 70, 11, 24, 2.0) # open left panel utils.click(200, 207, 41, 10, 2.0) log("Completing books") while Btn.universal_confirm.click(adb.screenshot()): points = find_green() if len(points) == 0: log("ERROR: books not found") break x, y = random.choice(points) utils.click(x, y, 10, 10, 2.0) utils.click(558, 302, 40, 14, 2.0) if Btn.universal_confirm.click(adb.screenshot()): log("Learning started") log("Books done")
def start_lab(): utils.click(3, 70, 11, 24, 2.0) # open left panel while not Btn.technology.on_screen(adb.screenshot()): # open lab utils.click(212, 277, 19, 11, 1.0) utils.click(301, 92, 36, 34, 2.0) # click center if Btn.tech_terminate.on_screen(adb.screenshot()): return utils.click(445, 77, 38, 52, 0.5) # close project for btn in [ Btn.lab_girl, Btn.tech_rigging, Btn.tech_donation, Btn.tech_basic ]: if start_lab_image(btn): break
def get_troop_status(troop_slot): ts_images = { 'gathering': 'ts_gathering.png', 'back': 'ts_back.png', 'enemy_atk': 'ts_enemy_atk.png', 'monster_atk': 'ts_monster_atk.png', 'scouting': 'ts_scouting.png', 'transfer': 'ts_transfer.png', 'reinforce': 'ts_reinforce.png', 'rally': 'ts_rally.png' } result = [] go_kingdom() screenshot = adb.screenshot() for i in range(troop_slot): haystack = screenshot.crop(coords.troop_info_area[i]) for status, img in ts_images.items(): try: im = PIL.Image.open(img_path(img)) if pyautogui.locate(im, haystack, confidence=IMG_MATCH_CONFIDENCE): result.append(status) break except IOError: log('File is missing:', img_path(img)) log('get_troop_status:', result) return result
def left_panel(): utils.click(3, 70, 11, 24, 3.0) # open left panel screen = adb.screenshot() Btn.menu_can.click(screen) # tap can Btn.menu_money.click(screen) # tap money send_commission() log("Commissions done")
def send_best_commission(oil: bool, max_time: int) -> bool: if Btn.commission_0.on_screen(utils.screenshot()): # check if we have fleets return False for _ in range(2): # swipe to bottom utils.scroll_down() time.sleep(2.0) screen = utils.screenshot() # make screenshots screen_hd = adb.screenshot_hd_gray() commission_buttons = img.find_zones(utils.screenshot(), Img.commission, 0.9) best_x, best_y, best_time = -1, -1, max_time for x, y, w, h in commission_buttons: # check oil has_oil = Btn.commission_oil.on_screen(screen[y - 30 : y + 20, x + 129 : x + 400]) if oil != has_oil: continue # check time time_img = screen_hd[y * 3 + 2 * 3 : y * 3 + 13 * 3, x * 3 + 66 * 3 : x * 3 + 107 * 3] time_num = parse_time(time_img) if time_num > max_time: continue # remember best commission if time_num < best_time: best_time = time_num best_x, best_y = x, y if best_time >= max_time: return False # start commission utils.click(best_x, best_y, 45, 13, 3.0) send_girl() Btn.commission_recommend.click(adb.screenshot()) Btn.commission_ready.click(adb.screenshot()) Btn.universal_confirm.click(adb.screenshot()) # check if commission started time.sleep(6.0) has_cancel = Btn.commission_cancel.on_screen(utils.screenshot()) # close commission window utils.click(63, 327, 18, 25, 1.0) return has_cancel
def start_lab_image(btn: Clickable): for _ in range(5): if btn.on_screen(adb.screenshot()): utils.click(301, 92, 36, 34, 2.0) # open project if Btn.tech_terminate.on_screen(adb.screenshot()): return True if Btn.commence.click(adb.screenshot()): if Btn.universal_confirm.click(adb.screenshot()): if Btn.tech_terminate.on_screen(adb.screenshot()): return True else: utils.click(445, 77, 38, 52, 0.5) # close project else: utils.click(445, 77, 38, 52, 0.5) # close project return False utils.click(445, 77, 38, 52, 0.5) # next project utils.click(445, 77, 38, 52, 1.5) # close project return False
def sort_rare(show_rare: bool): utils.click(556, 7, 32, 12, 2.5) # click sort while True: is_rare = adb.screenshot(False)[700, 920, 0] > 160 # check button color if show_rare == is_rare: # check if needed state break utils.click(318, 226, 31, 8, 1.5) # click rare utils.click(372, 318, 55, 7, 2.5) # click confirm
def click_home(): log("Going home...") start_time = time.time() while True: adb.back() time.sleep(0.5) if Btn.menu_quit_cancel.click(adb.screenshot()): return if time.time( ) - start_time > 20.0: # it's taking to long - restart game restart_game() return
def tribute_countdown(): try: img = adb.screenshot().crop(coords.tribute_countdown_box) # img = img.point(lambda i: i < 100 and 255) img = PIL.ImageOps.invert(img) s = img2str(img, config=r'--psm 10') s = s.split(':') second = hms2secs(int(s[0]), int(s[1]), int(s[2])) except (IndexError, ValueError) as e: log('Error occurred in get_tribute_countdown():', e) second = None return second
def swap(): for _ in range(8): before = adb.screenshot() if not Btn.switch.on_screen(before): log("ERROR: Failed to switch, button not on screen") return before = utils.screen_face() # get portrait utils.click(497, 334, 34, 7, 1.0) after = utils.screen_face() if img.mean_square(before, after) > 0.001: return time.sleep(1.5) log("ERROR: Failed to switch, more than 8 try's")
def collect_gift(): adb.tap(coords.alliance) adb.tap(coords.alliance_gift) for _ in range(10): im = adb.screenshot() if im.getpixel( (coords.gift_collect[0], coords.gift_collect[1]))[0] < 30: break adb.tap(coords.gift_collect) for _ in range(5): # try 5 times then abort if coords.back.visible_in(coords.top_window): adb.tap(coords.back[0]) else: break
def enhance_ships(): Btn.sort.click(utils.screenshot()) if adb.screenshot(False)[820, 1144, 2] > 100: utils.click(384, 260, 57, 14, 1.0) Btn.universal_confirm.click(adb.screenshot()) utils.click(49, 53, 63, 56, 3.0) # click first ship Btn.enhance.click(utils.screenshot()) no_enhance = 0 while True: # click enhance if Btn.enhance.on_screen(utils.screenshot()): utils.click(483, 302, 58, 19, 0.5) # press fill button utils.click(567, 302, 58, 19, 2.0) # press enhance button if Btn.universal_confirm.click(adb.screenshot()): # press confirm no_enhance = 0 if Btn.enhance_break.click( utils.screenshot()): # press disassemble utils.click(434, 244, 164, 97, 2.0) # tap to continue else: # something went wrong log("No break button!") else: no_enhance += 1 else: no_enhance += 10 log("No enhance button!") if no_enhance >= 4: # stop if we can't enhance 4 times break adb.swipe( # swipe to next ship random.randint(900, 966), random.randint(501, 558), random.randint(210, 276), random.randint(501, 558)) time.sleep(1.0)
def click_boss() -> str: log(f"Searching boss") for sw in swipes: sw() # swipe in some direction time.sleep(1.0) click_question() screen = utils.screenshot() for boss_pic in [Img.boss, Img.boss2, Img.boss_mini]: boss_point = img.find_best(screen, boss_pic, 0.7) if boss_point is not None: boss_point = boss_point[0] + boss_pic.shape[1] // 2, boss_point[1] + boss_pic.shape[0] // 2 break else: continue x, y = boss_point point = None for _ in range(2): # 2 click try's point = enemy_finder.get_safe_point(x * 3, y * 3) if point is None: continue bx, by = point log(f"Tap boss [{bx}, {by}]") adb.tap(bx, by) if detect_info(): # don't try second click break if wait_for_battle(8.0): # success if switch disappeared return "boss" if point is None: # don't attack ships if boss not clickable continue # failed log(f"Searching ships near boss") ships = [] screen = adb.screenshot(False) for yellow in [True, False]: ships.extend(enemy_finder.find_triangles(screen, yellow)) sort_near(ships, (x * 3, y * 3)) # ships near boss if tap_ships(ships): return "ship" return "none"
def find_green() -> List[Tuple[int, int]]: zone = adb.screenshot(False)[405:783, 290:1631] res = cv2.matchTemplate(zone, Img.book_color, cv2.TM_SQDIFF_NORMED) loc = np.where(res < 0.01) locks = zip(*loc[::-1]) points = [] for x, y in locks: for x1, y1 in points: if abs(x - x1) < 130 and abs(y - y1) < 220: break else: points.append((int(x), int(y))) points = [((x + 290) // 3, (y + 445) // 3) for x, y in points] return points
def gather_super_mine(mode='ordinary'): adb.tap(coords.alliance) adb.tap(coords.territory) adb.tap(coords.super_mine) screenshot = adb.screenshot() for loc in coords.super_mine_coord_locations: im = screenshot.crop(loc) im = PIL.ImageOps.invert(im) result = img2str(im, config=None) if 'Coordinate' in result: x = (loc[0] + loc[2]) // 2 y = (loc[1] + loc[3]) // 2 adb.tap((x, y)) break else: log('No super mine available') return False adb.tap(coords.screen_center) time.sleep(3) if coords.gather.visible_in(coords.mid_window): adb.tap(coords.gather[0]) time.sleep(3) else: log('Troop in super mine already') return False if coords.train.visible_in(coords.mid_window): adb.tap(coords.back[0]) log('No troops for gathering') else: if mode == 'half': adb.tap(coords.half_troop) elif mode == 'ordinary': adb.tap(coords.slot_preferred) adb.tap(coords.ordinary_slot) elif mode == 'superior': adb.tap(coords.slot_preferred) adb.tap(coords.superior_slot) adb.tap(coords.march) wait(coords.castle) log('Go gathering super mine complete') return True
def click_enemy() -> bool: log("Searching ships") for yellow in [True, False]: for sw in swipes: sw() # swipe in some direction time.sleep(1.0) click_question() screen = utils.screenshot() # click buttons ships = enemy_finder.find_triangles(adb.screenshot(False), yellow) player_point = img.find_best(screen, Img.arrow, 0.95) # if we find player go near player if player_point is not None: px, py = player_point sort_near(ships, (px * 3, (py + 70) * 3)) # player 70 pixels bellow arrow if tap_ships(ships): return True return False
def screenshot(self): img = None if (self.device_type == 'emu'): hwnd = self.device_id left = self.device_left top = self.device_top width = self.device_width height = self.device_height win32gui.ShowWindow(hwnd, win32con.SW_SHOW) win32gui.SetForegroundWindow(hwnd) img = np.array( ImageGrab.grab(bbox=(left, top, left + width, top + height))) img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) elif (self.device_type == 'android'): img = adb.screenshot() return Image(img)
def screenshot() -> np.ndarray: time.sleep(0.5) screen = adb.screenshot() if Btn.item.click(screen): # send what we get to discord cv2.imwrite("test.png", screen[140:215, 160:480]) send_img("test.png") return screenshot() if Btn.item2.click(screen): # send what we get to discord cv2.imwrite("test.png", screen[110:250, 160:480]) send_img("test.png") return screenshot() if Btn.no_oil.on_screen(screen): # no oil, stop bot log("No oil!") exit(0) for btn in useless_buttons: if btn.click(screen): return screenshot() return screen
def retire_ships(): def sort_rare(show_rare: bool): utils.click(556, 7, 32, 12, 2.5) # click sort while True: is_rare = adb.screenshot(False)[700, 920, 0] > 160 # check button color if show_rare == is_rare: # check if needed state break utils.click(318, 226, 31, 8, 1.5) # click rare utils.click(372, 318, 55, 7, 2.5) # click confirm utils.click(491, 336, 55, 16, 3.0) # click build if not Btn.retire_button.click(utils.screenshot()): # click retire log("ERROR: Retire not found!") return sort_rare(True) # no ships if Btn.retire_nothing.on_screen(adb.screenshot()): log("Nothing to retire") sort_rare(False) # disable sorting return # select ships for x in range(7): utils.click(54 + x * 82, 56, 54, 50, 0.3) if Btn.universal_confirm.click(adb.screenshot()): # click confirm if Btn.universal_confirm.click(adb.screenshot()): # confirm retire if Btn.item.click(adb.screenshot()): # accept items if Btn.universal_confirm.click( adb.screenshot()): # confirm disassemble if Btn.enhance_break.click( utils.screenshot()): # press disassemble Btn.item.click(adb.screenshot()) # accept items sort_rare(False)
def visible_in(self, area): filename = self.img im = PIL.Image.open(filename) haystack = adb.screenshot().crop(area) return pyautogui.locate(im, haystack, confidence=IMG_MATCH_CONFIDENCE)
def screen_face(): return adb.screenshot()[70:93, 11:51]
def fight(): start_time, last_enemy_time, sub_used = -1.0, -1.0, False last_player = None while True: screen = adb.screenshot(False) frame = frame_recognition.process_frame(screen) # start time counting if frame.auto_button and start_time < 0: start_time = time.time() last_enemy_time = start_time # level finished if not frame.auto_button and check_end(): adb.release() log(f"Level finished in {time.time() - start_time:.2f}s") return # auto mode need? target_auto = True if frame.barrage_button: target_auto = False # change mode if frame.auto_button != target_auto: utils.click(3, 15, 73, 15, 0) adb.release() continue # no control in auto mode if not target_auto or (last_player is None and frame.player is None): continue # launch submarine 5 seconds after start # if time.time() - start_time > 5.0 and not sub_used: # sub_used = True # utils.click(354, 295, 27, 25, 0) # adb.release() # pressing buttons # only if we have enemys or don't have them for 5 seconds if len(frame.enemys) > 0 or time.time() - last_enemy_time > 5.0: last_enemy_time = time.time() if frame.air_button: utils.click(428, 296, 25, 25, 0) adb.release() # player searching if frame.player is None: player_x, player_y = last_player else: player_x, player_y = frame.player last_player = frame.player enemy_y = -1 # pressing torpedoes if frame.torp_button and player_x > 650: utils.click(500, 296, 25, 25, 0) adb.release() # finding best enemy best_x = 100000 if len(frame.bombs) > 0: # bombs always best best_dst = 100000 for x, y in frame.bombs: dst = abs(player_y - y) if dst < best_dst: best_dst = dst enemy_y = y elif len(frame.enemys) > 0: # normal enemys - second target for x, y in frame.enemys: if x < best_x: best_x = x enemy_y = y else: # didn't found enemy, go to center enemy_y = 1080 // 2 # move to enemy y move_y = (enemy_y - player_y) / 300.0 move_x = 0.4 if player_x < 400 or frame.player is None else -0.2 # move forward if no enemys if len(frame.enemys) == 0 or best_x > 1500: move_x = 0.4 if player_x < 850 or frame.player is None else -0.2 # move faster if we have bomb ships or torpedoes ready if len(frame.bombs) > 0 or frame.torp_button: move_y = (enemy_y - player_y) / 100.0 move_x = 0.6 # make a move move_y = float(np.clip(move_y, -1.0, 1.0)) move(move_x, move_y)