diff --git a/combined_bot_main.py b/combined_bot_main.py index c8d4f18..f947034 100644 --- a/combined_bot_main.py +++ b/combined_bot_main.py @@ -7,6 +7,7 @@ from farm import Farm from magic import Magic from craft import Craft from mine import Mine +from sodoku import Sodoku from fruit import Fruit @@ -55,7 +56,7 @@ def run(): mine = Mine(overlay) mine.execute_main_loop() elif overlay.rb_int.get() == 7: - fruit = Fruit(overlay) + fruit = Sodoku(overlay) fruit.execute_main_loop() diff --git a/sodoku.py b/sodoku.py new file mode 100644 index 0000000..12f80e2 --- /dev/null +++ b/sodoku.py @@ -0,0 +1,219 @@ +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 Sodoku(GameBase): + + def __init__(self, overlay): + super().__init__(overlay) + + self.data_coordinates = np.zeros((9, 9), dtype=object) + self.observation = np.zeros((9, 9), dtype=int) + + self.colors = [1, 2, 3, 4, 5, 6, 7, 8, 9] + + self.offset_left = 860 + self.offset_down = 180 + + self.fill_data_coordinates() + + self.needles = {1: cv.imread("sodoku/1.jpg", cv.IMREAD_COLOR), + 2: cv.imread("sodoku/2.jpg", cv.IMREAD_COLOR), + 3: cv.imread("sodoku/3.jpg", cv.IMREAD_COLOR), + 4: cv.imread("sodoku/4.jpg", cv.IMREAD_COLOR), + 5: cv.imread("sodoku/5.jpg", cv.IMREAD_COLOR), + 6: cv.imread("sodoku/6.jpg", cv.IMREAD_COLOR), + 7: cv.imread("sodoku/7.jpg", cv.IMREAD_COLOR), + 8: cv.imread("sodoku/8.jpg", cv.IMREAD_COLOR), + 9: cv.imread("sodoku/9.jpg", cv.IMREAD_COLOR) + } + + def fill_data_coordinates(self): + # 860 to 1690 = 830 - 40 / 9 = 88 + # 180 to 1010 = 830 - 40 / 9 = 88 + # spacing 2 * 20 + dim = 88 + e_spacing = 0 + i_spacing = 0 + for e in range(0, 9, 1): + if e >= 4: + e_spacing = 20 + elif e >= 7: + e_spacing = 20 + for i in range(0, 9, 1): + if i >= 4: + i_spacing = 20 + elif i >= 7: + i_spacing = 20 + self.data_coordinates[e][i] = [(i * dim) + i_spacing, (e * dim) + e_spacing, dim, dim] + + def assess_playfield_and_make_move(self): + + new_observation, new_screenshot = self.get_current_board_state() + 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("sodoku/screen_shot.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[180:1010, 860:1690] + + #cv.imshow("screenshot", screenshot) + #cv.waitKey(150) + #continue + data_coords = np.zeros((9, 9), 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.85, 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 = self.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, 9, 1): + for i in range(0, 9, 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 + # per pos + # select from row,column and quadrant (1-9) + # find missing pieces per row, column, quadrant + + def find_patterns_and_valid_moves(self, state): + while self.is_empty_pieces_in_state(state): + for e in range(0, 9, 1): + for i in range(0, 9, 1): + if state[e, i] not in self.colors: + #color in self.colors: + store = self.collect_existing_pieces(state, e, i) + if len(store) == 8: + for color in self.colors: + if color not in store: + state[e, i] = color + self.deploy_finding_to_game(e, i, color) + + 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 deploy_finding_to_game(self, e, i, color): + cv.waitKey(5000) + 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) + + y = 1100 + x = 880 + ((color - 1) * 100) # +100 + self.dig_point(x, y, 100) + + def is_empty_pieces_in_state(self, state): + for e in range(0, 9, 1): + for i in range(0, 9, 1): + if state[e, i] not in self.colors: + return True + return False + + def collect_existing_pieces(self, state, e, i): + store = [] + for ee in range(0, 9, 1): + if state[ee, i] != 0: + store.append(state[ee, i]) + + for ii in range(0, 9, 1): + if state[e, ii] != 0: + store.append(state[e, ii]) + + # quad 1 + if e <= 2 and i <= 2: + for eee in range(0, 3, 1): + for iii in range(0, 3, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 2 + elif e <= 2 and i <= 5: + for eee in range(0, 3, 1): + for iii in range(3, 6, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 3 + elif e <= 2 and i <= 8: + for eee in range(0, 3, 1): + for iii in range(6, 9, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 4 + elif e <= 5 and i <= 2: + for eee in range(3, 6, 1): + for iii in range(0, 3, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 5 + elif e <= 5 and i <= 5: + for eee in range(3, 6, 1): + for iii in range(3, 6, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 6 + elif e <= 5 and i <= 8: + for eee in range(3, 6, 1): + for iii in range(6, 9, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 7 + elif e <= 8 and i <= 2: + for eee in range(6, 9, 1): + for iii in range(0, 3, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 8 + elif e <= 8 and i <= 5: + for eee in range(6, 9, 1): + for iii in range(3, 6, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + # quad 9 + elif e <= 8 and i <= 8: + for eee in range(6, 9, 1): + for iii in range(6, 9, 1): + if state[eee, iii] != 0: + store.append(state[eee, iii]) + + unique_numbers = list(set(store)) + + return unique_numbers \ No newline at end of file diff --git a/sodoku/1.jpg b/sodoku/1.jpg new file mode 100644 index 0000000..d50acd2 Binary files /dev/null and b/sodoku/1.jpg differ diff --git a/sodoku/2.jpg b/sodoku/2.jpg new file mode 100644 index 0000000..ee768a4 Binary files /dev/null and b/sodoku/2.jpg differ diff --git a/sodoku/3.jpg b/sodoku/3.jpg new file mode 100644 index 0000000..02116cc Binary files /dev/null and b/sodoku/3.jpg differ diff --git a/sodoku/4.jpg b/sodoku/4.jpg new file mode 100644 index 0000000..146f0b6 Binary files /dev/null and b/sodoku/4.jpg differ diff --git a/sodoku/5.jpg b/sodoku/5.jpg new file mode 100644 index 0000000..65662e4 Binary files /dev/null and b/sodoku/5.jpg differ diff --git a/sodoku/6.jpg b/sodoku/6.jpg new file mode 100644 index 0000000..39cdd0f Binary files /dev/null and b/sodoku/6.jpg differ diff --git a/sodoku/7.jpg b/sodoku/7.jpg new file mode 100644 index 0000000..6246c97 Binary files /dev/null and b/sodoku/7.jpg differ diff --git a/sodoku/8.jpg b/sodoku/8.jpg new file mode 100644 index 0000000..856c306 Binary files /dev/null and b/sodoku/8.jpg differ diff --git a/sodoku/9.jpg b/sodoku/9.jpg new file mode 100644 index 0000000..434e210 Binary files /dev/null and b/sodoku/9.jpg differ diff --git a/sodoku/screen_shot.jpg b/sodoku/screen_shot.jpg new file mode 100644 index 0000000..2df2407 Binary files /dev/null and b/sodoku/screen_shot.jpg differ