From d9b843448417e38eded25c4ed5f958466b42a7a5 Mon Sep 17 00:00:00 2001 From: Thaloria Date: Mon, 17 Oct 2022 17:12:27 +0200 Subject: [PATCH] refactoring to game base class --- game_base_class.py | 222 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 game_base_class.py diff --git a/game_base_class.py b/game_base_class.py new file mode 100644 index 0000000..eea00eb --- /dev/null +++ b/game_base_class.py @@ -0,0 +1,222 @@ +import pydirectinput +import random +import cv2 as cv +import numpy as np +from window_capture import WindowCapture +from vision import Vision +from config_file import UserConfigs + +GREEN = 1 +YELLOW = 2 +RED = 3 +BLUE = 4 +PURPLE = 5 +RAINBOW = 6 +BIGBOMB = 7 +BOMB = 8 +ARROW_DOWN = 9 +ARROW_RIGHT = 10 +ROCK_1 = 11 +ROCK_2 = 12 +ROCK_3 = 13 +BURGER = 14 +PAB1 = 15 +GOLDBAR = 16 +MAGINENT = 21 +CHEMTRANT = 22 +TENESENT = 23 +CIBUTRANT = 24 +ARTISENT = 25 + + +class GameBase: + + def __init__(self, overlay): + self.overlay = overlay + + self.data_value_grid = np.zeros((8, 14), dtype=int) + self.data_coordinates = np.zeros((8, 14), dtype=object) + self.observation = np.zeros((8, 14), dtype=int) + self.data_score_map = np.zeros((8, 14), dtype=int) + + self.explosives = [RAINBOW, ARROW_RIGHT, ARROW_DOWN, BIGBOMB, BOMB] + self.colors = [GREEN, YELLOW, RED, BLUE, MAGINENT, CHEMTRANT, TENESENT, CIBUTRANT, ARTISENT] + + self.next_level = cv.imread("control_elements/next_level.jpg", cv.IMREAD_COLOR) + self.next_level_x = cv.imread("control_elements/next_level_x.jpg", cv.IMREAD_COLOR) + self.reset_board = cv.imread("control_elements/reset_button.jpg", cv.IMREAD_COLOR) + self.reset_confirm = cv.imread("control_elements/reset_confirm.jpg", cv.IMREAD_COLOR) + + self.reset_counter = 0 + + # initialize the user-class + self.config = UserConfigs() + # initialize the StunWindowCapture class + self.capture_window = WindowCapture(None, None, self.config) + # initialize the StunVision class + self.vision_stun = Vision() + + def fill_data_coordinates(self): + # 230 to 2110 = 1883 / 14 = 134.5 + # 60 to 1130 = 1076 / 8 = 134.5 + dim = 134.5 + for e in range(0, 8, 1): + for i in range(0, 14, 1): + self.data_coordinates[e][i] = [i * dim, e * dim, dim, dim] + + def check_for_button_and_execute(self, screen, needle, offset_left=0, offset_down=0): + rectangles = self.vision_stun.find(screen, needle, 0.70, 1) + if len(rectangles) == 0: + return False + point = self.vision_stun.get_click_points(rectangles)[0] + self.dig_point(point[0] + offset_left, point[1] + offset_down, 500) + return True + + def check_for_next_level(self, screen, needle): + offset_left = 230 + offset_down = 58 + rectangles = self.vision_stun.find(screen, needle, 0.70, 1) + if len(rectangles) == 0: + return False + if self.detonate_explosive_when_stuck(self.observation): + return True + point = self.vision_stun.get_click_points(rectangles)[0] + self.dig_point(point[0] + offset_left, point[1] + offset_down, 500) + return True + + def detonate_explosive_when_stuck(self, state): + for e in range(0, 8, 1): + for i in range(0, 14, 1): + for explosive in self.explosives: + if self.local_pos_check(state, e, i, 0, 0, explosive): + src_pt = self.get_click_point(self.data_coordinates[e, i]) + if self.local_pos_checks(state, e, i, 1, 0, self.colors): + dest_pt = self.get_click_point(self.data_coordinates[e + 1, i]) + self.move_tile(src_pt, dest_pt) + return True + elif self.local_pos_checks(state, e, i, 0, 1, self.colors): + dest_pt = self.get_click_point(self.data_coordinates[e, i + 1]) + self.move_tile(src_pt, dest_pt) + return True + elif self.local_pos_checks(state, e, i, -1, 0, self.colors): + dest_pt = self.get_click_point(self.data_coordinates[e - 1, i]) + self.move_tile(src_pt, dest_pt) + return True + elif self.local_pos_checks(state, e, i, 0, -1, self.colors): + dest_pt = self.get_click_point(self.data_coordinates[e, i - 1]) + self.move_tile(src_pt, dest_pt) + return True + else: + continue + return False + + def check_explosives(self, state, e, i): + for explosive in self.explosives: + if self.local_pos_check(state, e, i, 0, 0, explosive): + dest_pt = self.get_click_point(self.data_coordinates[e, i]) + if self.local_pos_checks(state, e, i, 1, 0, self.explosives): + src_pt = self.get_click_point(self.data_coordinates[e + 1, i]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, 0, 1, self.explosives): + src_pt = self.get_click_point(self.data_coordinates[e, i + 1]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, -1, 0, self.explosives): + src_pt = self.get_click_point(self.data_coordinates[e - 1, i]) + self.move_tile(src_pt, dest_pt) + elif self.local_pos_checks(state, e, i, 0, -1, self.explosives): + src_pt = self.get_click_point(self.data_coordinates[e, i - 1]) + self.move_tile(src_pt, dest_pt) + else: + continue + return True + else: + continue + return False + + def is_direction_in_bounce_and_same_color(self, state, loc, color): + x, y = loc + if x <= 7 and x >= 0 and y <= 13 and y >= 0: + if state[x, y] == color: + return 1 + return 0 + + def local_pos_check(self, state, e, i, e_check, i_check, needle): + if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13: + if state[e + e_check, i + i_check] == needle: + return True + else: + return False + + def local_pos_checks(self, state, e, i, e_check, i_check, needles): + if e + e_check >= 0 and e + e_check <= 7 and i + i_check >= 0 and i + i_check <= 13: + for needle in needles: + if state[e + e_check, i + i_check] == needle: + return True + else: + continue + return False + + def get_click_point(self, rectangle): + # Loop over all the rectangles + x, y, w, h = rectangle + # Determine the center position + center_x = x + int(w / 2) + center_y = y + int(h / 2) + # Save the points + return int(center_x), int(center_y) + + def move_tile(self, point_source, point_dest): + offset_left = 230 + offset_down = 58 + pydirectinput.moveTo(point_source[0] + offset_left, point_source[1] + offset_down) + # pydirectinput.moveTo(0,0) + pydirectinput.mouseDown() + w = random.randint(25, 50) + cv.waitKey(100 + w) + pydirectinput.moveTo(point_dest[0] + offset_left, point_dest[1] + offset_down) + pydirectinput.mouseUp() + cv.waitKey(400 + w) + + def check_for_button_and_click_it(self, button_url): + screenshot = self.capture_window.get_screenshot() + # gray = cv.cvtColor(screenshot, cv.COLOR_BGR2GRAY) + # thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1] + # gray_needle = cv.cvtColor(cv.imread(button_url, cv.IMREAD_UNCHANGED), cv.COLOR_BGR2GRAY) + # thresh_needle = cv.threshold(gray_needle, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)[1] + needle = cv.imread(button_url, cv.IMREAD_UNCHANGED) + # rectangles = self.vision_stun.find(thresh, thresh_needle, 0.4, 1) + rectangles = self.vision_stun.find(screenshot, needle, 0.7, 1) + + if len(rectangles) == 1: + pointis = self.vision_stun.get_click_points(rectangles) + for pointi in pointis: + self.dig_point(pointi[0], pointi[1], 150) + + def dig_point(self, point1, point2, dig_time): + pydirectinput.moveTo(point1, point2) + cv.waitKey(dig_time) + pydirectinput.mouseDown() + w = random.randint(50, 100) + cv.waitKey(w) + pydirectinput.mouseUp() + + def move_to(self, x, y): + point_src = (1113, 598) + pydirectinput.moveTo(point_src[0], point_src[1]) + pydirectinput.mouseDown() + w = random.randint(1, 100) + cv.waitKey(150 + w) + pydirectinput.moveTo(x, y) + pydirectinput.mouseUp() + cv.waitKey(500 + w) + + def point_in_rect(self, point): + for e in range(0, 8, 1): + for i in range(0, 14, 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