| 
						 
							
							
							
						 
					 | 
				
			
			 | 
			 | 
			
				@ -1,6 +1,9 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				# -*- coding: utf-8 -*-
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import sys
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import os
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import subprocess
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import psutil
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    import curses
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -11,7 +14,7 @@ You can install it on Windows with:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				pip install --user windows-curses"""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    curses.COLOR_ORANGE = 8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    curses.COLOR_ORANGE = curses.COLOR_WHITE
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import random
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import sched
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -21,9 +24,9 @@ import locale
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				import subprocess
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    import configparser
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				except ImportError:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    import ConfigParser as configparser
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    from configparser import ConfigParser
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				except ImportError: # Python2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    from ConfigParser import SafeConfigParser as ConfigParser
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				DIR_NAME = "Terminis"
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -31,17 +34,10 @@ HELP_MSG = """terminis [options]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				Tetris clone for terminal
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --help\tshow command usage (this message)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --edit\tedit controls in text editor
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --reset\treset to default controls settings
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --level=n\tstart at level n (integer between 1 and 15)"""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				locale.setlocale(locale.LC_ALL, '')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				if locale.getpreferredencoding() == 'UTF-8':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    os.environ["NCURSES_NO_UTF8_ACS"] = "1"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				scheduler = sched.scheduler(time.time, lambda delay: curses.napms(int(delay*1000)))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --help\t-h\tshow command usage (this message)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --edit\t-e\tedit controls in text editor
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --reset\t-r\treset to default controls settings
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  --level=n\t\tstart at level n (integer between 1 and 15)"""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Rotation:
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -62,7 +58,33 @@ class Movement:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LEFT  = Point(-1, 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    RIGHT = Point(1, 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DOWN  = Point(0, 1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    STILL = Point(0, 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Scheduler(sched.scheduler, dict):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        sched.scheduler.__init__(self, time.time, time.sleep)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        dict.__init__(self)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def repeat(self, name, delay, action, args=tuple()):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self[name] = sched.scheduler.enter(self, delay, 1, self._repeat, (name, delay, action, args))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def _repeat(self, name, delay, action, args):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        del(self[name])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.repeat(name, delay, action, args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        action(*args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def single_shot(self, name, delay, action, args=tuple()):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self[name] = sched.scheduler.enter(self, delay, 1, self._single_shot, (name, action, args))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def _single_shot(self, name, action, args):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        del(self[name])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        action(*args)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def cancel(self, name):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if name in self:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            sched.scheduler.cancel(self, self.pop(name))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				scheduler = Scheduler()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Tetromino:
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -91,63 +113,52 @@ class Tetromino:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self, matrix, position):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix = matrix
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.position = position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.minoes_position = self.MINOES_POSITIONS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.minoes_positions = self.MINOES_POSITIONS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.orientation = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.rotation_point_5_used = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.rotated_last = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.lock_timer = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.fall_timer = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.hold_enabled = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def possible_position(self, minoes_position, movement):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def move_rotate(self, movement, minoes_positions):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        potential_position = self.position + movement
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if all(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.is_free_cell(mino_position+potential_position)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in minoes_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.is_free_cell(potential_position+mino_position)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in minoes_positions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return potential_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def move(self, movement, lock=True):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        possible_position = self.possible_position(self.minoes_position, movement)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if possible_position:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.position = possible_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.postpone_lock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.rotated_last = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.position = potential_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if "lock" in scheduler:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                scheduler.cancel("lock")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                scheduler.single_shot("lock", self.lock_delay, self.matrix.lock)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if lock and movement == Movement.DOWN:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.locking()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def soft_drop(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.move(Movement.DOWN):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.game.stats.piece_dropped(1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def hard_drop(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.lock_timer = scheduler.cancel(self.lock_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lines = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while self.move(Movement.DOWN, lock=False):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            lines += 2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.game.stats.piece_dropped(lines)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.lock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def move(self, movement, lock=True, refresh=True):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.move_rotate(movement, self.minoes_positions):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.rotated_last = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if refresh:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                lock
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                and movement == Movement.DOWN
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                and "lock" not in scheduler
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                scheduler.single_shot("lock", self.lock_delay, self.matrix.lock)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def rotate(self, direction):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        potential_minoes_positions = tuple(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        rotated_minoes_positions = tuple(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            Point(-direction*mino_position.y, direction*mino_position.x)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in self.minoes_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in self.minoes_positions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for rotation_point, liberty_degree in enumerate(self.SUPER_ROTATION_SYSTEM[self.orientation][direction], start=1):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            possible_position = self.possible_position(potential_minoes_positions, liberty_degree)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if possible_position:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.move_rotate(liberty_degree, rotated_minoes_positions):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.minoes_positions = rotated_minoes_positions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.orientation = (self.orientation+direction) % 4
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.position = possible_position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.minoes_position = potential_minoes_positions
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.postpone_lock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.rotated_last = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.rotated_last = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if rotation_point == 5:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.rotation_point_5_used = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.refresh()
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -155,32 +166,27 @@ class Tetromino:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            return False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def soft_drop(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.move(Movement.DOWN):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.game.stats.piece_dropped(1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def hard_drop(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        lines = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while self.move(Movement.DOWN, lock=False, refresh=False):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            lines += 2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.game.stats.piece_dropped(lines)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.lock()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def fall(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.fall_timer = scheduler.enter(self.fall_delay, 2, self.fall, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.move(Movement.DOWN)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def locking(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not self.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.lock_timer = scheduler.enter(self.lock_delay, 1, self.lock, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def postpone_lock(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.cancel(self.lock_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.lock_timer = scheduler.enter(self.lock_delay, 1, self.lock, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def lock(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.lock_timer = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not self.possible_position(self.minoes_position, Movement.DOWN):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.fall_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.fall_timer = scheduler.cancel(self.fall_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.lock(self.t_spin())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def t_spin(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return ""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class O(Tetromino):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SUPER_ROTATION_SYSTEM = tuple()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    MINOES_POSITIONS = (Point(0, 0), Point(1, 0), Point(0, -1), Point(1, -1))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    COLOR = curses.COLOR_YELLOW
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -260,11 +266,11 @@ class Window:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def draw_piece(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.piece:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.piece.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if "lock" in scheduler:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                attr = self.piece.color_pair | curses.A_BLINK | curses.A_REVERSE
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                attr = self.piece.color_pair
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in self.piece.minoes_position:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in self.piece.minoes_positions:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                position = mino_position + self.piece.position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.draw_mino(position.x, position.y, attr)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -278,7 +284,7 @@ class Matrix(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    NB_LINES = 21
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    WIDTH = NB_COLS*2+2
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    HEIGHT = NB_LINES+1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PIECE_POSITION = Point(4, 0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PIECE_POSITION = Point(4, -1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    TITLE = ""
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self, game, begin_x, begin_y):
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -289,6 +295,7 @@ class Matrix(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            [None for x in range(self.NB_COLS)]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for y in range(self.NB_LINES)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.piece = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Window.__init__(self, self.WIDTH, self.HEIGHT, begin_x, begin_y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def refresh(self, paused=False):
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -310,24 +317,30 @@ class Matrix(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            and not (position.y >= 0 and self.cells[position.y][position.x] is not None)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def lock(self, t_spin):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for mino_position in self.piece.minoes_position:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            position = mino_position + self.piece.position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if position.y >= 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.cells[position.y][position.x] = self.piece.color_pair
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.game.over()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def lock(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not self.piece.move(Movement.DOWN):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.cancel("fall")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        nb_lines_cleared = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for y, line in enumerate(self.cells):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if all(mino for mino in line):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.cells.pop(y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.cells.insert(0, [None for x in range(self.NB_COLS)])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                nb_lines_cleared += 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            t_spin = self.piece.t_spin()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.game.stats.piece_locked(nb_lines_cleared, t_spin)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.game.start_next_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for mino_position in self.piece.minoes_positions:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                position = mino_position + self.piece.position
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if position.y >= 0:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.cells[position.y][position.x] = self.piece.color_pair
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.game.over()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    return
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            nb_lines_cleared = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for y, line in enumerate(self.cells):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                if all(mino for mino in line):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.cells.pop(y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    self.cells.insert(0, [None for x in range(self.NB_COLS)])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    nb_lines_cleared += 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                    
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.game.stats.piece_locked(nb_lines_cleared, t_spin)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.piece = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.game.new_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class HoldNext(Window):
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -354,17 +367,16 @@ class Next(HoldNext):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    SCORES = (
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"": 0, "MINI T-SPIN": 1, "T-SPIN": 4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"": 1, "MINI T-SPIN": 2, "T-SPIN": 8},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"": 3, "T-SPIN": 12},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"": 5, "T-SPIN": 16},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"": 8}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"name": "", "": 0, "MINI T-SPIN": 1, "T-SPIN": 4},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"name": "SINGLE", "": 1, "MINI T-SPIN": 2, "T-SPIN": 8},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"name": "DOUBLE", "": 3, "T-SPIN": 12},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"name": "TRIPLE", "": 5, "T-SPIN": 16},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        {"name": "TETRIS", "": 8}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    LINES_CLEARED_NAMES = ("", "SINGLE", "DOUBLE", "TRIPLE", "TETRIS")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    TITLE = "STATS"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    FILE_NAME = ".high_score"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if sys.platform == "win32":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("appdata", os.path.expanduser("~\Appdata\Roaming"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("appdata", os.path.expanduser(r"~\Appdata\Roaming"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("XDG_DATA_HOME", os.path.expanduser("~/.local/share"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DIR_PATH = os.path.join(DIR_PATH, DIR_NAME)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -398,7 +410,6 @@ class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.combo = -1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.time = time.time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.lines_cleared = 0
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.clock_timer = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.strings = []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        Window.__init__(self, width, height, begin_x, begin_y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.new_level()
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -410,8 +421,6 @@ class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.window.addstr(3, 2, "HIGH\t{:n}".format(self.high_score), curses.A_BLINK|curses.A_BOLD)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.window.addstr(3, 2, "HIGH\t{:n}".format(self.high_score))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        t = time.localtime(time.time() - self.time)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.addstr(4, 2, "TIME\t%02d:%02d:%02d" % (t.tm_hour-1, t.tm_min, t.tm_sec))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.addstr(5, 2, "LEVEL\t%d" % self.level)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.addstr(6, 2, "GOAL\t%d" % self.goal)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.addstr(7, 2, "LINES\t%d" % self.lines_cleared)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -419,11 +428,12 @@ class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for y, string in enumerate(self.strings, start=start_y):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            x = (self.width-len(string)) // 2 + 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.window.addstr(y, x, string)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.refresh_time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def clock(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.clock_timer = scheduler.enter(1, 3, self.clock, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def refresh_time(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        t = time.localtime(time.time() - self.time)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.addstr(4, 2, "TIME\t%02d:%02d:%02d" % (t.tm_hour-1, t.tm_min, t.tm_sec))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def new_level(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.level += 1
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -446,7 +456,7 @@ class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if t_spin:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.strings.append(t_spin)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if nb_lines:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.strings.append(self.LINES_CLEARED_NAMES[nb_lines])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.strings.append(self.SCORES[nb_lines]["name"])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.combo += 1
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.combo = -1
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -485,10 +495,10 @@ class Stats(Window):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            print(e)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class ControlsParser(configparser.SafeConfigParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class ControlsParser(ConfigParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    FILE_NAME = "config.cfg"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if sys.platform == "win32":
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("appdata", os.path.expanduser("~\Appdata\Roaming"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("appdata", os.path.expanduser(r"~\Appdata\Roaming"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        DIR_PATH = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    DIR_PATH = os.path.join(DIR_PATH, DIR_NAME)
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -515,7 +525,7 @@ class ControlsParser(configparser.SafeConfigParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        configparser.SafeConfigParser.__init__(self)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        ConfigParser.__init__(self)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.optionxform = str
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.add_section(self.SECTION)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        for action, key in self.DEFAULTS.items():
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -574,6 +584,23 @@ class ControlsWindow(Window, ControlsParser):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.window.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Music:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    PATH = os.path.join(os.path.dirname(__file__), "music.sh")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def __init__(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.process = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def play(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.process = subprocess.Popen(["sh", self.PATH])
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def stop(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.process:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for proc in psutil.Process(self.process.pid).children(recursive=True):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                proc.terminate()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.process.terminate()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.process = None
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    WIDTH = 80
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    HEIGHT = Matrix.HEIGHT
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -611,6 +638,7 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next = Next(side_width, right_x, top_y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats = Stats(self, side_width, side_height, left_x, bottom_y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.controls = ControlsWindow(side_width, side_height, right_x, bottom_y)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.music = Music()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.actions = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.controls["QUIT"]: self.quit,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -624,14 +652,13 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.controls["HARD DROP"]: lambda: self.matrix.piece.hard_drop()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.playing = True
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.paused = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.time = time.time()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.clock_timer = scheduler.enter(1, 3, self.stats.clock, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.random_bag = []
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next.piece = self.random_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.start_next_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.input_timer = scheduler.enter(self.AUTOREPEAT_DELAY, 2, self.process_input, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.new_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        scheduler.repeat("time", 1, self.stats.refresh_time)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        scheduler.repeat("input", self.AUTOREPEAT_DELAY, self.process_input)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.music.play()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.run()
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -644,22 +671,19 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            random.shuffle(self.random_bag)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        return self.random_bag.pop()(self.matrix, Next.PIECE_POSITION)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def start_next_piece(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.piece = self.next.piece
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next.piece = self.random_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.start_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def start_piece(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def new_piece(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        scheduler.cancel("lock")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if not self.matrix.piece:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.piece, self.next.piece = self.next.piece, self.random_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.next.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.piece.position = Matrix.PIECE_POSITION
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.matrix.piece.possible_position(self.matrix.piece.minoes_position, Movement.STILL):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.piece.fall_timer = scheduler.enter(Tetromino.fall_delay, 2, self.matrix.piece.fall, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.matrix.piece.move(Movement.DOWN):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.repeat("fall", Tetromino.fall_delay, self.matrix.piece.fall)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.over()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def process_input(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.input_timer = scheduler.enter(self.AUTOREPEAT_DELAY, 2, self.process_input, tuple())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        try:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            action = self.actions[self.scr.getkey()]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        except (curses.error, KeyError):
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -674,6 +698,7 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.refresh(paused=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next.refresh(paused=True)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.scr.timeout(-1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.music.stop()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while True:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            key = self.scr.getkey()
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -681,32 +706,28 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.quit()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            elif key == self.controls["PAUSE"]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.scr.timeout(0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.hold.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.next.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.stats.time = time.time() - self.stats.time
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                break
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.scr.timeout(0)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.hold.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.next.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.time = time.time() - self.stats.time
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.music.play()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def swap(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.matrix.piece.hold_enabled:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.matrix.piece.fall_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.piece.fall_timer = scheduler.cancel(self.matrix.piece.fall_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.matrix.piece.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.matrix.piece.lock_timer = scheduler.cancel(self.matrix.piece.lock_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.cancel("fall")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            scheduler.cancel("lock")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.piece, self.hold.piece = self.hold.piece, self.matrix.piece
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.hold.piece.position = self.hold.PIECE_POSITION
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.hold.piece.minoes_position = self.hold.piece.MINOES_POSITIONS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.hold.piece.minoes_positions = self.hold.piece.MINOES_POSITIONS
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.hold.piece.hold_enabled = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.hold.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            if self.matrix.piece:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.start_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				                self.start_next_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.new_piece()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def over(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.time = time.time() - self.stats.time
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.matrix.refresh()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if curses.has_colors():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            for tetromino_class in self.TETROMINOES: 
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@ -724,31 +745,36 @@ class Game:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.scr.timeout(-1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        while self.scr.getkey() != self.controls["QUIT"]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            pass
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.time = time.time() - self.stats.time
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.quit()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    def quit(self):
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.playing = False
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.matrix.piece.fall_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.piece.fall_timer = scheduler.cancel(self.matrix.piece.fall_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.matrix.piece.lock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.matrix.piece.lock_timer = scheduler.cancel(self.matrix.piece.lock_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.stats.clock_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.stats.clock_timer = scheduler.cancel(self.stats.clock_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if self.input_timer:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            self.input_timer = scheduler.cancel(self.input_timer)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.stats.save()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        t = time.localtime(time.time() - self.stats.time)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        self.music.stop()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        sys.exit(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "SCORE\t{:n}\n".format(self.stats.score) +
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "HIGH\t{:n}\n".format(self.stats.high_score) +
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "TIME\t%02d:%02d:%02d\n" % (t.tm_hour-1, t.tm_min, t.tm_sec) +
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "LEVEL\t%d\n" % self.stats.level +
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            "LINES\t%d" % self.stats.lines_cleared
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        )
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				def main():
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if "--help" in sys.argv[1:] or "/?" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    if "--help" in sys.argv[1:] or "-h" in sys.argv[1:] or "/?" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        print(HELP_MSG)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    else:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if "--reset" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if "--reset" in sys.argv[1:] or "-r" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            controls = ControlsParser()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            controls.reset()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            controls.edit()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        elif "--edit" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        elif "--edit" in sys.argv[1:] or "-e" in sys.argv[1:]:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            ControlsParser().edit()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        locale.setlocale(locale.LC_ALL, '')
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        if locale.getpreferredencoding() == 'UTF-8':
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				            os.environ["NCURSES_NO_UTF8_ACS"] = "1"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        curses.wrapper(Game)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |