from copy import copy import cv2 as cv import numpy as np from game_base_class import GameBase from pynput.keyboard import Key, Controller from field import Field from tetromino import Tetromino from optimizer import Optimizer from litris_stone_id_thread import NewStoneID class Litris(GameBase): def __init__(self, overlay): super().__init__(overlay) self.keyboard = Controller() self.data_coordinates = np.zeros((20, 20), dtype=object) self.observation = np.zeros((20, 20), dtype=int) self.colors = [1, 2, 3, 4, 5, 6, 7, 8, 9] self.offset_left = 610 self.offset_down = 40 self.fill_data_coordinates() self.field = Field() self.field_mem = Field() self.litris_reset_board = cv.imread("control_elements/sodoku_reset_button.jpg", cv.IMREAD_COLOR) self.stone_id_thread = NewStoneID() self.move_mode = 1 def fill_data_coordinates(self): # 610 to 1950 = 1340 - 76 / 20 = 63 # 40 to 1380 = 1340 - 76 / 20 = 63 # spacing 19 * 4 dim = 63 e_spacing = 4 i_spacing = 4 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] def assess_playfield_and_make_move(self): while True: if self.stone_id_thread.get_pick_up_status() == False: screenshot = self.capture_window.get_screenshot() screenshot = screenshot[880:1060, 1400:1600] if self.check_for_button_and_execute(screenshot, self.litris_reset_board, 1400, 880): self.field.reset_field() if self.overlay.run_mode == 'stopped' or self.overlay.run_mode == 'paused': return cv.waitKey(50) continue #current_letter = self.new_stone_detection_and_identification() #current_letter = self.stone_id() #current_letter = 'D' current_letter = self.stone_id_thread.get_actual_letter() #self.stone_id_thread.set_pick_up_status(False) print("current_letter: ", current_letter) #if current_letter is None: # cv.waitKey(50) # return current_tetromino = Tetromino.create(current_letter) if self.move_mode == 2: current_tetromino.rotate(3) elif self.move_mode == 3: current_tetromino.rotate(2) elif self.move_mode == 4: current_tetromino.rotate(1) opt = Optimizer.get_optimal_drop(self.field, current_tetromino) rotation = opt['tetromino_rotation'] column = opt['tetromino_column'] print("Rota:", rotation) print("column:", column) current_tetromino.rotate(rotation) offset_col = current_tetromino.get_offset_column(rotation, self.move_mode) print("offset column:", offset_col) self.field.drop(current_tetromino, column) self.move_stone(column - offset_col, rotation) self.drop_down() print(self.field) if self.field.get_line_count() >= 10: self.update_move_mode() self.field.rotate_state() #self.update_move_mode() #self.field.reset_field() #field_mem = copy(self.field) #self.field = copy(self.field_mem) #self.field_mem = copy(field_mem) self.field.cleared_rows = 1 cv.waitKey(200) self.stone_id_thread.set_pick_up_status(False) def drop_down(self): if self.move_mode == 1: down = Key.down left = Key.left right = Key.right elif self.move_mode == 2: down = Key.left left = Key.up right = Key.down elif self.move_mode == 3: down = Key.up left = Key.right right = Key.left elif self.move_mode == 4: down = Key.right left = Key.down right = Key.up for i in range(1, 10, 1): self.keyboard.press(down) self.keyboard.release(down) print("drop down pressed:", down) cv.waitKey(50) def update_move_mode(self): if self.move_mode <=3: self.move_mode = self.move_mode + 1 elif self.move_mode == 4: self.move_mode = 1 def move_stone(self, col_movement, rotation): if col_movement is None: return if self.move_mode == 1: down = Key.down left = Key.left right = Key.right elif self.move_mode == 2: down = Key.left left = Key.up right = Key.down elif self.move_mode == 3: down = Key.up left = Key.right right = Key.left elif self.move_mode == 4: down = Key.right left = Key.down right = Key.up # Press and release space self.keyboard.press(down) self.keyboard.release(down) print("direction pressed: ", down) cv.waitKey(120) if rotation == 3: self.keyboard.press('e') self.keyboard.release('e') print("rotation 1 pressed: e") cv.waitKey(40) elif rotation == 2: self.keyboard.press('e') self.keyboard.release('e') print("rotation 2 pressed: e 1") cv.waitKey(30) self.keyboard.press('e') self.keyboard.release('e') print("rotation 2 pressed: e 2") cv.waitKey(30) elif rotation == 1: self.keyboard.press('e') self.keyboard.release('e') print("rotation 3 pressed: e 1") cv.waitKey(20) self.keyboard.press('e') self.keyboard.release('e') print("rotation 3 pressed: e 2") cv.waitKey(20) self.keyboard.press('e') self.keyboard.release('e') print("rotation 3 pressed: e 3") cv.waitKey(20) if col_movement < 0: for i in range(0, col_movement, - 1): self.keyboard.press(left) self.keyboard.release(left) print("move left 3 pressed:", left) cv.waitKey(40) else: for i in range(0, col_movement, 1): self.keyboard.press(right) self.keyboard.release(right) print("move right 3 pressed:", right) cv.waitKey(40) def point_in_rect(self, point): for e in range(0, 20, 1): for i in range(0, 20, 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