├── LICENSE.md └── initial /LICENSE.md: -------------------------------------------------------------------------------- 1 | // free // 2 | -------------------------------------------------------------------------------- /initial: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | 4 | # Initialize pygame 5 | pygame.init() 6 | 7 | # Screen dimensions 8 | SCREEN_WIDTH = 300 9 | SCREEN_HEIGHT = 600 10 | SQUARE_SIZE = 30 11 | PLAY_WIDTH = 10 * SQUARE_SIZE 12 | PLAY_HEIGHT = 20 * SQUARE_SIZE 13 | 14 | # Colors 15 | BLACK = (0, 0, 0) 16 | WHITE = (255, 255, 255) 17 | GRAY = (128, 128, 128) 18 | 19 | # Define the shapes of the pieces 20 | S = [['.....', 21 | '.....', 22 | '..00.', 23 | '.00..', 24 | '.....'], 25 | 26 | ['.....', 27 | '..0..', 28 | '..00.', 29 | '...0.', 30 | '.....']] 31 | 32 | Z = [['.....', 33 | '.....', 34 | '.00..', 35 | '..00.', 36 | '.....'], 37 | 38 | ['.....', 39 | '..0..', 40 | '.00..', 41 | '.0...', 42 | '.....']] 43 | 44 | I = [['.....', 45 | '.....', 46 | '0000.', 47 | '.....', 48 | '.....'], 49 | 50 | ['..0..', 51 | '..0..', 52 | '..0..', 53 | '..0..', 54 | '.....']] 55 | 56 | O = [['.....', 57 | '.....', 58 | '.00..', 59 | '.00..', 60 | '.....']] 61 | 62 | J = [['.....', 63 | '.0...', 64 | '.000.', 65 | '.....', 66 | '.....'], 67 | 68 | ['.....', 69 | '..00.', 70 | '..0..', 71 | '..0..', 72 | '.....'], 73 | 74 | ['.....', 75 | '.....', 76 | '.000.', 77 | '...0.', 78 | '.....'], 79 | 80 | ['.....', 81 | '..0..', 82 | '..0..', 83 | '.00..', 84 | '.....']] 85 | 86 | L = [['.....', 87 | '...0.', 88 | '.000.', 89 | '.....', 90 | '.....'], 91 | 92 | ['.....', 93 | '..0..', 94 | '..0..', 95 | '..00.', 96 | '.....'], 97 | 98 | ['.....', 99 | '.....', 100 | '.000.', 101 | '.0...', 102 | '.....'], 103 | 104 | ['.....', 105 | '.00..', 106 | '..0..', 107 | '..0..', 108 | '.....']] 109 | 110 | T = [['.....', 111 | '..0..', 112 | '.000.', 113 | '.....', 114 | '.....'], 115 | 116 | ['.....', 117 | '..0..', 118 | '..00.', 119 | '..0..', 120 | '.....'], 121 | 122 | ['.....', 123 | '.....', 124 | '.000.', 125 | '..0..', 126 | '.....'], 127 | 128 | ['.....', 129 | '..0..', 130 | '.00..', 131 | '..0..', 132 | '.....']] 133 | 134 | SHAPES = [S, Z, I, O, J, L, T] 135 | SHAPE_COLORS = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)] 136 | 137 | # Piece class 138 | class Piece: 139 | def __init__(self, x, y, shape): 140 | self.x = x 141 | self.y = y 142 | self.shape = shape 143 | self.color = SHAPE_COLORS[SHAPES.index(shape)] 144 | self.rotation = 0 145 | 146 | # Create the grid 147 | def create_grid(locked_positions={}): 148 | grid = [[BLACK for _ in range(10)] for _ in range(20)] 149 | 150 | for i in range(len(grid)): 151 | for j in range(len(grid[i])): 152 | if (j, i) in locked_positions: 153 | c = locked_positions[(j, i)] 154 | grid[i][j] = c 155 | return grid 156 | 157 | # Convert shape format 158 | def convert_shape_format(piece): 159 | positions = [] 160 | format = piece.shape[piece.rotation % len(piece.shape)] 161 | 162 | for i, line in enumerate(format): 163 | row = list(line) 164 | for j, column in enumerate(row): 165 | if column == '0': 166 | positions.append((piece.x + j, piece.y + i)) 167 | for i, pos in enumerate(positions): 168 | positions[i] = (pos[0] - 2, pos[1] - 4) 169 | return positions 170 | 171 | # Valid space 172 | def valid_space(piece, grid): 173 | accepted_positions = [[(j, i) for j in range(10) if grid[i][j] == BLACK] for i in range(20)] 174 | accepted_positions = [j for sub in accepted_positions for j in sub] 175 | 176 | formatted = convert_shape_format(piece) 177 | 178 | for pos in formatted: 179 | if pos not in accepted_positions: 180 | if pos[1] > -1: 181 | return False 182 | return True 183 | 184 | # Check if game is lost 185 | def check_lost(positions): 186 | for pos in positions: 187 | x, y = pos 188 | if y < 1: 189 | return True 190 | return False 191 | 192 | # Get the next shape 193 | def get_shape(): 194 | return Piece(5, 0, random.choice(SHAPES)) 195 | 196 | # Draw text in the middle of the screen 197 | def draw_text_middle(text, size, color, surface): 198 | font = pygame.font.Font(pygame.font.get_default_font(), size, bold=False) 199 | label = font.render(text, 1, color) 200 | surface.blit(label, (SCREEN_WIDTH / 2 - (label.get_width() / 2), SCREEN_HEIGHT / 2 - (label.get_height() / 2))) 201 | 202 | # Draw the grid 203 | def draw_grid(surface, grid): 204 | for i in range(len(grid)): 205 | for j in range(len(grid[i])): 206 | pygame.draw.rect(surface, grid[i][j], (j * SQUARE_SIZE, i * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE), 0) 207 | draw_grid_lines(surface) 208 | 209 | # Draw the grid lines 210 | def draw_grid_lines(surface): 211 | for i in range(len(grid)): 212 | pygame.draw.line(surface, GRAY, (0, i * SQUARE_SIZE), (SCREEN_WIDTH, i * SQUARE_SIZE)) 213 | for j in range(len(grid[i])): 214 | pygame.draw.line(surface, GRAY, (j * SQUARE_SIZE, 0), (j * SQUARE_SIZE, SCREEN_HEIGHT)) 215 | 216 | # Clear rows 217 | def clear_rows(grid, locked): 218 | increment = 0 219 | for i in range(len(grid) - 1, -1, -1): 220 | row = grid[i] 221 | if BLACK not in row: 222 | increment += 1 223 | ind = i 224 | for j in range(len(row)): 225 | try: 226 | del locked[(j, i)] 227 | except: 228 | continue 229 | 230 | if increment > 0: 231 | for key in sorted(list(locked), key=lambda x: x[1])[::-1]: 232 | x, y = key 233 | if y < ind: 234 | new_key = (x, y + increment) 235 | locked[new_key] = locked.pop(key) 236 | return increment 237 | 238 | # Draw the next shape 239 | def draw_next_shape(piece, surface): 240 | font = pygame.font.Font(pygame.font.get_default_font(), 30) 241 | label = font.render('Next Shape', 1, WHITE) 242 | 243 | sx = PLAY_WIDTH + 50 244 | sy = SCREEN_HEIGHT / 2 - 100 245 | format = piece.shape[piece.rotation % len(piece.shape)] 246 | 247 | for i, line in enumerate(format): 248 | row = list(line) 249 | for j, column in enumerate(row): 250 | if column == '0': 251 | pygame.draw.rect(surface, piece.color, (sx + j * SQUARE_SIZE, sy + i * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE), 0) 252 | 253 | surface.blit(label, (sx + 10, sy - 30)) 254 | 255 | # Main function 256 | def main(): 257 | global grid 258 | 259 | locked_positions = {} 260 | grid = create_grid(locked_positions) 261 | 262 | change_piece = False 263 | run = True 264 | current_piece = get_shape() 265 | next_piece = get_shape() 266 | clock = pygame.time.Clock() 267 | fall_time = 0 268 | level_time = 0 269 | 270 | while run: 271 | grid = create_grid(locked_positions) 272 | fall_speed = 0.27 273 | 274 | for event in pygame.event.get(): 275 | if event.type == pygame.QUIT: 276 | run = False 277 | pygame.display.quit() 278 | quit() 279 | 280 | if event.type == pygame.KEYDOWN: 281 | if event.key == pygame.K_LEFT: 282 | current_piece.x -= 1 283 | if not valid_space(current_piece, grid): 284 | current_piece.x += 1 285 | if event.key == pygame.K_RIGHT: 286 | current_piece.x += 1 287 | if not valid_space(current_piece, grid): 288 | current_piece.x -= 1 289 | if event.key == pygame.K_DOWN: 290 | current_piece.y += 1 291 | if not valid_space(current_piece, grid): 292 | current_piece.y -= 1 293 | if event.key == pygame.K_UP: 294 | current_piece.rotation = (current_piece.rotation + 1) % len(current_piece.shape) 295 | if not valid_space(current_piece, grid): 296 | current_piece.rotation = (current_piece.rotation - 1) % len(current_piece.shape) 297 | 298 | fall_time += clock.get_rawtime() 299 | level_time += clock.get_rawtime() 300 | clock.tick() 301 | 302 | if level_time / 1000 > 5: 303 | level_time = 0 304 | if fall_speed > 0.12: 305 | fall_speed -= 0.005 306 | 307 | if fall_time / 1000 >= fall_speed: 308 | fall_time = 0 309 | current_piece.y += 1 310 | if not valid_space(current_piece, grid): 311 | current_piece.y -= 1 312 | change_piece = True 313 | 314 | shape_pos = convert_shape_format(current_piece) 315 | 316 | for i in range(len(shape_pos)): 317 | x, y = shape_pos[i] 318 | if y > -1: 319 | grid[y][x] = current_piece.color 320 | 321 | if change_piece: 322 | for pos in shape_pos: 323 | p = (pos[0], pos[1]) 324 | locked_positions[p] = current_piece.color 325 | current_piece = next_piece 326 | next_piece = get_shape() 327 | change_piece = False 328 | clear_rows(grid, locked_positions) 329 | 330 | draw_grid(screen, grid) 331 | draw_next_shape(next_piece, screen) 332 | pygame.display.update() 333 | 334 | if check_lost(locked_positions): 335 | run = False 336 | draw_text_middle("You Lost", 80, WHITE, screen) 337 | pygame.display.update() 338 | pygame.time.delay(1500) 339 | 340 | pygame.display.quit() 341 | 342 | if __name__ == "__main__": 343 | screen = pygame.display.set_mode((SCREEN_WIDTH + 200, SCREEN_HEIGHT)) 344 | pygame.display.set_caption('Tetris') 345 | main() 346 | --------------------------------------------------------------------------------