From 6012a51538db4a124375c60fd89b716cab299251 Mon Sep 17 00:00:00 2001 From: "Thaloria@web.de" Date: Sun, 23 Jul 2023 14:24:09 +0200 Subject: [PATCH] litris update --- litris.py | 240 +++++++++++++++++++-------------------------------- tetromino.py | 12 +-- 2 files changed, 96 insertions(+), 156 deletions(-) diff --git a/litris.py b/litris.py index 7d21de8..9553430 100644 --- a/litris.py +++ b/litris.py @@ -41,39 +41,18 @@ from optimizer import Optimizer import time -BLOCK_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]] -BLOCK_SMALL = [[1, 1], [1, 1]] -BLOCK_COL = 9 +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]] -BL3_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]] -Bl3_COL = 9 - -L1_FULL = [[0, 0, 0, 0], [0, 0, 1, 0], [1, 1, 1, 0], [0, 0, 0, 0]] -L1_COL = 8 - -L2_FULL = [[0, 0, 0, 0], [1, 1, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]] -L2_COL = 8 - -LINE_FULL = [[0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]] -LINE_COL = 8 - -DOT_FULL = [[0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]] -DOT_COL = 10 - -DDOT_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]] -DDOT_COL = 9 - -DDDOT_FULL = [[0, 0, 0, 0], [0, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0]] -DDDOT_COL = 9 - -Z1_FULL = [[0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 1, 0], [0, 0, 0, 0]] -Z1_COL = 9 - -Z2_FULL = [[0, 0, 0, 0], [0, 1, 1, 0], [0, 0, 1, 1], [0, 0, 0, 0]] -Z2_COL = 9 - -T1_FULL = [[0, 0, 0, 0], [0, 1, 1, 1], [0, 0, 1, 0], [0, 0, 0, 0]] -T1_COL = 9 class Litris(GameBase): @@ -83,7 +62,7 @@ class Litris(GameBase): self.keyboard = Controller() self.data_coordinates = np.zeros((20, 20), dtype=object) - self.stone_coordinates = np.zeros((4, 4), 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] @@ -97,8 +76,17 @@ class Litris(GameBase): #self.sd_reset_board = cv.imread("control_elements/sodoku_reset_button.jpg", cv.IMREAD_COLOR) - self.needles = {1: cv.imread("litris/blue_needle.jpg", cv.IMREAD_COLOR) - # 2: cv.imread("sodoku/2.jpg", cv.IMREAD_COLOR), + self.needles = {"I": cv.imread("litris/I.jpg", cv.IMREAD_COLOR), + "O": cv.imread("litris/O.jpg", cv.IMREAD_COLOR), + "L": cv.imread("litris/L.jpg", cv.IMREAD_COLOR), + "J": cv.imread("litris/J.jpg", cv.IMREAD_COLOR), + "S": cv.imread("litris/S.jpg", cv.IMREAD_COLOR), + "Z": cv.imread("litris/Z.jpg", cv.IMREAD_COLOR), + "T": cv.imread("litris/T.jpg", cv.IMREAD_COLOR), + "D": cv.imread("litris/D.jpg", cv.IMREAD_COLOR), + "A": cv.imread("litris/A.jpg", cv.IMREAD_COLOR), + "B": cv.imread("litris/B.jpg", cv.IMREAD_COLOR), + "C": cv.imread("litris/C.jpg", cv.IMREAD_COLOR) } def reset_field(self): @@ -115,7 +103,7 @@ 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, 4, 1): + 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] @@ -136,14 +124,17 @@ class Litris(GameBase): #stone_list = ["L","S","Z","J"] #ier = 0 - current_stone = self.new_stone_detection_and_identification() - current_letter = self.get_letter_for_stone(current_stone) - print("Current stone:", current_letter) - if current_letter is None: - return + + #current_letter = self.new_stone_detection_and_identification() + current_letter = self.stone_id() current_tetromino = Tetromino.create(current_letter) opt = Optimizer.get_optimal_drop(self.field, current_tetromino) rotation = opt['tetromino_rotation'] + if current_letter == 'D' and (rotation == 1 or rotation == 3): + if rotation == 3: + rotation = 1 + elif rotation == 1: + rotation = 3 column = opt['tetromino_column'] print("Rota:", rotation) print("column:", column) @@ -196,25 +187,57 @@ class Litris(GameBase): #cv.waitKey(150) return data_coords, screenshot - def new_stone_detection_and_identification(self): - stone_coords = np.zeros((4, 4), dtype=object) + def stone_id(self): + fail_counter = 0 while True: screenshot = self.capture_window.get_screenshot() #screenshot = cv.imread("litris/main_playfield.jpg") # 1148 1412 580 845 - screenshot = screenshot[580:845, 1148:1412] + screenshot = screenshot[623:802, 1128:1432] + #cv.imshow("screenshot", screenshot) + #cv.waitKey(150) + for needle_key in self.needles.keys(): + rectangles = self.vision_stun.find(screenshot, self.needles[needle_key], 0.85, 1) + if len(rectangles) == 0: + if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': + return + continue + else: + return needle_key + if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': + return + if fail_counter >= 3: + self.keyboard.press(Key.down) + self.keyboard.release(Key.down) + print("direction pressed: drop down") + cv.waitKey(100) + 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, 16) + rectangles = self.vision_stun.find(screenshot, self.needles[1], 0.85, 8) if len(rectangles) == 0: - cv.waitKey(100) if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': return - self.keyboard.press(Key.down) - self.keyboard.release(Key.down) + if fail_counter >= 5: + self.keyboard.press(Key.down) + self.keyboard.release(Key.down) + print("direction pressed: drop down") + cv.waitKey(100) + fail_counter = fail_counter + 1 + cv.waitKey(50) continue points = self.vision_stun.get_click_points(rectangles) @@ -228,124 +251,41 @@ class Litris(GameBase): #output_image = self.vision_stun.draw_rectangles(screenshot, rectangles) #cv.imshow("output_image", output_image) #cv.waitKey(150) - return stone_coords + + 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, BLOCK_FULL): + if np.array_equal(stone, O_FULL): return "O" - elif np.array_equal(stone, BL3_FULL): + elif np.array_equal(stone, D_FULL): return "D" - elif np.array_equal(stone, L1_FULL): + elif np.array_equal(stone, L_FULL): return "L" - elif np.array_equal(stone, L2_FULL): + elif np.array_equal(stone, J_FULL): return "J" - elif np.array_equal(stone, LINE_FULL): + elif np.array_equal(stone, I_FULL): return "I" - elif np.array_equal(stone, DOT_FULL): + elif np.array_equal(stone, C_FULL): return "C" - elif np.array_equal(stone, DDOT_FULL) : + elif np.array_equal(stone, B_FULL): return "B" - elif np.array_equal(stone, DDDOT_FULL) : + elif np.array_equal(stone, A_FULL): return "A" - elif np.array_equal(stone, Z1_FULL): + elif np.array_equal(stone, S_FULL): return "S" - elif np.array_equal(stone, Z2_FULL): + elif np.array_equal(stone, Z_FULL): return "Z" - elif np.array_equal(stone, T1_FULL): + elif np.array_equal(stone, T_FULL): return "T" else: return None - - def find_place_for_stone(self, stone, current_board): - - if np.array_equal(stone, BLOCK_FULL): - # block - for e in range(19, 17, - 1): - for i in range(0, 19, 1): - if current_board[e][i] == 0 and current_board[e - 1][i] == 0 and current_board[e][i + 1] == 0 and current_board[e - 1][i + 1] == 0: - if e == 19: - return i - BLOCK_COL - elif e < 19 and current_board[e + 1][i] == 1 and current_board[e + 1][i + 1] == 1: - return i - BLOCK_COL - if np.array_equal(stone, BL3_FULL): - # block - for e in range(19, 17, - 1): - for i in range(0, 19, 1): - if current_board[e][i] == 1 and current_board[e - 1][i] == 0 and current_board[e][i + 1] == 0 and current_board[e - 1][i + 1] == 0: - return i - Bl3_COL - elif np.array_equal(stone, L1_FULL): - # L1 - for e in range(19, 17, - 1): - for i in range(0, 18, 1): - if current_board[e][i] == 0 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 0 and \ - current_board[e - 1][i + 2] == 0: - return i - L1_COL - elif np.array_equal(stone, L2_FULL): - # L1 - for e in range(19, 17, - 1): - for i in range(0, 18, 1): - if current_board[e - 1][i] == 0 and current_board[e - 1][i + 1] == 0 and current_board[e - 1][i + 2] == 0 and \ - current_board[e][i + 2] == 0 and current_board[e][i] == 1 and current_board[e][i + 1] == 1: - return i - L2_COL - elif np.array_equal(stone, LINE_FULL): - # Line - for e in range(19, 18, - 1): - for i in range(0, 17, 1): - if current_board[e][i] == 0 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 0 and \ - current_board[e][i + 3] == 0: - if e == 19: - return i - LINE_COL - elif e < 19 and current_board[e + 1][i] == 1 and current_board[e + 1][i + 1] == 1 and current_board[e + 1][i + 2] and current_board[e + 1][i + 3]: - return i - LINE_COL - elif np.array_equal(stone, DOT_FULL): - # Dot - for e in range(19, 18, - 1): - for i in range(0, 20, 1): - if current_board[e][i] == 0: - if e == 19: - return i - DOT_COL - elif e < 19 and current_board[e + 1][i] == 1: - return i - DOT_COL - - elif np.array_equal(stone, DDOT_FULL) : - # DDot - for e in range(19, 18, - 1): - for i in range(0, 19, 1): - if current_board[e][i] == 0 and current_board[e][i + 1] == 0: - if e == 19: - return i - DDOT_COL - elif e < 19 and current_board[e + 1][i] == 1 and current_board[e + 1][i + 1]: - return i - DDOT_COL - elif np.array_equal(stone, DDDOT_FULL) : - # DDDot - for e in range(19, 18, - 1): - for i in range(0, 18, 1): - if current_board[e][i] == 0 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 0: - if e == 19: - return i - DDDOT_COL - elif e < 19 and current_board[e + 1][i] == 1 and current_board[e + 1][i + 1] == 1 and current_board[e + 1][i + 2]: - return i - DDDOT_COL - return i - DDDOT_COL - elif np.array_equal(stone, Z1_FULL): - # Z1 - for e in range(19, 17, - 1): - for i in range(0, 18, 1): - if current_board[e][i] == 0 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 1 and current_board[e - 1][i + 1] == 0 and current_board[e - 1][i + 2] == 0: - return i - Z1_COL - elif np.array_equal(stone, Z2_FULL): - # Z2 - for e in range(19, 17, - 1): - for i in range(0, 18, 1): - if current_board[e][i] == 1 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 0 and current_board[e - 1][i] == 0 and current_board[e - 1][i + 1] == 0: - return i - Z2_COL - elif np.array_equal(stone, T1_FULL): - # T1 - for e in range(19, 17, - 1): - for i in range(0, 18, 1): - if current_board[e][i] == 1 and current_board[e][i + 1] == 0 and current_board[e][i + 2] == 1 and current_board[e - 1][i] == 0 and current_board[e - 1][i + 1] == 0 and current_board[e - 1][i + 2] == 0: - return i - T1_COL def move_stone(self, col_movement, rotation): if col_movement is None: return @@ -401,7 +341,7 @@ class Litris(GameBase): return None, None def point_in_smal_rect(self, point): - for e in range(0, 4, 1): + 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 diff --git a/tetromino.py b/tetromino.py index d18e60c..00e57a3 100644 --- a/tetromino.py +++ b/tetromino.py @@ -172,14 +172,14 @@ class Tetromino(): 'i': {0: 8, 1: 9, 2: 9, 3: 9}, 'a': {0: 9, 1: 9, 2: 9, 3: 9}, 'b': {0: 9, 1: 9, 2: 9, 3: 9}, - 'c': {0: 10, 1: 9, 2: 9, 3: 9}, + 'c': {0: 10, 1: 10, 2: 10, 3: 10}, 'o': {0: 9, 1: 9, 2: 9, 3: 9}, 'd': {0: 9, 1: 9, 2: 9, 3: 9}, - 't': {0: 9, 1: 9, 2: 9, 3: 9}, - 's': {0: 9, 1: 8, 2: 9, 3: 8}, - 'z': {0: 9, 1: 8, 2: 10, 3: 8}, - 'j': {0: 8, 1: 9, 2: 8, 3: 9}, - 'l': {0: 8, 1: 9, 2: 8, 3: 9} + 't': {0: 9, 1: 9, 2: 8, 3: 9}, + 's': {0: 9, 1: 9, 2: 9, 3: 9}, + 'z': {0: 9, 1: 9, 2: 9, 3: 9}, + 'j': {0: 8, 1: 9, 2: 9, 3: 9}, + 'l': {0: 8, 1: 9, 2: 9, 3: 9} } return offset_map.get(self.letter)[rotation]