└── game /game: -------------------------------------------------------------------------------- 1 | ```python 2 | import pygame 3 | import random 4 | 5 | # Инициализация Pygame 6 | pygame.init() 7 | 8 | # Параметры экрана 9 | screen_width = 400 10 | screen_height = 600 11 | play_width = 300 12 | play_height = 600 13 | block_size = 30 14 | 15 | # Установка экрана 16 | screen = pygame.display.set_mode((screen_width, screen_height)) 17 | pygame.display.set_caption("Tetris") 18 | 19 | # Цвета 20 | colors = [ 21 | (0, 0, 0), 22 | (255, 85, 85), 23 | (100, 200, 115), 24 | (120, 108, 245), 25 | (255, 140, 50), 26 | (50, 120, 52), 27 | (146, 202, 73), 28 | (150, 161, 218) 29 | ] 30 | 31 | # Фигуры 32 | tetriminoes = [ 33 | [[1, 1, 1], 34 | [0, 1, 0]], 35 | 36 | [[0, 2, 2], 37 | [2, 2, 0]], 38 | 39 | [[3, 3, 0], 40 | [0, 3, 3]], 41 | 42 | [[4, 0, 0], 43 | [4, 4, 4]], 44 | 45 | [[0, 0, 5], 46 | [5, 5, 5]], 47 | 48 | [[6, 6, 6, 6]], 49 | 50 | [[7, 7], 51 | [7, 7]] 52 | ] 53 | 54 | class Tetris: 55 | def __init__(self, height, width): 56 | self.height = height 57 | self.width = width 58 | self.board = [[0 for _ in range(width)] for _ in range(height)] 59 | self.gameover = False 60 | self.score = 0 61 | self.level = 1 62 | self.lines_cleared = 0 63 | self.current_piece = self.new_piece() 64 | self.next_piece = self.new_piece() 65 | self.piece_x = 3 66 | self.piece_y = 0 67 | 68 | def new_piece(self): 69 | return random.choice(tetriminoes) 70 | 71 | def rotate_piece(self): 72 | self.current_piece = [list(row) for row in zip(*self.current_piece[::-1])] 73 | 74 | def valid_space(self): 75 | accepted_positions = [[(j, i) for j in range(self.width) if self.board[i][j] == 0] for i in range(self.height)] 76 | accepted_positions = [j for sub in accepted_positions for j in sub] 77 | 78 | formatted = self.convert_shape_format() 79 | for pos in formatted: 80 | if pos not in accepted_positions: 81 | if pos[1] > -1: 82 | return False 83 | return True 84 | 85 | def convert_shape_format(self): 86 | positions = [] 87 | format = self.current_piece 88 | 89 | for i, line in enumerate(format): 90 | row = list(line) 91 | for j, column in enumerate(row): 92 | if column != 0: 93 | positions.append((self.piece_x + j, self.piece_y + i)) 94 | return positions 95 | 96 | def clear_rows(self): 97 | rows_cleared = 0 98 | for i in range(self.height - 1, -1, -1): 99 | if 0 not in self.board[i]: 100 | del self.board[i] 101 | self.board.insert(0, [0 for _ in range(self.width)]) 102 | rows_cleared += 1 103 | self.lines_cleared += 1 104 | if self.lines_cleared % 10 == 0: 105 | self.level += 1 106 | self.score += rows_cleared * 10 107 | 108 | def draw_board(self, screen): 109 | for i in range(self.height): 110 | for j in range(self.width): 111 | pygame.draw.rect(screen, colors[self.board[i][j]], 112 | (j * block_size, i * block_size, block_size, block_size), 0) 113 | 114 | piece_format = self.convert_shape_format() 115 | for pos in piece_format: 116 | pygame.draw.rect(screen, colors[self.current_piece[0][0]], 117 | (pos[0] * block_size, pos[1] * block_size, block_size, block_size), 0) 118 | 119 | self.draw_grid(screen) 120 | 121 | def draw_next_piece(self, screen): 122 | piece_format = self.next_piece 123 | for i, line in enumerate(piece_format): 124 | for j, column in enumerate(line): 125 | if column != 0: 126 | pygame.draw.rect(screen, colors[column], 127 | ((self.width + j + 1) * block_size, (i + 1) * block_size, block_size, block_size), 0) 128 | 129 | def draw_text(self, screen, text, size, color, position): 130 | font = pygame.font.Font(pygame.font.get_default_font(), size) 131 | label = font.render(text, 1, color) 132 | screen.blit(label, position) 133 | 134 | def draw_grid(self, screen): 135 | sx = 0 136 | sy = 0 137 | for i in range(self.height): 138 | pygame.draw.line(screen, (128, 128, 128), (sx, sy + i * block_size), (sx + play_width, sy + i * block_size)) 139 | for j in range(self.width): 140 | pygame.draw.line(screen, (128, 128, 128), (sx + j * block_size, sy), (sx + j * block_size, sy + play_height)) 141 | 142 | def freeze_piece(self): 143 | for pos in self.convert_shape_format(): 144 | p = pos 145 | self.board[p[1]][p[0]] = self.current_piece[0][0] 146 | self.current_piece = self.next_piece 147 | self.next_piece = self.new_piece() 148 | self.piece_x = 3 149 | self.piece_y = 0 150 | if not self.valid_space(): 151 | self.gameover = True 152 | 153 | def main(): 154 | clock = pygame.time.Clock() 155 | tetris = Tetris(20, 10) 156 | fall_time = 0 157 | 158 | while True: 159 | if tetris.gameover: 160 | screen.fill((0, 0, 0)) 161 | tetris.draw_text(screen, "Game Over", 60, (255, 0, 0), (screen_width // 2 - 100, screen_height // 2 - 30)) 162 | tetris.draw_text(screen, "Press R to Restart", 30, (255, 255, 255), (screen_width // 2 - 90, screen_height // 2 + 30)) 163 | pygame.display.update() 164 | 165 | for event in pygame.event.get(): 166 | if event.type == pygame.QUIT: 167 | pygame.quit() 168 | return 169 | if event.type == pygame.KEYDOWN and event.key == pygame.K_r: 170 | tetris = Tetris(20, 10) 171 | fall_time = 0 172 | 173 | else: 174 | screen.fill((0, 0, 0)) 175 | tetris.clear_rows() 176 | tetris.draw_board(screen) 177 | tetris.draw_next_piece(screen) 178 | tetris.draw_text(screen, f'Score: {tetris.score}', 30, (255, 255, 255), (play_width + 10, 10)) 179 | tetris.draw_text(screen, f'Level: {tetris.level}', 30, (255, 255, 255), (play_width + 10, 50)) 180 | pygame.display.update() 181 | 182 | fall_speed = 0.3 - (tetris.level * 0.02) 183 | fall_time += clock.get_rawtime() 184 | clock.tick() 185 | 186 | if fall_time / 1000 >= fall_speed: 187 | tetris.piece_y += 1 188 | if not tetris.valid_space(): 189 | tetris.piece_y -= 1 190 | tetris.freeze_piece() 191 | fall_time = 0 192 | 193 | for event in pygame.event.get(): 194 | if event.type == pygame.QUIT: 195 | pygame.quit() 196 | return 197 | if event.type == pygame.KEYDOWN: 198 | if event.key == pygame.K_LEFT: 199 | tetris.piece_x -= 1 200 | if not tetris.valid_space(): 201 | tetris.piece_x += 1 202 | if event.key == pygame.K_RIGHT: 203 | tetris.piece_x += 1 204 | if not tetris.valid_space(): 205 | tetris.piece_x -= 1 206 | if event.key == pygame.K_DOWN: 207 | tetris.piece_y += 1 208 | if not tetris.valid_space(): 209 | tetris.piece_y -= 1 210 | if event.key == pygame.K_UP: 211 | tetris.rotate_piece() 212 | if not tetris.valid_space(): 213 | tetris.rotate_piece() 214 | tetris.rotate_piece() 215 | tetris.rotate_piece() 216 | 217 | if __name__ == "__main__": 218 | main() 219 | ``` 220 | --------------------------------------------------------------------------------