Files
Litcraft_Python_B/litris.py

220 lines
7.3 KiB
Python

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
from window_capture import WindowCapture
from vision import Vision
from config_file import UserConfigs
class Litris(GameBase):
def __init__(self, overlay):
super().__init__(overlay)
self.config = UserConfigs()
self.capture_window = WindowCapture(None, None, self.config)
self.vision_stun = Vision()
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