diff --git a/litris.py b/litris.py index be1db4d..f919c24 100644 --- a/litris.py +++ b/litris.py @@ -6,6 +6,18 @@ from field import Field from tetromino import Tetromino from optimizer import Optimizer +O_FULL = [[0, 1, 1, 0], [0, 1, 1, 0]] +D_FULL = [[0, 1, 1, 0], [0, 0, 1, 0]] +L_FULL = [[0, 0, 1, 0], [1, 1, 1, 0]] +J_FULL = [[1, 1, 1, 0], [0, 0, 1, 0]] +I_FULL = [[1, 1, 1, 1], [0, 0, 0, 0]] +C_FULL = [[0, 0, 0, 0], [0, 0, 1, 0]] +B_FULL = [[0, 0, 0, 0], [0, 1, 1, 0]] +A_FULL = [[0, 1, 1, 1], [0, 0, 0, 0]] +S_FULL = [[0, 0, 1, 1], [0, 1, 1, 0]] +Z_FULL = [[0, 1, 1, 0], [0, 0, 1, 1]] +T_FULL = [[0, 1, 1, 1], [0, 0, 1, 0]] + class Litris(GameBase): def __init__(self, overlay): @@ -14,7 +26,7 @@ class Litris(GameBase): self.keyboard = Controller() self.data_coordinates = np.zeros((20, 20), dtype=object) - + self.stone_coordinates = np.zeros((2, 4), dtype=object) self.observation = np.zeros((20, 20), dtype=int) self.colors = [1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -28,30 +40,8 @@ class Litris(GameBase): #self.sd_reset_board = cv.imread("control_elements/sodoku_reset_button.jpg", cv.IMREAD_COLOR) - self.needles = {"I": cv.imread("litris/I.jpg", cv.IMREAD_UNCHANGED), - "O": cv.imread("litris/O.jpg", cv.IMREAD_UNCHANGED), - "L": cv.imread("litris/L.jpg", cv.IMREAD_UNCHANGED), - "J": cv.imread("litris/J.jpg", cv.IMREAD_UNCHANGED), - "S": cv.imread("litris/S.jpg", cv.IMREAD_UNCHANGED), - "Z": cv.imread("litris/Z.jpg", cv.IMREAD_UNCHANGED), - "T": cv.imread("litris/T.jpg", cv.IMREAD_UNCHANGED), - "D": cv.imread("litris/D.jpg", cv.IMREAD_UNCHANGED), - "A": cv.imread("litris/A.jpg", cv.IMREAD_UNCHANGED), - "B": cv.imread("litris/B.jpg", cv.IMREAD_UNCHANGED), - "C": cv.imread("litris/C.jpg", cv.IMREAD_UNCHANGED) - } - self.needle_masks = {"I": cv.imread("litris/I-mask.png", cv.IMREAD_COLOR), - "O": cv.imread("litris/O-mask.png", cv.IMREAD_COLOR), - "L": cv.imread("litris/L-mask.png", cv.IMREAD_COLOR), - "J": cv.imread("litris/J-mask.png", cv.IMREAD_COLOR), - "S": cv.imread("litris/S-mask.png", cv.IMREAD_COLOR), - "Z": cv.imread("litris/Z-mask.png", cv.IMREAD_COLOR), - "T": cv.imread("litris/T-mask.png", cv.IMREAD_COLOR), - "D": cv.imread("litris/D-mask.png", cv.IMREAD_COLOR), - "A": cv.imread("litris/A-mask.png", cv.IMREAD_COLOR), - "B": cv.imread("litris/B-mask.png", cv.IMREAD_COLOR), - "C": cv.imread("litris/C-mask.png", cv.IMREAD_COLOR) - } + self.needles = {1: cv.imread("litris/blue_needle.jpg", cv.IMREAD_UNCHANGED)} + def reset_field(self): self.state = [[' ' for cols in range(Field.WIDTH)] @@ -67,9 +57,12 @@ class Litris(GameBase): for e in range(0, 20, 1): for i in range(0, 20, 1): self.data_coordinates[e][i] = [(i * dim) + (i * i_spacing), (e * dim) + (e * e_spacing), dim, dim] + for e in range(0, 2, 1): + for i in range(0, 4, 1): + self.stone_coordinates[e][i] = [(i * dim) + (i * i_spacing), (e * dim) + (e * e_spacing), dim, dim] def assess_playfield_and_make_move(self): - + # current_letter = self.new_stone_detection_and_identification() current_letter = self.stone_id() #current_letter = 'D' print("current_letter: ", current_letter) @@ -156,6 +149,79 @@ class Litris(GameBase): fail_counter = fail_counter + 1 cv.waitKey(50) + + def new_stone_detection_and_identification(self): + stone_coords = np.zeros((2, 4), dtype=object) + fail_counter = 0 + while True: + screenshot = self.capture_window.get_screenshot() + #screenshot = cv.imread("litris/main_playfield.jpg") + # 1148 1412 580 845 + screenshot = screenshot[643:782, 1148:1412] + #cv.imshow("screenshot", screenshot) + #cv.waitKey(150) + + # 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[1], 0.85, 4) + if len(rectangles) == 0: + if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': + return + if fail_counter >= 5: + self.keyboard.press(Key.down) + self.keyboard.release(Key.down) + print("direction pressed: drop down") + cv.waitKey(50) + fail_counter = fail_counter + 1 + cv.waitKey(50) + continue + points = self.vision_stun.get_click_points(rectangles) + + for point in points: + x, y = self.point_in_smal_rect(point) + if x is not None and y is not None: + stone_coords[x][y] = 1 + # 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) + + current_letter = self.get_letter_for_stone(stone_coords) + if current_letter is None: + print("letter id failed for: ", stone_coords) + cv.waitKey(50) + continue + return current_letter + + def get_letter_for_stone(self, stone): + + if np.array_equal(stone, O_FULL): + return "O" + elif np.array_equal(stone, D_FULL): + return "D" + elif np.array_equal(stone, L_FULL): + return "L" + elif np.array_equal(stone, J_FULL): + return "J" + elif np.array_equal(stone, I_FULL): + return "I" + elif np.array_equal(stone, C_FULL): + return "C" + elif np.array_equal(stone, B_FULL): + return "B" + elif np.array_equal(stone, A_FULL): + return "A" + elif np.array_equal(stone, S_FULL): + return "S" + elif np.array_equal(stone, Z_FULL): + return "Z" + elif np.array_equal(stone, T_FULL): + return "T" + else: + return None + def move_stone(self, col_movement, rotation): if col_movement is None: return @@ -215,4 +281,15 @@ class Litris(GameBase): if x1 < x and x < x2: if y1 < y and y < y2: return e, i + return None, None + + def point_in_smal_rect(self, point): + for e in range(0, 2, 1): + for i in range(0, 4, 1): + x1, y1, w, h = self.stone_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 \ No newline at end of file