diff options
-rwxr-xr-x | cameltris.py | 305 |
1 files changed, 155 insertions, 150 deletions
diff --git a/cameltris.py b/cameltris.py index e7b2b1c..b850685 100755 --- a/cameltris.py +++ b/cameltris.py @@ -131,18 +131,20 @@ class TPiece(Piece): def refresh_game_canvas(): + global player + game_canvas.fill(black) - for row_idx, row in enumerate(grid): + for row_idx, row in enumerate(player.grid): for col_idx, element in enumerate(row): if element is not None: game_canvas.blit(element, (col_idx * 50 + 1, row_idx * 50 + 1)) # Display the current piece - for row_idx, row in enumerate(current_piece.elements): + for row_idx, row in enumerate(player.current_piece.elements): for col_idx, element in enumerate(row): if element is not None: - game_canvas.blit(element, ((col_idx + current_piece_position[1]) * 50 + 1, (row_idx + current_piece_position[0]) * 50 + 1)) + game_canvas.blit(element, ((col_idx + player.current_piece_position[1]) * 50 + 1, (row_idx + player.current_piece_position[0]) * 50 + 1)) def refresh_right_pane_canvas(): level_canvas.fill(black) @@ -151,8 +153,8 @@ def refresh_right_pane_canvas(): if pygame.font: score_font = pygame.font.Font(None, 56) - score_canvas.blit(score_font.render(f"{score:08d}", True, white), (0, 0)) - level_canvas.blit(score_font.render(f"{level:08d}", True, white), (0, 0)) + score_canvas.blit(score_font.render(f"{player.score:08d}", True, white), (0, 0)) + level_canvas.blit(score_font.render(f"{player.level:08d}", True, white), (0, 0)) right_pane_canvas.blit(score_canvas, (2, 10)) right_pane_canvas.blit(level_canvas, (2, 70)) @@ -161,12 +163,12 @@ def refresh_piece_preview_canvas(): piece_preview_canvas.fill(black) non_empty_rows = list() - for row in next_piece.elements: + for row in player.next_piece.elements: if any(map(lambda element: element is not None, row)): non_empty_rows.append(row) non_empty_cols = set() - for row in next_piece.elements: + for row in player.next_piece.elements: for col_id, element in enumerate(row): if element is not None: non_empty_cols.add(col_id) @@ -189,128 +191,143 @@ def refresh_screen(): screen.blit(right_pane_canvas, (501, 0)) -def has_collision(y: int, x: int) -> bool: - try: - for row_id, row in enumerate(current_piece.elements): - for col_id, element in enumerate(row): - if element is None: - continue +class Player: + def __init__(self, controller): + self.controller = controller + self.grid = [[None for _ in range(10)] for _ in range(20)] - if row_id + y < 0: - continue + self.current_piece, self.current_piece_position = self.generate_piece() + self.next_piece, self.next_piece_position = self.generate_piece() + + self.starting_level = self.level = 1 + self.score = 0 + + self.lines_burnt = 0 + + self.das = 0 + self.pressing_down_countdown = None + + self.piece_drop_frames = 0 + + def generate_piece(self): + # We may want to make this a function outside the class + piece = random.choice((TPiece, SPiece, IPiece, ZPiece, SquarePiece, LPiece, JPiece))() - if col_id + x < 0: - return True + for row_id, row in enumerate(piece.elements): + if list(filter(lambda x: x is not None, row)): + break - if grid[row_id + y][col_id + x] is not None: - return True + initial_y_position = -row_id + initial_x_position = (len(self.grid[0]) // 2) - (len(piece.elements[0]) // 2) - except IndexError: - return True + return (piece, [initial_y_position, initial_x_position]) - return False + def burn_rows(self): + rows_to_burn = list() -def move_piece_down(): - if not has_collision(current_piece_position[0] + 1, current_piece_position[1]): - current_piece_position[0] += 1 - else: - raise WouldCollide() + for row in self.grid: + if all(map(lambda element: element is not None, row)): + rows_to_burn.append(row) -def move_piece_up(): - if not has_collision(current_piece_position[0] - 1, current_piece_position[1]): - current_piece_position[0] -= 1 - else: - raise WouldCollide() + for row in rows_to_burn: + self.grid.insert(0, [None for _ in range(10)]) + self.grid.remove(row) -def move_piece_left(): - if not has_collision(current_piece_position[0], current_piece_position[1] - 1): - current_piece_position[1] -= 1 - else: - raise WouldCollide() + return len(rows_to_burn) -def move_piece_right(): - if not has_collision(current_piece_position[0], current_piece_position[1] + 1): - current_piece_position[1] += 1 - else: - raise WouldCollide() + def stick_piece(self): + for row_id, row in enumerate(self.current_piece.elements): + for col_id, element in enumerate(row): + if element is None: + continue + self.grid[row_id + self.current_piece_position[0]][col_id + self.current_piece_position[1]] = element + + count = self.burn_rows() + + if count == 1: + print("Single") + rate = 1 + elif count == 2: + print("Double") + rate = 2.5 + elif count == 3: + print("Triple") + rate = 7.5 + elif count == 4: + print("Tetris!") + rate = 30 + else: + rate = 0 -def rotate_piece_counter_clockwise(): - current_piece.rotate_counter_clockwise() + self.lines_burnt += count - if has_collision(current_piece_position[0], current_piece_position[1]): - current_piece.rotate_clockwise() - raise WouldCollide() + self.score += int(self.level * 40 * rate) -def rotate_piece_clockwise(): - current_piece.rotate_clockwise() + if self.lines_burnt >= self.level * 10: + self.level += 1 + self.current_piece, self.current_piece_position = self.next_piece, self.next_piece_position + self.next_piece, self.next_piece_position = self.generate_piece() + refresh_piece_preview_canvas() - if has_collision(current_piece_position[0], current_piece_position[1]): - current_piece.rotate_counter_clockwise() - raise WouldCollide() + def has_collision(self, y: int, x: int) -> bool: + try: + for row_id, row in enumerate(self.current_piece.elements): + for col_id, element in enumerate(row): + if element is None: + continue + if row_id + y < 0: + continue -def generate_piece(): - piece = random.choice((TPiece, SPiece, IPiece, ZPiece, SquarePiece, LPiece, JPiece))() + if col_id + x < 0: + return True - for row_id, row in enumerate(piece.elements): - if list(filter(lambda x: x is not None, row)): - break + if self.grid[row_id + y][col_id + x] is not None: + return True - initial_y_position = -row_id - initial_x_position = (len(grid[0]) // 2) - (len(piece.elements[0]) // 2) + except IndexError: + return True - return (piece, [initial_y_position, initial_x_position]) + return False + def move_piece_down(self): + if not self.has_collision(self.current_piece_position[0] + 1, self.current_piece_position[1]): + self.current_piece_position[0] += 1 + else: + raise WouldCollide() -def burn_rows(): - rows_to_burn = list() + def move_piece_up(self): + if not self.has_collision(self.current_piece_position[0] - 1, self.current_piece_position[1]): + self.current_piece_position[0] -= 1 + else: + raise WouldCollide() - for row in grid: - if all(map(lambda element: element is not None, row)): - rows_to_burn.append(row) + def move_piece_left(self): + if not self.has_collision(self.current_piece_position[0], self.current_piece_position[1] - 1): + self.current_piece_position[1] -= 1 + else: + raise WouldCollide() - for row in rows_to_burn: - grid.insert(0, [None for _ in range(10)]) - grid.remove(row) + def move_piece_right(self): + if not self.has_collision(self.current_piece_position[0], self.current_piece_position[1] + 1): + self.current_piece_position[1] += 1 + else: + raise WouldCollide() - return len(rows_to_burn) + def rotate_piece_counter_clockwise(self): + self.current_piece.rotate_counter_clockwise() + if self.has_collision(self.current_piece_position[0], self.current_piece_position[1]): + self.current_piece.rotate_clockwise() + raise WouldCollide() -def stick_piece(): - global current_piece, current_piece_position, next_piece, next_piece_position, lines_burnt, level, score + def rotate_piece_clockwise(self): + self.current_piece.rotate_clockwise() + + if has_collision(self.current_piece_position[0], self.current_piece_position[1]): + self.current_piece.rotate_counter_clockwise() + raise WouldCollide() - for row_id, row in enumerate(current_piece.elements): - for col_id, element in enumerate(row): - if element is None: - continue - grid[row_id + current_piece_position[0]][col_id + current_piece_position[1]] = element - - count = burn_rows() - - if count == 1: - print("Single") - rate = 1 - elif count == 2: - print("Double") - rate = 2.5 - elif count == 3: - print("Triple") - rate = 7.5 - elif count == 4: - print("Tetris!") - rate = 30 - else: - rate = 0 - - lines_burnt += count - - score += int(level * 40 * rate) - - if lines_burnt >= level * 10: - level += 1 - current_piece, current_piece_position = next_piece, next_piece_position - next_piece, next_piece_position = generate_piece() - refresh_piece_preview_canvas() PARSER = argparse.ArgumentParser() @@ -345,38 +362,26 @@ piece_preview_canvas = pygame.Surface((200, 200)) score_canvas = pygame.Surface((296, 50)) level_canvas = pygame.Surface((296, 50)) -grid = [[None for _ in range(10)] for _ in range(20)] -current_piece, current_piece_position = generate_piece() -next_piece, next_piece_position = generate_piece() +if ARGS["joystick_id"] is not None: + joystick = pygame.joystick.Joystick(ARGS["joystick_id"]) + joystick.init() + controller = JoystickController(joystick) +else: + controller = KeyboardController(pygame.key) + +player = Player(controller) refresh_piece_preview_canvas() # Number of frames frames_per_gridcell = [48, 43, 38, 33, 28, 23, 18, 13, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1] -piece_drop_frames = 0 - -starting_level = level = 1 -score = 0 clock = pygame.time.Clock() -lines_burnt = 0 - -das = 0 - -pressing_down_countdown = None - -if ARGS["joystick_id"] is not None: - joystick = pygame.joystick.Joystick(ARGS["joystick_id"]) - joystick.init() - controller = JoystickController(joystick) -else: - controller = KeyboardController(pygame.key) - while True: - piece_drop_frames += 1 + player.piece_drop_frames += 1 for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -386,50 +391,50 @@ while True: sys.exit() with contextlib.suppress(WouldCollide): if controller.get_input_down(event) == Input.MOVE_RIGHT: - move_piece_right() - das = 0 + player.move_piece_right() + player.das = 0 if controller.get_input_down(event) == Input.MOVE_LEFT: - move_piece_left() - das = 0 + player.move_piece_left() + player.das = 0 if controller.get_input_down(event) == Input.ROTATE_CLOCKWISE: - rotate_piece_clockwise() + player.rotate_piece_clockwise() if controller.get_input_down(event) == Input.ROTATE_COUNTER_CLOCKWISE: - rotate_piece_counter_clockwise() + player.rotate_piece_counter_clockwise() if controller.get_input_down(event) == Input.MOVE_DOWN: - piece_drop_frames = 0 - pressing_down_countdown = 3 + player.piece_drop_frames = 0 + player.pressing_down_countdown = 3 try: - move_piece_down() + player.move_piece_down() except WouldCollide: - stick_piece() + player.stick_piece() elif event.type == controller.upevent: if controller.get_input_up(event) == Input.MOVE_DOWN: - pressing_down_countdown = None + player.pressing_down_countdown = None - das += 1 - if das == 16: + player.das += 1 + if player.das == 16: with contextlib.suppress(WouldCollide): if controller.is_pressed(Input.MOVE_RIGHT): - move_piece_right() + player.move_piece_right() if controller.is_pressed(Input.MOVE_LEFT): - move_piece_left() - das = 10 + player.move_piece_left() + player.das = 10 - if pressing_down_countdown == 0: + if player.pressing_down_countdown == 0: try: - move_piece_down() + player.move_piece_down() except WouldCollide: - stick_piece() - pressing_down_countdown = 2 - elif pressing_down_countdown is not None: - pressing_down_countdown -= 1 + player.stick_piece() + player.pressing_down_countdown = 2 + elif player.pressing_down_countdown is not None: + player.pressing_down_countdown -= 1 - if piece_drop_frames >= frames_per_gridcell[level - 1]: - piece_drop_frames = 0 + if player.piece_drop_frames >= frames_per_gridcell[player.level - 1]: + player.piece_drop_frames = 0 try: - move_piece_down() + player.move_piece_down() except WouldCollide: - stick_piece() + player.stick_piece() refresh_screen() pygame.display.update() |