diff --git a/combined_user_interface.py b/combined_user_interface.py index 27414d6..aa643fb 100644 --- a/combined_user_interface.py +++ b/combined_user_interface.py @@ -32,19 +32,20 @@ class PrimaryOverlay(threading.Thread): self.Emitter_Box = ttk.Combobox self.RadioButtons = dict - self.RadioButtonNames = ["Equip", "Crops", "Farm", "Magic", "Craft", "Mine"] + self.RadioButtonNames = ["Equip", "Crops", "Farm", "Magic", "Craft", "Mine", "Fruit"] self.RadioButton1 = tk.Radiobutton self.RadioButton2 = tk.Radiobutton self.RadioButton3 = tk.Radiobutton self.RadioButton4 = tk.Radiobutton self.RadioButton5 = tk.Radiobutton self.RadioButton6 = tk.Radiobutton + self.RadioButton7 = tk.Radiobutton self.StartButton = tk.Button self.StopButton = tk.Button self.PauseButton = tk.Button self.QuitButton = tk.Button - self.TkPosition = '133x305+60+600' + self.TkPosition = '133x329+60+600' self.setDaemon(True) self.StatusLabel = tk.Label @@ -72,7 +73,7 @@ class PrimaryOverlay(threading.Thread): self.rb_int = tk.IntVar(self.root, value=1) self.RadioButtons = dict() # var = tk.IntVar(value=1) - for i in range(1, 7): + for i in range(1, 8): self.RadioButtons[i] = tk.Radiobutton(self.rb_frame, text=self.RadioButtonNames[i - 1], variable=self.rb_int, value=i, command=self.radio_button_callback) @@ -276,6 +277,17 @@ class PrimaryOverlay(threading.Thread): self.SpawnLabel.configure(text="") self.EnergyLabel.configure(text="Runs:") self.show_mining_overlay() + elif self.rb_int.get() == 7: + self.EnergyEntry.configure(state=tk.DISABLED) + self.energy_use.set('') + self.SpawnEntry.configure(state=tk.DISABLED) + self.spawn_use.set('') + self.Emitter_Box.configure(state=tk.DISABLED) + self.emitter_use.set('') + self.EmitterLabel.configure(text="") + self.SpawnLabel.configure(text="") + self.EnergyLabel.configure(text="") + self.hide_mining_overlay() def get_run_mode(self): return self.run_mode diff --git a/control_elements/ok_button.jpg b/control_elements/ok_button.jpg new file mode 100644 index 0000000..d78f586 Binary files /dev/null and b/control_elements/ok_button.jpg differ diff --git a/fruit.py b/fruit.py new file mode 100644 index 0000000..1543066 --- /dev/null +++ b/fruit.py @@ -0,0 +1,137 @@ +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.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): + # 540 to 1870 = 1330 / 11 = 121 + # 180 to 1030 = 1076 / 8 = 121.4 + dim = 121.2 + 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: + 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 = cv.imread("field_farm.jpg") + screenshot = screenshot[180:1030, 540:1870] + # 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, 540, 180): + cv.waitKey(500) + screenshot = self.capture_window.get_screenshot() + screenshot = screenshot[180:1030, 540:1870] + if self.check_for_button_and_execute(screenshot, self.reset_board, 540, 180): + cv.waitKey(500) + screenshot = self.capture_window.get_screenshot() + screenshot = screenshot[180:1030, 540:1870] + if self.check_for_button_and_execute(screenshot, self.reset_confirm, 540, 180): + cv.waitKey(500) + screenshot = self.capture_window.get_screenshot() + screenshot = screenshot[180:1030, 540:1870] + + # 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 find_patterns_and_valid_moves(self, state): + for e in range(0, 8, 1): + for i in range(0, 14, 1): + if self.check_pairs(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(self, state, e, i, color): + try: + # + if state[e, i] == color and state[e + 1, i] == color: + click_pt = self.get_click_point(self.data_coordinates[e, i]) + self.dig_point(click_pt[0], click_pt[1], 100) + return True + elif state[e, i] == color and state[e, i + 1] == color: + click_pt = self.get_click_point(self.data_coordinates[e, i]) + self.dig_point(click_pt[0], click_pt[1], 100) + return True + return False + except: + return False \ No newline at end of file diff --git a/fruit/blue.jpg b/fruit/blue.jpg new file mode 100644 index 0000000..3ca0cd0 Binary files /dev/null and b/fruit/blue.jpg differ diff --git a/fruit/green.jpg b/fruit/green.jpg new file mode 100644 index 0000000..80b969d Binary files /dev/null and b/fruit/green.jpg differ diff --git a/fruit/orange.jpg b/fruit/orange.jpg new file mode 100644 index 0000000..0391ec4 Binary files /dev/null and b/fruit/orange.jpg differ diff --git a/fruit/red.jpg b/fruit/red.jpg new file mode 100644 index 0000000..9d41cb1 Binary files /dev/null and b/fruit/red.jpg differ diff --git a/fruit/yellow.jpg b/fruit/yellow.jpg new file mode 100644 index 0000000..5e7f188 Binary files /dev/null and b/fruit/yellow.jpg differ diff --git a/game_base_class.py b/game_base_class.py index 9071827..4e904cb 100644 --- a/game_base_class.py +++ b/game_base_class.py @@ -47,6 +47,7 @@ class GameBase: 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.ok_button = cv.imread("control_elements/ok_button.jpg", cv.IMREAD_COLOR) self.reset_counter = 0