class Controller: def __init__(self): self.playfield = Playfield() self.playfield.init() pass @staticmethod def ready(): sys.stdout.write('READY\n') sys.stdout.flush() def run_game_cycle(self): line = sys.stdin.readline() if line.strip() == 'SKILL': exit() elif line.strip() == 'STICK': self.playfield.run_playfield_cycle() self.print_pixel_map(self.playfield.generate_pixel_map()) elif len(line) > 4 and line.startswith('P'): self.on_user_input(line[1:5]) def on_user_input(self, user_input): if user_input[3:4] == '1': if self.playfield.world.runner.in_default_position( self.playfield.dimensions): self.playfield.world.runner.jump() @staticmethod def print_pixel_map(pixel_map): for row in pixel_map: for pixel in row: sys.stdout.write(pixel.to_string()) sys.stdout.flush()
def game_loop(self): """Game loop.""" surface = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) surface.fill(0xC4CFA1) # Same colour as splash screen playfield = Playfield(PLAYFIELD_WIDTH, PLAYFIELD_HEIGHT, self.tileset) pygame.time.set_timer(pygame.USEREVENT, START_SPEED) clock = pygame.time.Clock() trimino = self.spawn_trimino() game_over = False while not game_over: event = pygame.event.poll() if event.type == pygame.QUIT: self.exit_game() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: break if event.key == pygame.K_j: if not self.legal_move(playfield, trimino.rotate_left()): trimino.rotate_right() # Revert rotation if event.key == pygame.K_k: if not self.legal_move(playfield, trimino.rotate_right()): trimino.rotate_left() # Revert rotation if event.key == pygame.K_SPACE: # Hard drop while self.legal_move(playfield, trimino.move_down()): pass if playfield.place_trimino(trimino.move_up()): trimino = self.spawn_trimino() self.process_lines(playfield) else: game_over = True elif event.type == pygame.USEREVENT: if not self.legal_move(playfield, trimino.move_down()): if playfield.place_trimino(trimino.move_up()): trimino = self.spawn_trimino() self.process_lines(playfield) else: game_over = True pressed = pygame.key.get_pressed() if pressed[pygame.K_LEFT]: if not self.legal_move(playfield, trimino.move_left()): trimino.move_right() # Revert move if pressed[pygame.K_RIGHT]: if not self.legal_move(playfield, trimino.move_right()): trimino.move_left() # Revert move if pressed[pygame.K_DOWN]: if not self.legal_move(playfield, trimino.move_down()): trimino.move_up() # Revert move playfield.draw() trimino.draw() self.font.write(0, 1, "SCORE: %d" % self.player.score) self.font.write(0, 10, "LEVEL: %d" % self.level) pygame.display.flip() clock.tick(30) pygame.time.set_timer(pygame.USEREVENT, 0) # Disable timer
def __init__(self): super(GameState, self).__init__() self.falling_tetro = None # nrows should be 22 self.playfield = Playfield(10, 15) self.playfield.rect.centerx = Engine.screenrect.centerx self.playfield.rect.bottom = Engine.screenrect.bottom - block.SIZE self.members.append(self.playfield)
def __init__(self): self._active_piece = None self._next_piece_class = None self._playfield = Playfield() self._score = 0 self._game_over = False self._rng_queue = np.array( []) # for _gen_next_piece_class: we generate a queue of all
def __init__(self, game, player, font, zoom, push, pop): self._game = game self._playfield = Playfield(self._game, player, font, zoom, self._ignoremotion) self._info = InfoView(self._playfield, font, zoom, push, pop) self._ignore = None self.scale(font)
def __init__(self): super(GameState, self).__init__() self.falling_tetro = None # nrows should be 22 self.playfield = Playfield(10, 15) self.playfield.rect.centerx = Engine.screenrect.centerx self.playfield.rect.bottom = Engine.screenrect.bottom - block.SIZE self.members.append(self.playfield)
def __update_game(self): self.__surface.fill((0, 0, 0)) self.__score = self.__ball.get_score() Playfield(self.__surface, self.__username, self.__score) self.__snake.update_snake() self.__food.look_for_food() self.__paddle.update_paddle() self.__ball.update_ball() pygame.display.flip() self.__clock.tick(60)
def __init__(self, surface, username, numberOfPlayers, soundsOn): # Initialize variables self.__clock = pygame.time.Clock() self.__surface = surface self.__isRunning = True self.__username = username self.__numberOfPlayers = numberOfPlayers self.__soundsOn = soundsOn # Initialize the game entities self.__ball = Ball(self.__surface) self.__score = self.__ball.get_score() self.__playfield = Playfield(self.__surface, self.__username, self.__score) self.__surface = self.__playfield.get_surface() self.__snake = Snake(self.__surface, self.__isRunning) self.__food = Food(self.__surface) # Check if multiplayer or not if self.__numberOfPlayers == 0: self.__paddle = Paddle(self.__surface) else: self.__paddle = Paddle(self.__surface, True)
class GameScreen(object): dt = 0.05 def __init__(self, game, player, font, zoom, push, pop): self._game = game self._playfield = Playfield(self._game, player, font, zoom, self._ignoremotion) self._info = InfoView(self._playfield, font, zoom, push, pop) self._ignore = None self.scale(font) def scale(self, font): self._font = font self._playfield.scale(self._font) self._info.scale(self._font) def resize(self, size): self._fieldwidth = max(0, size[0] - self._info.width) self._playfield.resize((self._fieldwidth, size[1])) self._info.resize((size[0] - self._fieldwidth, size[1])) def _ignoremotion(self, rel): self._ignore = rel def handle(self, e): if e.type == MOUSEMOTION and e.rel != self._ignore: mouse.set_visible(True) self._ignore = None if self._playfield.handle(e): return True if 'pos' in e.dict: e.dict['pos'] = (e.pos[0] - self._fieldwidth, e.pos[1]) return self._info.handle(e) def _playinfosurfaces(self, surface): size = surface.get_size() return (surface.subsurface(Rect((0,0),(self._fieldwidth,size[1]))), surface.subsurface(Rect((self._fieldwidth,0), (size[0]-self._fieldwidth, size[1])))) def draw(self, surface): play, info = self._playinfosurfaces(surface) self._playfield.draw(play) self._info.draw(info)
class PlayfieldController: def __init__(self): self._active_piece = None self._next_piece_class = None self._playfield = Playfield() self._score = 0 self._game_over = False self._rng_queue = np.array( []) # for _gen_next_piece_class: we generate a queue of all # 7 pieces, shuffled, and sample as needed. When # the queue is empty, regenerate it. def _gen_next_piece_class(self): # based on rng algorithm described in https://tetris.fandom.com/wiki/Random_Generator if self._rng_queue.size == 0: # if the queue is empty self._rng_queue = np.random.permutation( [I, J, L, O, S, T, Z]) # [I, J, L, O, S, T, Z] self._next_piece_class = self._rng_queue[0] self._rng_queue = np.delete(self._rng_queue, 0) # These four methods should perform the necessary checking, and transform the active # piece according to the official Tetris rules. def move_left(self): ''' Has the effect of pressing left on the controller.''' try: if self._playfield.is_legal_move(self._active_piece, (self._active_piece.coords[0] - 1, self._active_piece.coords[1])): self._active_piece.coords = (self._active_piece.coords[0] - 1, self._active_piece.coords[1]) else: return False except AttributeError: warnings.warn( 'Tried to move left before starting the game. Updating game.', RuntimeWarning) self.update() self.move_left() def move_right(self): '''Has the effect of pressing right on the controller.''' try: if self._playfield.is_legal_move(self._active_piece, (self._active_piece.coords[0] + 1, self._active_piece.coords[1])): self._active_piece.coords = (self._active_piece.coords[0] + 1, self._active_piece.coords[1]) else: return False except AttributeError: warnings.warn( 'Tried to move right before starting the game. Statrting game.', RuntimeWarning) self.update() self.move_right() def rotate_cw(self): '''Has the effect of pressing rotate-clockwise on the controller.''' # Read about wall kicks here: https://tetris.wiki/SRS#Wall_Kicks # O tetrominos don't rotate if isinstance(self._active_piece, O): return # Try a basic rotation try: orientation = self._active_piece.orientation except AttributeError: warnings.warn( 'Tried to rotate cw before starting the game. Starting game.', RuntimeWarning) self.update() self.rotate_cw() if self._playfield.is_legal_move(self._active_piece.rotate_cw(), self._active_piece.coords): pass # nothing to do, we already rotated the piece # Try wall kicks: https://tetris.wiki/SRS#Wall_Kicks else: if isinstance(self._active_piece, I): # I tetrominos have their own wall # kick rules. wall_kick_data = [[(-2, 0), (1, 0), (-2, -1), (1, 2)], [(-1, 0), (2, 0), (-1, +2), (2, -1)], [(2, 0), (-1, 0), (2, 1), (-1, -2)], [(1, 0), (-2, 0), (1, -2), (-2, 1)]] else: wall_kick_data = [[(-1, 0), (-1, 1), (0, -2), (-1, -2)], [(1, 0), (1, -1), (0, 2), (1, 2)], [(1, 0), (1, 1), (0, -2), (1, -2)], [(-1, 0), (-1, -1), (0, 2), (-1, 2)]] for test in [0, 1, 2, 3]: if self._playfield.is_legal_move( self._active_piece, (self._active_piece.coords[0] + wall_kick_data[orientation][test][0], self._active_piece.coords[1] + wall_kick_data[orientation][test][1])): # stop the tests, keep the rotation self._active_piece.coords =\ (self._active_piece.coords[0] + wall_kick_data[orientation][test][0], self._active_piece.coords[1] + wall_kick_data[orientation][test][1]) break else: if test == 3: # If we've gone through all the tests and # no wall kick yields a legal rotation, # rotate our piece back. self._active_piece.rotate_ccw() def rotate_ccw(self): '''Has the effect of pressing rotate-counterclockwise on the controller.''' # Read about wall kicks here: https://tetris.wiki/SRS#Wall_Kicks if isinstance(self._active_piece, O): return # Try a basic rotation try: orientation = self._active_piece.orientation except AttributeError: warnings.warn( 'Tried to rotate ccw before starting the game. Starting game.', RuntimeWarning) self.update() self.rotate_ccw() if self._playfield.is_legal_move(self._active_piece.rotate_ccw(), self._active_piece.coords): pass # nothing to do, we already rotated the piece # Try wall kicks: https://tetris.wiki/SRS#Wall_Kicks else: if isinstance(self._active_piece, I): # I tetrominos have their own wall # kick rules. wall_kick_data = [[(-1, 0), (2, 0), (-1, 2), (2, -1)], [(2, 0), (-1, 0), (2, 1), (-1, -2)], [(1, 0), (-2, 0), (1, -2), (-2, 1)], [(-2, 0), (1, 0), (-2, -1), (1, 2)]] else: wall_kick_data = [[(1, 0), (1, 1), (0, -2), (1, -2)], [(1, 0), (1, -1), (0, 2), (1, 2)], [(-1, 0), (-1, 1), (0, -2), (-1, -2)], [(-1, 0), (-1, -1), (0, 2), (-1, 2)]] for test in [0, 1, 2, 3]: if self._playfield.is_legal_move( self._active_piece, (self._active_piece.coords[0] + wall_kick_data[orientation][test][0], self._active_piece.coords[1] + wall_kick_data[orientation][test][1])): # stop the tests, keep the rotation self._active_piece.coords =\ (self._active_piece.coords[0] + wall_kick_data[orientation][test][0], self._active_piece.coords[1] + wall_kick_data[orientation][test][1]) break else: if test == 3: # If we've gone through all the tests and # no wall kick yields a legal rotation, # rotate our piece back. self._active_piece.rotate_cw() # This dictionary defines the initial coordinates for each type of piece. # There are contradicting definitions for this, so we need to figure out which # we will stick with. initial_coords = { I: (3, 17), J: (3, 17), L: (3, 17), O: (3, 17), S: (3, 17), T: (3, 17), Z: (3, 17) } def update(self): ''' Has the effect of updating the game state. This either means moving the piece down, locking in the piece and dropping the new piece/generating a new self._next_piece_class, or ending the game. Return True if a new piece is spawned ''' if self._game_over: return False else: # Proceed... # If the action is to end the game, set self._game_over = True and return True. # # If the _active_piece is None, start the game by genarating the active piece # and the next piece class objects, and instantiate the active piece with # initial coordinates. if self._active_piece == None: self._gen_next_piece_class() self._active_piece = self._next_piece_class( self.initial_coords[self._next_piece_class]) self._gen_next_piece_class() # If we're able to move down, move the active piece one row down. if self._playfield.is_legal_move( self._active_piece, (self._active_piece.coords[0], self._active_piece.coords[1] - 1)): self._active_piece.coords = (self._active_piece.coords[0], self._active_piece.coords[1] - 1) return False # Otherwise, place the piece, etc. else: self._playfield.insert_piece(self._active_piece, self._active_piece.coords) # clear completed rows if necessary points = [0, 40, 100, 300, 1200] # number of points awarded for each # successively cleared row # This clears filled rows and drops pieces as necessary. Returns # number of rows cleared. num_cleared = self._playfield.clear_filled_rows() # if num_cleared > 0: # print('I cleared a line!') assert (num_cleared >= 0 and num_cleared < 5) self._score += points[num_cleared] # Drop the next piece self._active_piece = self._next_piece_class( self.initial_coords[self._next_piece_class]) self._gen_next_piece_class() # If we can't place the piece, game over if not self._playfield.is_legal_move( self._active_piece, self._active_piece.coords): self._game_over = True return False return True def gamestate(self): return GameState(self._playfield, self._active_piece, self._next_piece_class) @property def game_over(self): return self._game_over
def __init__(self): self.playfield = Playfield() self.playfield.init() pass
class GameState(state.State): tetro_classes = (tetros.Leftsnake, tetros.Rightsnake, tetros.Stick, tetros.Square, tetros.Tee, tetros.Leftgun, tetros.Rightgun) tetro_colors = (Colors.ORANGE, Colors.RED, Colors.BLUE, Colors.YELLOW) def __init__(self): super(GameState, self).__init__() self.falling_tetro = None # nrows should be 22 self.playfield = Playfield(10, 15) self.playfield.rect.centerx = Engine.screenrect.centerx self.playfield.rect.bottom = Engine.screenrect.bottom - block.SIZE self.members.append(self.playfield) # # self.kill() # # start a countdown, and revive ourself when done # self.intro = Countdown(3000, 256, self.revive) # self.intro.rect.center = Engine.screenrect.center # self.members.append(self.intro) def update(self): # escape back to main menu if Engine.is_just_pressed(K_ESCAPE): Engine.switch(states.MainMenuState()) if not self.alive: super(GameState, self).update() return # update falling tetro # X movements if self.falling_tetro is not None: dx = 0 # if Engine.pressed(K_LEFT): dx = -block.SIZE if Engine.pressed(K_RIGHT): dx = block.SIZE # if dx != 0: self.falling_tetro.move(dx, 0) # move it back if any of it's block are now outside the # playfield for tblock in self.falling_tetro.members: if (tblock.rect.x < self.playfield.rect.x or tblock.rect.right > self.playfield.rect.right): self.falling_tetro.move(-dx, 0) break else: # not colliding with "walls" check against well blocks well_blocks = self.playfield.get_well_blocks() for tblock, wblock in itertools.product( self.falling_tetro.members, well_blocks): if tblock.rect.colliderect(wblock.rect): # move it back and land self.falling_tetro.move(-dx, 0) break else: self.falling_tetro.col += 1 if dx > 0 else -1 # Y movements if (self.falling_tetro is not None and self.falling_tetro.dropping): self.falling_tetro.drop_delay_counter += Engine.elapsed if self.falling_tetro.drop_delay_counter > self.falling_tetro.drop_delay: # move and check for collisions dy = block.SIZE self.falling_tetro.move(0, dy) # well_blocks = self.playfield.get_well_blocks() # collision with well bottom for tblock in self.falling_tetro.members: if tblock.rect.bottom > self.playfield.rect.bottom: # move it back and land self.falling_tetro.move(0, -dy) if self.falling_tetro.row < 0: self.kill() return self.falling_tetro.land(self.playfield) self.falling_tetro = None break else: # collision with blocks in the well for tblock, wblock in itertools.product( self.falling_tetro.members, well_blocks): if tblock.rect.colliderect(wblock.rect): # move it back and land self.falling_tetro.move(0, -dy) if self.falling_tetro.row < 0: self.kill() return self.falling_tetro.land(self.playfield) self.falling_tetro = None break else: # update row self.falling_tetro.row += 1 # reset counter self.falling_tetro.drop_delay_counter = 0 # new tetro if needed if self.falling_tetro is None: color = random.choice(self.tetro_colors) tetro_cls = random.choice(self.tetro_classes) # # not giving the startx-y may get the tetromino and playfield out # of sync because startx-y default to zero startx = self.playfield.rect.x + block.SIZE * 4 starty = self.playfield.rect.y - block.SIZE * 4 self.falling_tetro = tetro_cls(color, startx=startx, starty=starty, drop_delay=50) # self.members.append(self.falling_tetro) self.falling_tetro.drop() super(GameState, self).update()
def get_active_board(gamestate): playfield = Playfield() playfield.insert_piece(gamestate._active_piece, gamestate._active_piece.coords) return playfield.get_bool_board().astype(float)
class GameState(state.State): tetro_classes = (tetros.Leftsnake, tetros.Rightsnake, tetros.Stick, tetros.Square, tetros.Tee, tetros.Leftgun, tetros.Rightgun) tetro_colors = (Colors.ORANGE, Colors.RED, Colors.BLUE, Colors.YELLOW) def __init__(self): super(GameState, self).__init__() self.falling_tetro = None # nrows should be 22 self.playfield = Playfield(10, 15) self.playfield.rect.centerx = Engine.screenrect.centerx self.playfield.rect.bottom = Engine.screenrect.bottom - block.SIZE self.members.append(self.playfield) # # self.kill() # # start a countdown, and revive ourself when done # self.intro = Countdown(3000, 256, self.revive) # self.intro.rect.center = Engine.screenrect.center # self.members.append(self.intro) def update(self): # escape back to main menu if Engine.is_just_pressed(K_ESCAPE): Engine.switch(states.MainMenuState()) if not self.alive: super(GameState, self).update() return # update falling tetro # X movements if self.falling_tetro is not None: dx = 0 # if Engine.pressed(K_LEFT): dx = -block.SIZE if Engine.pressed(K_RIGHT): dx = block.SIZE # if dx != 0: self.falling_tetro.move(dx, 0) # move it back if any of it's block are now outside the # playfield for tblock in self.falling_tetro.members: if (tblock.rect.x < self.playfield.rect.x or tblock.rect.right > self.playfield.rect.right): self.falling_tetro.move(-dx, 0) break else: # not colliding with "walls" check against well blocks well_blocks = self.playfield.get_well_blocks() for tblock, wblock in itertools.product( self.falling_tetro.members, well_blocks): if tblock.rect.colliderect(wblock.rect): # move it back and land self.falling_tetro.move(-dx, 0) break else: self.falling_tetro.col += 1 if dx > 0 else -1 # Y movements if (self.falling_tetro is not None and self.falling_tetro.dropping): self.falling_tetro.drop_delay_counter += Engine.elapsed if self.falling_tetro.drop_delay_counter > self.falling_tetro.drop_delay: # move and check for collisions dy = block.SIZE self.falling_tetro.move(0, dy) # well_blocks = self.playfield.get_well_blocks() # collision with well bottom for tblock in self.falling_tetro.members: if tblock.rect.bottom > self.playfield.rect.bottom: # move it back and land self.falling_tetro.move(0, -dy) if self.falling_tetro.row < 0: self.kill() return self.falling_tetro.land(self.playfield) self.falling_tetro = None break else: # collision with blocks in the well for tblock, wblock in itertools.product( self.falling_tetro.members, well_blocks): if tblock.rect.colliderect(wblock.rect): # move it back and land self.falling_tetro.move(0, -dy) if self.falling_tetro.row < 0: self.kill() return self.falling_tetro.land(self.playfield) self.falling_tetro = None break else: # update row self.falling_tetro.row += 1 # reset counter self.falling_tetro.drop_delay_counter = 0 # new tetro if needed if self.falling_tetro is None: color = random.choice(self.tetro_colors) tetro_cls = random.choice(self.tetro_classes) # # not giving the startx-y may get the tetromino and playfield out # of sync because startx-y default to zero startx = self.playfield.rect.x + block.SIZE * 4 starty = self.playfield.rect.y - block.SIZE * 4 self.falling_tetro = tetro_cls(color, startx=startx, starty=starty, drop_delay=50) # self.members.append(self.falling_tetro) self.falling_tetro.drop() super(GameState, self).update()
# Filter out any outcome that doesn't have the lowest cost lowest_cost = min([outcome['cost'] for outcome in outcomes]) outcomes = list( filter(lambda outcome: outcome['cost'] == lowest_cost, outcomes)) # if None was swapped out, ban hold for next turn self.ban_hold = outcomes[0]['tetromino'] == None # With multiple lowest cost outcomes, selection is only affected by # number of keystrokes outcome requires. The lowest outcome in the # list is more likely to not require swap and not require any # rotations return outcomes[0] if __name__ == "__main__": solver = Solver() playfield = Playfield() game_over = False shape = random.choice(Tetromino.SHAPES) tetromino = Tetromino(shape) tetromino = playfield.hold_tetromino(tetromino) score = 0 while not game_over: shape = random.choice(Tetromino.SHAPES) tetromino = Tetromino(shape) chosen_outcome = solver.decide_outcome(playfield, tetromino) playfield.execute_outcome(chosen_outcome, tetromino) print('score = {}, cost = {}'.format(score, chosen_outcome['cost'])) print(playfield) score += 1
import time from pynput import keyboard import config as cfg import input_controls as controls import tetris_sim as sim from tetromino import Tetromino from playfield import Playfield print("Start Tetris AI") # initialize playgrid playgrid = Playfield() # program begins running when user clicks the play button def on_press(key): if(key == keyboard.Key.space): tetro_color = controls.capture_tetromino() input_tetro = Tetromino(color=tetro_color) playgrid.fast_drop(input_tetro) playgrid.print_self() return False with keyboard.Listener( on_press = on_press) as listener: listener.join() start_time = time.time() elapsed_time = 0
def process_video(piece_tracking=False): folder = '/home/alexandre/Downloads/' fileName = '210629' extension = '.mp4' player_name = '' session = SessionStats() pieces_stats = [] cap = cv2.VideoCapture(folder + fileName + extension) cap_width = cap.get(3) cap_height = cap.get(4) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) fourcc = cv2.VideoWriter_fourcc(*'mpeg') defaults = Reader.read_yaml() scale = defaults['frame']['scale'] frame_width = int(defaults['video']['width'] * scale) frame_height = int(defaults['video']['height'] * scale) timing = TimingStats(cap.get(cv2.CAP_PROP_FPS)) out = cv2.VideoWriter('/home/alexandre/Desktop/temp/' + fileName + '.avi', fourcc, timing.fps, (frame_width, frame_height)) playfield = Playfield(defaults['playfield'], scale) hold = None nexts = None current_piece = None current_piece_id = -1 current_piece_srs_rotation = 0 current_piece_column = 0 next_piece = None next_piece_id = -1 prev_hold_id = -1 prev_hold = None prev_frame = None prev_playfield = None frame = None frame_digits = init_frame_digits(defaults['timer'], scale) pieces = [] session.timer = [] timer_prev_digits = [] first_hold = False timer_initialized = False started = False digits_read = False pieces_read = False background_top = False training_complete = False recording = False ended = False prev_hold_frame = -1 entry_frame = -1 end_count = 0 prev_squares_on_top = 0 squares_on_top = 0 piece_lines_cleared = 0 map_frame_time = {} ignore_line_clear = 0 session.piece_count = -1 colors_defined = 0 timing.start_frame = total_frames timing.end_frame = total_frames timing.fastest_time = 13 timing.slowest_time_corrected = 50 timing.slowest_time = 120 timing.total_pieces = 100 camera = False #camera = True #timing.start_frame = 116 #timing.end_frame = 1475 #final_time = [0,3,1,7,5] # pts1 = np.float32([[113, 90], [1200, 80], [116, 700], [1204, 696]]) # pts2 = np.float32([[0, 0], [960, 0], [0, 540], [960, 540]]) # pts1 = np.float32([[53, 144], [1171, 125], [152, 567], [1242, 703]]) # pts2 = np.float32([[84, 143], [892, 99], [154, 439], [960, 540]]) replay_overlay = int(timing.fps * defaults['overlay']['replay_text']) numbers = [] ignore_squares = init_ignore_squares(defaults) ignore_squares_ingame = {} ignore_next = 0 ignore_hold = 0 frame_pieces_update = -1 frame_hold_update = -1 sq_candidates = [] board_updated = 0 last_playfield = None prev_candidates = [] board_id = copy.deepcopy(playfield) board_id.height = defaults['layout']['playfield']['num_rows'] board_id.board = np.zeros((board_id.height, board_id.width)) board_diff = np.zeros_like(playfield.board) while cap.isOpened() and session.frame_count < total_frames: ret, original_frame = cap.read() session.frame_count = int(cap.get(cv2.CAP_PROP_POS_FRAMES)) if camera: matrix = cv2.getPerspectiveTransform(pts1, pts2) frame = cv2.warpPerspective(original_frame, matrix, (960, 540)) else: frame = cv2.resize(original_frame, (frame_width, frame_height)) #original_frame = cv2.resize(original_frame, (frame_width, frame_height)) original_frame = frame set_current_frames(defaults, frame, playfield, hold, nexts, frame_digits) next_changed = nexts_changed(defaults['threshold'], nexts) entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if camera and not started and session.frame_count == timing.start_frame: started = True digits_read = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 # cap.set(cv2.CAP_PROP_POS_FRAMES,timing.start_frame + timing.fps) # ret, frame = cap.read() # frame = cv2.resize(frame, (frame_width, frame_height)) # session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) # print(" Background top set", session.frame_count) # background_top = True # playfield.set_background_top(frame, defaults['overlay']['max_row']) # cap.set(cv2.CAP_PROP_POS_FRAMES,0) # training_complete = True if not camera and not timer_initialized and timer_is_zero( frame_digits, defaults['threshold']): print(' Timer initialized') timer_initialized = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) if (not started and timer_initialized and not timer_digits_match( frame_digits, defaults['threshold'])) and not pieces_read: timing.start_frame = session.frame_count - 1 started = True hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not background_top and next_changed and digits_read: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - 2) ret, frame = cap.read() frame = cv2.resize(frame, (frame_width, frame_height)) session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) print(" Background top set", session.frame_count) background_top = True playfield.set_background_top(frame, defaults['overlay']['max_row']) if not pieces_read and next_changed: id = len(nexts) - 1 if set_piece_color(defaults, pieces, nexts[id]): colors_defined += 1 print('Colors defined', colors_defined) if colors_defined == defaults['sprint']['num_pieces']: print('All colors defined') pieces_read = True if training_complete and session.frame_count >= timing.start_frame and not ended: if piece_tracking: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id current_piece_name = defaults['pieces']['names'][ current_piece_id] current_piece_column = defaults['pieces'][ current_piece_name][ 'spawn_column'] #change current_piece update into a function later print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) if next_changed and not first_hold: current_piece = next_piece current_piece_id = next_piece_id current_piece_name = defaults['pieces']['names'][ current_piece_id] if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True timer_prev_digits = session.timer session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, []) #print(temp_playfield.board) else: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) timer_prev_digits = session.timer if camera: session.timer = Time.frames_to_time( session.frame_count - timing.start_frame, timing.fps) else: session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) #print('Squares on top:', prev_squares_on_top, squares_on_top) #if prev_squares_on_top > 0 and squares_on_top == 0: if ignore_line_clear > 0: ignore_line_clear -= 1 else: temp_lines = line_cleared(defaults['threshold'], playfield) if len(temp_lines) > 0: piece_lines_cleared = len(temp_lines) ignore_line_clear = 20 playfield.clear_lines(temp_lines) #board_id.clear_lines(temp_lines) board_updated = session.piece_count + 1 if len(temp_lines) == 4: min_line = min(temp_lines) board_diff = [(6, 0), (6, 1), (6, 2), (6, 3)] board_id.update_with(board_diff, session.piece_count + 1, session.total_lines) expiry = int(defaults['overlay']['tetris_animation'] * timing.fps + session.frame_count) ignore_squares_ingame = update_ignore_tetris( defaults['overlay'], ignore_squares_ingame, playfield.width, playfield.height, min_line, expiry) if ignore_next > 0: ignore_next -= 1 if ignore_hold > 0: ignore_hold -= 1 if next_changed: entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if ignore_next == 0: ignore_next = entry_delay if not first_hold: #locked piece if session.piece_count >= 0: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - entry_delay - 1) ret, prev_frame = cap.read() if camera: matrix = cv2.getPerspectiveTransform( pts1, pts2) prev_frame = cv2.warpPerspective( prev_frame, matrix, (960, 540)) else: prev_frame = cv2.resize( prev_frame, (frame_width, frame_height)) playfield.set_current_frame(prev_frame) cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, ignore_squares_ingame) ignore_squares_ingame = remove_from_ignore( ignore_squares_ingame, session.frame_count) if prev_playfield is not None: temp_playfield.fill_incorrect_squares( prev_playfield) prev_playfield = copy.deepcopy(playfield) print('Session', session.piece_count, board_updated) print(temp_playfield.board) print('Prev', session.piece_count, board_updated) print(prev_playfield.board) if piece_lines_cleared == 0: board_diff = temp_playfield.board_diff( prev_playfield, defaults['sprint']['num_pieces'], ignore_squares_ingame) if len(board_diff) != 4: print('Missing square here!', len(board_diff)) print(prev_playfield.board) name = defaults['pieces']['names'][ current_piece_id] print(temp_playfield.board) if len(prev_candidates) == 0: candidates = temp_playfield.reconstruct_board( defaults['pieces'], prev_playfield, defaults['pieces'][name]) else: candidates = temp_playfield.reconstruct_board_from_candidates( defaults['pieces'], prev_playfield, prev_candidates, defaults['pieces'][name]) #Manually fix missing pieces #print('Count', session.piece_count) #if session.piece_count == 80: # candidates = [[(3, 7, 0)]] #if session.frame_count == 954: # candidates = [[(4, 6, 3)]] if len(candidates) == 1: for c in candidates[0]: print('cand', c) board_diff = update_board( defaults, c, prev_playfield) piece = defaults['pieces'][ 'names'][c[0]] print(piece) piece_state = np.array( defaults['pieces'][piece] ['rotations'][c[2]]) prev_playfield.hard_drop( piece_state, c[1], c[0]) board_updated += 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) prev_candidates = [] else: print(len(candidates), ' Found', candidates) board_diff = [] prev_candidates = candidates last_playfield = prev_playfield else: board_updated = session.piece_count + 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) #print(board_id.board) playfield.remove_effect(defaults) playfield.set_current_frame(frame) #prev_frame = frame session.piece_count += 1 if session.piece_count > 0: print('Next changed', session.frame_count, session.piece_count) hold_frame = -1 if prev_hold_frame >= entry_frame: hold_frame = prev_hold_frame session.holds += 1 time_diff = Time.frame_to_time_diff( hold_frame, entry_frame, map_frame_time, defaults['timer']) session.hold_time += time_diff if piece_lines_cleared > 0: session.update_lines( defaults['delay'], piece_lines_cleared) pc = False if session.perfect_clear(): pc = True session.perfect_clears += 1 piece_stat = PieceStats( session.piece_count, current_piece_id, entry_frame, session.frame_count, hold_frame, piece_lines_cleared, pc, current_piece, hold.current_frame, board_diff) print('Creating ', piece_stat.count, piece_stat.id) pieces_stats.append(piece_stat) entry_frame = session.frame_count else: first_hold = False frame_pieces_update = session.frame_count current_piece = next_piece current_piece_id = next_piece_id print('Current piece is now', current_piece_id) piece_lines_cleared = 0 if camera: frame_pieces_update += entry_delay if session.frame_count == frame_pieces_update: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Next piece is ', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if ignore_hold == 0: ignore_hold = entry_delay print('Hold changed', session.frame_count) if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) prev_hold_frame = session.frame_count frame_hold_update = session.frame_count if camera: frame_hold_update += entry_delay if session.frame_count == frame_hold_update: print('Updating hold frame', session.frame_count) prev_hold = hold.current_frame if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True # if np.array_equal(timer_prev_digits, session.timer) or session.frame_count >= timing.end_frame: # end_count += 1 # if camera: # session.timer = final_time # if end_count >= defaults['timer']['end_count']: # timing.end_frame = session.frame_count - defaults['timer']['end_count'] # print(" Final time:", session.timer, timing.end_frame) # ended = True # else: # end_count = 0 if session.frame_count > timing.start_frame and session.frame_count < timing.start_frame + timing.fps and not digits_read: frame_count_diff = session.frame_count - timing.start_frame div = round(timing.fps) // 10 remainder = div // 2 if frame_count_diff % div == remainder: print("Digits read", len(numbers)) numbers = store_number( numbers, frame_digits[defaults['timer']['decisecond']], defaults['threshold']['digit']) if len(numbers) == defaults['timer']['numbers']: #frame_count = advance_time(frame_count,fps,defaults['timer']['time_advance']) digits_read = True #cap.set(cv2.CAP_PROP_POS_FRAMES,frame_count) if not training_complete and background_top and digits_read and pieces_read: cap.set(cv2.CAP_PROP_POS_FRAMES, 0) training_complete = True back_diff = Draw.draw_background_diff(playfield, hold, frame) #if session.frame_count > 1: # prev_diff = Draw.draw_previous_frame_diff(playfield, hold, frame, nexts) #current = Draw.draw_current_frame(defaults, playfield, frame_digits, current_piece, next_piece, frame) last_piece_time = [] if session.piece_count > 0: entry_delay = int(defaults['delay']['entry'] * timing.fps) last_piece_frame = pieces_stats[session.piece_count - 1].end_frame - entry_delay last_piece_time = map_frame_time[last_piece_frame] if session.frame_count < timing.start_frame: session.timer = [0, 0, 0, 0, 0] elif training_complete and session.frame_count < timing.end_frame + 3 * timing.fps: print(session.frame_count, timing.fps, timing.end_frame + 2 * timing.fps) original_frame = Draw.draw_time_stats(defaults, original_frame, frame_width, frame_height, session, last_piece_time, board_id, pieces_stats, map_frame_time, timing) original_frame = Draw.draw_pieces_stats(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) original_frame = Draw.draw_lines_stats(defaults, original_frame, frame_width, frame_height, timing, session, last_piece_time) original_frame = Draw.draw_playfield(defaults, original_frame, frame_width, frame_height, board_id, pieces_stats, timing, map_frame_time) #original_frame = Draw.draw_player_info(defaults['layout']['player'], original_frame, frame_width, frame_height, player_name) #original_frame = Draw.draw_histogram(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) print("Frame", session.frame_count, "/", total_frames, session.timer) if recording: out.write(original_frame) if training_complete: recording = True cv2.imshow('frame', original_frame) #if prev_frame is not None: # cv2.imshow('timer', prev_frame) #cv2.imshow('back_diff',back_diff) #if session.frame_count > 1: # cv2.imshow('prev_diff',prev_diff) key = cv2.waitKey(1) #while key not in [ord('q'), ord('k'),ord('l')]: # key = cv2.waitKey(0) if key == ord('l'): session.frame_count -= 5 if session.frame_count < 0: session.frame_count = 0 cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) elif key == ord('q'): break cap.release() out.release() cv2.destroyAllWindows()
class Game: def __init__(self, surface, username, numberOfPlayers, soundsOn): # Initialize variables self.__clock = pygame.time.Clock() self.__surface = surface self.__isRunning = True self.__username = username self.__numberOfPlayers = numberOfPlayers self.__soundsOn = soundsOn # Initialize the game entities self.__ball = Ball(self.__surface) self.__score = self.__ball.get_score() self.__playfield = Playfield(self.__surface, self.__username, self.__score) self.__surface = self.__playfield.get_surface() self.__snake = Snake(self.__surface, self.__isRunning) self.__food = Food(self.__surface) # Check if multiplayer or not if self.__numberOfPlayers == 0: self.__paddle = Paddle(self.__surface) else: self.__paddle = Paddle(self.__surface, True) def start_game(self): while self.__isRunning: # Check if game is being closed manually for event in pygame.event.get(): if event.type == pygame.QUIT: self.__isRunning = False # Check if game is done if self.__snake.game_over(): self.__isRunning = False mixer.music.stop() self.__play_gameover_sound() Tk().wm_withdraw() # Pop-up screen using tkinter library messagebox.showinfo( 'GAME OVER - You a dead snake bruv', 'I admit that I touched myself/walls :\'(') # Check if snake eats the food elif self.__snake.get_head().colliderect(self.__food.show_food()): self.__snake.set_length() self.__play_touch_sound() self.__food.update_food() # Check if the paddle touches the ball elif self.__paddle.get_paddle().colliderect( self.__ball.get_ball()): self.__ball.bounce() self.__play_touch_sound() # Check if one of the segments of the snake touches the ball for segment in self.__snake.get_snake(): if segment.colliderect(self.__ball.get_ball()): self.__ball.bounce() self.__play_touch_sound() # Continously update the game with the new values/info self.__update_game() def __update_game(self): self.__surface.fill((0, 0, 0)) self.__score = self.__ball.get_score() Playfield(self.__surface, self.__username, self.__score) self.__snake.update_snake() self.__food.look_for_food() self.__paddle.update_paddle() self.__ball.update_ball() pygame.display.flip() self.__clock.tick(60) # Check if sounds are activated or not and then play them accordingly def __play_touch_sound(self): if self.__soundsOn: touch = mixer.Sound("assets/touch_sound.wav") mixer.Sound.play(touch) def __play_gameover_sound(self): if self.__soundsOn: gameover = mixer.Sound("assets/game_over_sound.wav") mixer.Sound.play(gameover) # Code for testing the Game class def get_username(self): return self.__username def get_numberOfPlayers(self): return self.__numberOfPlayers
def test_creating_playfield(): playfield = Playfield(surface, "Noah", 7) assert playfield.get_surface() == surface assert playfield.get_username() == "Noah" assert playfield.get_score() == 7
#!usr/bin/env python3 # Attempts to play tetris using simple CV and keyboard inputs # Intended for tetris link: https://tetris.com/play-tetris from tetromino import Tetromino from playfield import Playfield from solver import Solver from agent import Agent agent = Agent() sample = 'waiting' solver = Solver() playfield = Playfield() current_tetromino = agent.start_game() block_num = 0 game_over = False while not game_over: block_num += 1 # decide outcome chosen_outcome = solver.decide_outcome(playfield, current_tetromino) # execute outcome next_shape = agent.execute_outcome_and_sample(chosen_outcome, interval=0.04, sleep=0.4) playfield.execute_outcome(chosen_outcome, current_tetromino)
row]: # ...and for every element 'i' in that row... pin_off_pub.publish(curr_light.pin) # Turn off flippers flipper_off(myPlay.left_flipper) flipper_off(myPlay.right_flipper) # Turn off all coils for coil in myPlay.coils: pin_off_pub.publish(coil.pin) schedule.shutdown() # The status of the playfield, lights, switches, score, etc myPlay = Playfield() # ROS initialization and shutdown rospy.init_node('low_level') rospy.on_shutdown(signal_handler) # Ros services to return the lights and switches get_light_service = rospy.Service('get_light', get_light, handle_get_light) get_switch_service = rospy.Service('get_switch', get_switch, handle_get_switch) # ROS subscriber to change the status of a light from blinking to not or vice versa override_light_sub = rospy.Subscriber("override_light", override_light, handle_override_light) # ROS subscribers for each switch that will exist on the playfield # TOP
def process_video(video_name, total_pieces): session = SessionStats() pieces_stats = [] parent_path = Path(os.getcwd()).parent.absolute() cap = cv2.VideoCapture(os.path.join(parent_path, 'input', video_name)) cap_width = cap.get(3) cap_height = cap.get(4) total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT) fourcc = cv2.VideoWriter_fourcc(*'mpeg') defaults = Reader.read_yaml() scale = defaults['frame']['scale'] frame_width = int(defaults['video']['width'] * scale) frame_height = int(defaults['video']['height'] * scale) timing = TimingStats(cap.get(cv2.CAP_PROP_FPS)) print(os.path.join(os.getcwd(), video_name)) out = cv2.VideoWriter(os.path.join(parent_path, 'output', video_name), fourcc, timing.fps, (frame_width, frame_height)) playfield = Playfield(defaults['playfield'], scale) hold = None nexts = None current_piece = None current_piece_id = -1 next_piece = None next_piece_id = -1 prev_hold_id = -1 prev_hold = None prev_frame = None prev_playfield = None frame = None frame_digits = init_frame_digits(defaults['timer'], scale) pieces = [] session.timer = [] timer_prev_digits = [] first_hold = False timer_initialized = False started = False digits_read = False pieces_read = False background_top = False training_complete = False recording = False ended = False prev_hold_frame = -1 entry_frame = -1 end_count = 0 prev_squares_on_top = 0 squares_on_top = 0 piece_lines_cleared = 0 map_frame_time = {} ignore_line_clear = 0 session.piece_count = -1 colors_defined = 0 timing.start_frame = total_frames timing.end_frame = total_frames timing.fastest_time = 13 timing.slowest_time_corrected = 50 timing.slowest_time = 120 timing.total_pieces = total_pieces camera = False replay_overlay = int(timing.fps * defaults['overlay']['replay_text']) numbers = [] ignore_squares = init_ignore_squares(defaults) ignore_squares_ingame = {} ignore_next = 0 ignore_hold = 0 frame_pieces_update = -1 frame_hold_update = -1 sq_candidates = [] board_updated = 0 last_playfield = None prev_candidates = [] board_id = copy.deepcopy(playfield) board_id.height = defaults['layout']['playfield']['num_rows'] board_id.board = np.zeros((board_id.height, board_id.width)) board_diff = np.zeros_like(playfield.board) while cap.isOpened() and session.frame_count < total_frames: ret, original_frame = cap.read() session.frame_count = int(cap.get(cv2.CAP_PROP_POS_FRAMES)) if camera: matrix = cv2.getPerspectiveTransform(pts1, pts2) frame = cv2.warpPerspective(original_frame, matrix, (960, 540)) else: frame = cv2.resize(original_frame, (frame_width, frame_height)) #original_frame = cv2.resize(original_frame, (frame_width, frame_height)) original_frame = frame set_current_frames(defaults, frame, playfield, hold, nexts, frame_digits) next_changed = nexts_changed(defaults['threshold'], nexts) if camera and not started and session.frame_count == timing.start_frame: started = True digits_read = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not camera and not timer_initialized and timer_is_zero( frame_digits, defaults['threshold']): print(' Timer initialized') timer_initialized = True playfield.set_background_bottom(frame, defaults['overlay']['max_row']) if (not started and timer_initialized and not timer_digits_match( frame_digits, defaults['threshold'])) and not pieces_read: timing.start_frame = session.frame_count - 1 started = True hold = init_hold(defaults['hold'], scale) nexts = init_nexts(defaults, scale) hold.set_background(frame) pieces = init_pieces(defaults) for i in range(len(nexts)): nexts[i].set_background(frame) nexts[i].set_current_frame(frame) if set_piece_color(defaults, pieces, nexts[i]): print('Color set') colors_defined += 1 if not background_top and next_changed and digits_read: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - 2) ret, frame = cap.read() frame = cv2.resize(frame, (frame_width, frame_height)) session.frame_count = cap.get(cv2.CAP_PROP_POS_FRAMES) print(" Background top set", session.frame_count) background_top = True playfield.set_background_top(frame, defaults['overlay']['max_row']) if not pieces_read and next_changed: id = len(nexts) - 1 if set_piece_color(defaults, pieces, nexts[id]): colors_defined += 1 print('Colors defined', colors_defined) if colors_defined == defaults['sprint']['num_pieces']: print('All colors defined') pieces_read = True if training_complete and session.frame_count >= timing.start_frame and not ended: if session.frame_count == timing.start_frame: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Setting next piece id', next_piece_id) timer_prev_digits = session.timer if camera: session.timer = Time.frames_to_time( session.frame_count - timing.start_frame, timing.fps) else: session.timer = match_digits(frame_digits, numbers, defaults['threshold']) map_frame_time[session.frame_count] = session.timer prev_squares_on_top = squares_on_top squares_on_top = piece_on_top(defaults, playfield, ignore_squares) if ignore_line_clear > 0: ignore_line_clear -= 1 else: temp_lines = line_cleared(defaults['threshold'], playfield) if len(temp_lines) > 0: piece_lines_cleared = len(temp_lines) ignore_line_clear = 20 playfield.clear_lines(temp_lines) #board_id.clear_lines(temp_lines) board_updated = session.piece_count + 1 if len(temp_lines) == 4: min_line = min(temp_lines) board_diff = [(6, 0), (6, 1), (6, 2), (6, 3)] board_id.update_with(board_diff, session.piece_count + 1, session.total_lines) expiry = int(defaults['overlay']['tetris_animation'] * timing.fps + session.frame_count) ignore_squares_ingame = update_ignore_tetris( defaults['overlay'], ignore_squares_ingame, playfield.width, playfield.height, min_line, expiry) if ignore_next > 0: ignore_next -= 1 if ignore_hold > 0: ignore_hold -= 1 if next_changed: entry_delay = np.round(defaults['delay']['entry'] * timing.fps) if ignore_next == 0: ignore_next = entry_delay if not first_hold: #locked piece if session.piece_count >= 0: cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count - entry_delay - 1) ret, prev_frame = cap.read() if camera: matrix = cv2.getPerspectiveTransform( pts1, pts2) prev_frame = cv2.warpPerspective( prev_frame, matrix, (960, 540)) else: prev_frame = cv2.resize( prev_frame, (frame_width, frame_height)) playfield.set_current_frame(prev_frame) cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) temp_playfield = copy.deepcopy(playfield) update_playfield(defaults, temp_playfield, pieces, ignore_squares_ingame) ignore_squares_ingame = remove_from_ignore( ignore_squares_ingame, session.frame_count) if prev_playfield is not None: temp_playfield.fill_incorrect_squares( prev_playfield) prev_playfield = copy.deepcopy(playfield) print('Session', session.piece_count, board_updated) print(temp_playfield.board) print('Prev', session.piece_count, board_updated) print(prev_playfield.board) if piece_lines_cleared == 0: board_diff = temp_playfield.board_diff( prev_playfield, defaults['sprint']['num_pieces'], ignore_squares_ingame) if len(board_diff) != 4: print('Missing square here!', len(board_diff)) print(prev_playfield.board) name = defaults['pieces']['names'][ current_piece_id] print(temp_playfield.board) if len(prev_candidates) == 0: candidates = temp_playfield.reconstruct_board( defaults['pieces'], prev_playfield, defaults['pieces'][name]) else: candidates = temp_playfield.reconstruct_board_from_candidates( defaults['pieces'], prev_playfield, prev_candidates, defaults['pieces'][name]) if len(candidates) == 1: for c in candidates[0]: print('cand', c) board_diff = update_board( defaults, c, prev_playfield) piece = defaults['pieces'][ 'names'][c[0]] print(piece) piece_state = np.array( defaults['pieces'][piece] ['rotations'][c[2]]) prev_playfield.hard_drop( piece_state, c[1], c[0]) board_updated += 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) prev_candidates = [] else: print(len(candidates), ' Found', candidates) board_diff = [] prev_candidates = candidates last_playfield = prev_playfield else: board_updated = session.piece_count + 1 playfield.update_with( board_diff, current_piece_id, 0) board_id.update_with( board_diff, board_updated, session.total_lines) playfield.remove_effect(defaults) playfield.set_current_frame(frame) session.piece_count += 1 if session.piece_count > 0: print('Next changed', session.frame_count, session.piece_count) hold_frame = -1 if prev_hold_frame >= entry_frame: hold_frame = prev_hold_frame session.holds += 1 time_diff = Time.frame_to_time_diff( hold_frame, entry_frame, map_frame_time, defaults['timer']) session.hold_time += time_diff if piece_lines_cleared > 0: session.update_lines(defaults['delay'], piece_lines_cleared) pc = False if session.perfect_clear(): pc = True session.perfect_clears += 1 piece_stat = PieceStats( session.piece_count, current_piece_id, entry_frame, session.frame_count, hold_frame, piece_lines_cleared, pc, current_piece, hold.current_frame, board_diff) print('Creating ', piece_stat.count, piece_stat.id) pieces_stats.append(piece_stat) entry_frame = session.frame_count else: first_hold = False frame_pieces_update = session.frame_count current_piece = next_piece current_piece_id = next_piece_id print('Current piece is now', current_piece_id) piece_lines_cleared = 0 if camera: frame_pieces_update += entry_delay if session.frame_count == frame_pieces_update: next_piece = nexts[0].current_frame next_piece_id = FrameProcessing.map_frame_to_piece( defaults, next_piece, pieces) print('Next piece is ', next_piece_id) if hold_changed(defaults['threshold'], hold, session): if ignore_hold == 0: ignore_hold = entry_delay print('Hold changed', session.frame_count) if prev_hold is not None: current_piece = prev_hold print('Current id was', current_piece_id, 'hold id was', prev_hold_id) current_piece_id, prev_hold_id = prev_hold_id, current_piece_id print('Current id is now', current_piece_id, 'hold id is', prev_hold_id) else: first_hold = True prev_hold_id = current_piece_id print('First Hold. Hold id is', prev_hold_id) prev_hold_frame = session.frame_count frame_hold_update = session.frame_count if camera: frame_hold_update += entry_delay if session.frame_count == frame_hold_update: print('Updating hold frame', session.frame_count) prev_hold = hold.current_frame if session.total_lines == 40: timing.end_frame = session.frame_count - defaults['timer'][ 'end_count'] ended = True if session.frame_count > timing.start_frame and session.frame_count < timing.start_frame + timing.fps and not digits_read: frame_count_diff = session.frame_count - timing.start_frame div = round(timing.fps) // 10 remainder = div // 2 if frame_count_diff % div == remainder: print("Digits read", len(numbers)) numbers = store_number( numbers, frame_digits[defaults['timer']['decisecond']], defaults['threshold']['digit']) if len(numbers) == defaults['timer']['numbers']: digits_read = True if not training_complete and background_top and digits_read and pieces_read: cap.set(cv2.CAP_PROP_POS_FRAMES, 0) training_complete = True back_diff = Draw.draw_background_diff(playfield, hold, frame) last_piece_time = [] if session.piece_count > 0: entry_delay = int(defaults['delay']['entry'] * timing.fps) last_piece_frame = pieces_stats[session.piece_count - 1].end_frame - entry_delay last_piece_time = map_frame_time[last_piece_frame] if session.frame_count < timing.start_frame: session.timer = [0, 0, 0, 0, 0] elif training_complete and session.frame_count < timing.end_frame + 3 * timing.fps: print(session.frame_count, timing.fps, timing.end_frame + 2 * timing.fps) original_frame = Draw.draw_time_stats(defaults, original_frame, frame_width, frame_height, session, last_piece_time, board_id, pieces_stats, map_frame_time, timing) original_frame = Draw.draw_pieces_stats(defaults, original_frame, pieces_stats, frame_width, frame_height, map_frame_time, timing, session) original_frame = Draw.draw_lines_stats(defaults, original_frame, frame_width, frame_height, timing, session, last_piece_time) original_frame = Draw.draw_playfield(defaults, original_frame, frame_width, frame_height, board_id, pieces_stats, timing, map_frame_time) print("Frame", session.frame_count, "/", total_frames, session.timer) if recording: out.write(original_frame) if training_complete: recording = True cv2.imshow('frame', original_frame) key = cv2.waitKey(1) #while key not in [ord('q'), ord('k'),ord('l')]: # key = cv2.waitKey(0) if key == ord('l'): session.frame_count -= 5 if session.frame_count < 0: session.frame_count = 0 cap.set(cv2.CAP_PROP_POS_FRAMES, session.frame_count) elif key == ord('q'): break cap.release() out.release() cv2.destroyAllWindows()
def __init__(self): self.genes = np.array(random.sample(range(-100, 100), cfg.NUM_WEIGHTS)) / 100 self.playgrid = Playfield() self.score = 0 self.piece_count = 0