class GameState(TytrysState): """Game Logic """ def __init__(self, window): super(GameState, self).__init__(window) # These lines are so that I don't have to stare at warnings # restart sets these to the right values self.board = Board(10, 22) self.next_piece = random_tetromino(0, 0) self.current_piece = random_tetromino(5, 20) self.drop_time = .5 self.current_key = -1 self.lines_to_next_level = 15 self.level = 1 self.score = 0 self.view_modified = True self._restart() self.board_window = window.derwin( self.board.height, self.board.width + 2, 0, 0) self.info_window = window.derwin( self.board.height, 8, 0, self.board.width + 2) def _restart(self): """Restart game with default values""" self.board = Board(10, 22) self.next_piece = random_tetromino(0, 0) self.current_piece = random_tetromino(5, 20) self.drop_time = .5 self.current_key = -1 self.lines_to_next_level = 15 self.level = 1 self.score = 0 self.view_modified = True def process_messages(self): while not self.messages.empty(): if self.messages.get() == "restart": self._restart() self.window.clear() def handle_user_input(self): direction = None key_pressed = self.window.getch() if key_pressed in (ord('j'), ord('J'), curses.KEY_LEFT): direction = Direction.Left elif key_pressed in (ord('l'), ord('L'), curses.KEY_RIGHT): direction = Direction.Right elif key_pressed in (ord('i'), ord('I'), curses.KEY_UP): direction = Direction.CCW elif key_pressed in (ord('k'), ord('K'), curses.KEY_DOWN): direction = Direction.CW elif key_pressed in (ord('q'), ord('Q')): self.view_modified = True game.switch_to_state("paused") elif key_pressed == ord(' '): self.drop_current_piece() if direction is not None: if direction == Direction.CCW or direction == Direction.CW: if self.board.are_valid_coordinates( self.current_piece.rotate_result(direction)): renderer.clear_tetromino(self.current_piece, self.board_window) self.view_modified = True self.current_piece.rotate(direction) else: if self.board.are_valid_coordinates( self.current_piece.move_result(direction)): renderer.clear_tetromino(self.current_piece, self.board_window) self.view_modified = True self.current_piece.move(direction) def drop_current_piece(self): self.view_modified = True renderer.clear_tetromino(self.current_piece, self.board_window) while self.board.are_valid_coordinates( self.current_piece.move_result(Direction.Down)): self.current_piece.move(Direction.Down) def draw(self): if self.view_modified: self.view_modified = False renderer.draw_board(self.board, self.board_window) renderer.draw_tetromino(self.current_piece, self.board_window) self.board_window.refresh() self._draw_info() def _draw_info(self): self.info_window.border() self.info_window.addstr(1, 1, "Tytrys") self.info_window.hline(2, 1, ord('_'), 6) self.info_window.addstr(4, 1, "Next:") self.next_piece.set_location(3, 14) # little hacky renderer.draw_tetromino(self.next_piece, self.info_window) self.info_window.addstr(10, 1, "Score:") self.info_window.addstr(11, 1, str(self.score)) self.info_window.addstr(14, 1, "Level:") self.info_window.addstr(15, 3, str(self.level)) self.info_window.addstr(18, 1, "Lines:") self.info_window.addstr(19, 1, str(self.lines_to_next_level) + " ") self.info_window.refresh() def update(self, delta): self.elapsed_time += delta self.handle_user_input() if self.elapsed_time >= self.drop_time: if self.board.are_valid_coordinates( self.current_piece.move_result(Direction.Down)): renderer.clear_tetromino(self.current_piece, self.board_window) self.current_piece.move(Direction.Down) else: renderer.clear_tetromino(self.next_piece, self.info_window) try: self.board.lock_tetromino(self.current_piece) self.current_piece = self.next_piece self.current_piece.set_location(5, 20) self.next_piece = random_tetromino(0, 0) rows_removed = self.board.clear_full_rows() if rows_removed: self.lines_to_next_level -= rows_removed self.score += sum(range(rows_removed + 1)) * 100 if self.lines_to_next_level <= 0: self.score += 1000 * self.level self.lines_to_next_level = 15 self.level += 1 self.drop_time *= .75 except RuntimeError: game.add_state_and_switch("game over", GameOverState(self.window, self.score)) self.view_modified = True self.elapsed_time -= self.drop_time