import cv2 as cv import numpy as np from utils import mse from game_base_class import GameBase GREEN = 1 YELLOW = 2 RED = 3 BLUE = 4 ORANGE = 5 class Fruit(GameBase): def __init__(self, overlay): super().__init__(overlay) self.data_coordinates = np.zeros((7, 11), dtype=object) self.observation = np.zeros((7, 11), dtype=int) self.colors = [GREEN, YELLOW, RED, BLUE, ORANGE] self.offset_left = 553 self.offset_down = 188 self.fill_data_coordinates() self.needles = {GREEN: cv.imread("fruit/green.jpg", cv.IMREAD_COLOR), YELLOW: cv.imread("fruit/yellow.jpg", cv.IMREAD_COLOR), BLUE: cv.imread("fruit/blue.jpg", cv.IMREAD_COLOR), RED: cv.imread("fruit/red.jpg", cv.IMREAD_COLOR), ORANGE: cv.imread("fruit/orange.jpg", cv.IMREAD_COLOR) } def fill_data_coordinates(self): # 553 to 1861 = 1330 / 11 = 119 # 188 to 1022 = 1076 / 7 = 119 dim = 119 for e in range(0, 7, 1): for i in range(0, 11, 1): self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim] def assess_playfield_and_make_move(self): new_observation, new_screenshot = self.get_current_board_state() # wrong movement detection # last board state is same as actual if mse(new_observation, self.observation) == 0.0: # no movement detected -> blow explosives or reset self.reset_counter += 1 if self.reset_counter == 1: pass elif self.reset_counter == 2: pass elif self.reset_counter >= 3: screenshot = self.capture_window.get_screenshot() if self.check_for_button_and_execute(screenshot, self.reset_board): cv.waitKey(500) screenshot = self.capture_window.get_screenshot() if self.check_for_button_and_execute(screenshot, self.reset_confirm): cv.waitKey(500) self.reset_counter = 0 return else: return self.find_patterns_and_valid_moves(new_observation) self.observation = new_observation return new_observation def get_current_board_state(self): # get an updated image of the game screenshot = self.capture_window.get_screenshot() #screenshot = screenshot[900:1030, 540:1870] # screenshot = cv.imread("field_farm.jpg") # gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY) # thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1] if self.check_for_button_and_execute(screenshot, self.ok_button): cv.waitKey(500) screenshot = self.capture_window.get_screenshot() screenshot = screenshot[188:1210, 390:2000] # 553 to 1861 = 1330 / 11 = 119 # 188 to 1022 #cv.imshow("screenshot", screenshot) #cv.waitKey(150) # continue data_coords = np.zeros((7, 11), dtype=object) # field = Field() for needle_key in self.needles.keys(): # gray_needle = cv.cvtColor(self.needles[needle_key], cv.COLOR_BGR2GRAY) # thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1] rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.74, 56) if len(rectangles) == 0: continue points = self.vision_stun.get_click_points(rectangles) for point in points: x, y = self.point_in_rect(point) if x is not None and y is not None: data_coords[x][y] = int(needle_key) # self.change_value(x, y, int(needle_key)) # print(field.data_value_grid) # cv.circle(screenshot, points[0], 7, (0, 255, 0), -1) # output_image = vision_stun.draw_rectangles(screenshot, rectangles) # cv.imshow("output_image", output_image) # cv.waitKey(150) return data_coords, screenshot def point_in_rect(self, point): for e in range(0, 7, 1): for i in range(0, 11, 1): x1, y1, w, h = self.data_coordinates[e][i] x2, y2 = x1 + w, y1 + h x, y = point if x1 < x and x < x2: if y1 < y and y < y2: return e, i return None, None def find_patterns_and_valid_moves(self, state): for e in range(0, 7, 1): for i in range(0, 11, 1): if state[e, i] in self.colors: #color in self.colors: if self.check_pairs_h(state, e, i): return if self.check_pairs_v(state, e, i): return if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': return if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': return def check_pairs_h(self, state, e, i): try: # if state[e, i] == state[e + 1, i]: click_pt = self.get_click_point(self.data_coordinates[e, i]) self.dig_point(click_pt[0] + self.offset_left, click_pt[1] + self.offset_down, 100) return True return False except: return False def check_pairs_v(self, state, e, i): try: # if state[e, i] == state[e, i + 1]: click_pt = self.get_click_point(self.data_coordinates[e, i]) self.dig_point(click_pt[0] + self.offset_left, click_pt[1] + self.offset_down, 100) return True return False except: return False