class Petris(): """ Application respresentation class. """ def init(self): """ Initialize application. """ self.lines = 0 self.score = 0 self.level = 1 self.screen = Screen() self.screen.init() self.screen.level = self.level self.screen.lines = self.lines random.seed() self.figures = [] self.figures.append(FigureI()) self.figures.append(FigureO()) self.figures.append(FigureL()) self.figures.append(FigureJ()) self.figures.append(FigureT()) self.figures.append(FigureS()) self.figures.append(FigureZ()) def destroy(self): """ Free application resources. """ self.screen.destroy() def _get_game_delay(self): """ Returns real number of seconds for sleep time between figure falling steps. """ seconds = 0.080 + 0.800 * pow(0.75, self.level - 1) if (seconds < 0.01): seconds = 0.01 return seconds def _generate_figure(self): """ Generate next figure to be fallen. """ return self.figures[random.randint(0, len(self.figures) - 1)] def run(self): """ Run main application loop. Return True if game was aborted by user, or False if he lose the game. """ figure = None exiting = False fast_falling = False paused = False sleep_time = 0 # Sleep with little portions to make keyboard more interactive. sleep_chunk = 0.2 next_figure = self._generate_figure() while not exiting: # Create and initialize new figure. if not figure: figure = next_figure self.screen.move_figure_to_start(figure) next_figure = self._generate_figure() self.screen.set_next_figure(next_figure) self.screen.draw(figure) if sleep_time <= 0: sleep_time = self._get_game_delay() if sleep_time > sleep_chunk: sleep_time -= sleep_chunk time.sleep(sleep_chunk) else: time.sleep(sleep_time) sleep_time = 0 # Keyboard input loop. ch = self.screen.getch() if ch == curses.ERR: # Key was not pressed. pass elif ch == ord("l") or ch == ord("L"): # Move right. self.screen.move_figure_right(figure) elif ch == ord("h") or ch == ord("H"): # Move left. self.screen.move_figure_left(figure) elif ch == ord("j") or ch == ord("J"): # Rotate anticlockwise. self.screen.rotate_figure_anticlockwise(figure) elif ch == ord("k") or ch == ord("K"): # Rotate clockwise. self.screen.rotate_figure_clockwise(figure) elif ch == ord("f") or ch == ord("F"): # Fast falling. fast_falling = True elif ch == ord("p") or ch == ord("P"): # Pause. paused = not paused if paused: self.screen.status = "PAUSED" else: self.screen.status = None elif ch == ord("q") or ch == ord("Q"): # Quit. return True if paused: continue if sleep_time == 0 and not self._fall_down(figure): figure = None fast_falling = False else: if fast_falling: while self._fall_down(figure): pass figure = None fast_falling = False # Check for the end of game. if figure == None and self.screen.glass.is_full(): # Quit return False def _fall_down(self, figure): """ Do one falling down step. """ if not self.screen.move_figure_down(figure): lines = self.screen.delete_full_lines() score = self._lines_to_score(lines) self.lines += lines self.score += score self.level = int(1 + self.lines / 10) self.screen.score = self.score self.screen.lines = self.lines self.screen.level = self.level return False else: return True def _lines_to_score(self, lines): """ Get scores for the full lines. """ line_score = [0, 40, 100, 300, 1200] return line_score[lines] * self.level