import sys import os import pygame import random import time pygame.init() bag = [] konami = 0 if len(sys.argv) > 1 and sys.argv[1] == "white": white_mode = True else: white_mode = False dead = False death_visible = False # Screen dimensions WIDTH = 400 HEIGHT = 800 GRID_SIZE = 40 # Colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) CYAN = (0, 255, 255) PURPLE = (255, 0, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) ORANGE = (255, 140, 0) BLUE = (0, 0, 255) YELLOW = (255, 235, 0) COLORS = [WHITE, CYAN, PURPLE, RED, GREEN, ORANGE, BLUE, YELLOW] # Tetromino shapes SHAPES = [ [ ['.....', '.....', '.....', 'OOOO.', '.....'], ['.....', 'O....', 'O....', 'O....', 'O....'] ], [ ['.....', '.....', '.O...', 'OOO..', '.....'], ['.....', '.O...', 'OO...', '.O...', '.....'], ['.....', '.....', 'OOO..', '.O...', '.....'], ['.....', 'O....', 'OO...', 'O....', '.....'] ], [ ['.....', '.....', 'OO...', '.OO..', '.....'], ['.....', '.O...', 'OO...', 'O....', '.....'] ], [ [ '.....', '.....', '.OO..', 'OO...', '.....'], ['.....', 'O....', 'OO...', '.O...', '.....'], ], [ ['.....', 'O....', 'O....', 'OO...', '.....'], ['.....', '..O..', 'OOO..', '.....', '.....'], ['.....', 'OO...', '.O...', '.O...', '.....'], ['.....', '.....', 'OOO..', 'O....', '.....'] ], [ ['.....', '.O...', '.O...', 'OO...', '.....'], ['.....', '.....', 'OOO..', '..O..', '.....'], ['.....', 'OO...', 'O....', 'O....', '.....'], ['.....', 'O....', 'OOO..', '.....', '.....'] ], [ [ '.....', '.....', 'OO...', 'OO...', '.....'], ] ] class Tetromino: def __init__(self, x, y, shape, color): self.x = x self.y = y self.shape = shape self.color = color self.rotation = 0 class Tetris: def __init__(self, width, height): self.width = width self.height = height # In de volgende regel wordt een "speelveld" van # 0 tot width breed, en van 0 tot height hoog gemaakt. # dat wil zeggen: een array van : width+1 bij height+1 # ieder element krijgt de waarde 0. self.grid = [[0 for w in range(width)] for h in range(height)] self.current_piece = self.new_piece() self.game_over = False self.score = 0 # Add score attribute def new_piece(self): global dead if dead == False: global bag #als de zak leeg is vul de zak (het is leeg bij een, want anders kun je geen previeuw van het volgende stukje zien) if len(bag) <= 0: while len(bag) < 7: # Choose a random shape shapeno = random.randint(0, len(SHAPES)-1) #checkt of het stukje al ertussen zit if shapeno not in bag: bag = bag + [shapeno] print(bag) #pak een stukje uit de zak shapeno = bag[0] bag.pop(0) shape = SHAPES[shapeno] bag.pop(0) if white_mode == False: color = COLORS[shapeno + 1] else: color = COLORS[0] print(bag) return Tetromino(self.width // 2, 0, shape, color) #anders pak het eerste stukje uit de zak else: shapeno = bag[0] shape = SHAPES[shapeno] bag.pop(0) if white_mode == False: color = COLORS[shapeno + 1] else: color = COLORS[0] print(bag) return Tetromino(self.width // 2, 0, shape, color) def valid_move(self, piece, x, y, rotation): # Check if the piece can move to the given position for i, row in enumerate(piece.shape[(piece.rotation + rotation) % len(piece.shape)]): for j, cell in enumerate(row): # fix hier, dat je blokjes te ver links kunnen komen. try: if cell == "O" and (piece.x + x) < 0: return False if cell == 'O' and (self.grid[piece.y + i + y][piece.x + j + x] != 0): return False except IndexError: return False return True def clear_lines(self): # Clear the lines that are full and return the number of cleared lines lines_cleared = 0 # Fix hier, dat de onderste regel niet verdwijnt. for i, row in enumerate(self.grid[:]): # ook zo'n telegramstijl-regel code: if all(cell != 0 for cell in row): #[0,0,0,0,0, (255, 0, 255), 0] lines_cleared += 1 del self.grid[i] self.grid.insert(0, [0 for _ in range(self.width)]) return lines_cleared def lock_piece(self, piece): # Lock the piece in place and create a new piece # Een for met twee variabelen: # de eerste loopt op, en de tweede geeft het element (de letter) uit de # piece shape[...] # dat komt omdat enumerate() deze twee waarden teruggeeft. for i, row in enumerate(piece.shape[piece.rotation % len(piece.shape)]): for j, cell in enumerate(row): if cell == 'O': self.grid[piece.y + i][piece.x + j] = piece.color # Clear the lines and update the score lines_cleared = self.clear_lines() # Update the score based on the number of cleared lines if lines_cleared == 1: self.score += lines_cleared * 40 elif lines_cleared == 2: self.score += lines_cleared * 50 elif lines_cleared == 3: self.score += lines_cleared * 100 elif lines_cleared == 4: self.score += lines_cleared * 300 # Create a new piece self.current_piece = self.new_piece() # Check if the game is over if not self.valid_move(self.current_piece, 0, 0, 0): self.game_over = True return lines_cleared def update(self): # Move the tetromino down one cell if not self.game_over: if self.valid_move(self.current_piece, 0, 1, 0): self.current_piece.y += 1 else: self.lock_piece(self.current_piece) def draw(self, screen): # Draw the grid and the current piece # Enumerate geeft 2 waarden terug! for y, row in enumerate(self.grid): for x, cell in enumerate(row): if cell: pygame.draw.rect(screen, cell, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1)) if self.current_piece: for i, row in enumerate(self.current_piece.shape[self.current_piece.rotation % len(self.current_piece.shape)]): for j, cell in enumerate(row): if cell == 'O': pygame.draw.rect(screen, self.current_piece.color, ((self.current_piece.x + j) * GRID_SIZE, (self.current_piece.y + i) * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1)) def draw_score(screen, score, x, y): # Draw the score on the screen font = pygame.font.Font(None, 36) text = font.render(f"Score: {score}", True, WHITE) screen.blit(text, (x, y)) def draw_game_over(screen, x, y): # Draw the game over text on the screen font = pygame.font.Font(None, 35) text = font.render("Game Over", True, RED,) text2 = font.render("press any arrow key to try again", True , WHITE ) screen.blit(text, (x+20, y)) screen.blit(text2, (x-90, y+40)) def main(): global dead # Initialize pygame screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption('Tetris') # Create a clock object clock = pygame.time.Clock() # Create a Tetris object game = Tetris(WIDTH // GRID_SIZE, HEIGHT // GRID_SIZE) fall_time = 0 # You can adjust this value to change the falling speed, it's in milliseconds (*10) fall_speed = 100.02 global konami while True: # Fill the screen with black screen.fill(BLACK) for event in pygame.event.get(): # Check for the KEYDOWN event if event.type == pygame.KEYDOWN and dead == False: if event.key == pygame.K_LEFT: if game.valid_move(game.current_piece, -1, 0, 0): game.current_piece.x -= 1 # Move the piece to the left if konami == 4 or konami == 6: konami += 1 else: konami = 0 if event.key == pygame.K_RIGHT: if game.valid_move(game.current_piece, 1, 0, 0): game.current_piece.x += 1 # Move the piece to the right if konami == 5: konami += 1 elif konami == 7: global white_mode white_mode = not white_mode game.game_over = True konami = 0 else: konami = 0 if event.key == pygame.K_DOWN: if konami == 2 or konami == 3: konami += 1 else: konami = 0 fall_speed /= 10 if event.key == pygame.K_UP: if game.valid_move(game.current_piece, 0, 0, 1): game.current_piece.rotation += 1 # Rotate the piece if konami == 0 or konami == 1: konami += 1 else: konami = 0 if event.key == pygame.K_SPACE: while game.valid_move(game.current_piece, 0, 1, 0): game.current_piece.y += 1 # Move the piece down until it hits the bottom game.lock_piece(game.current_piece) # Lock the piece in place elif event.type == pygame.KEYUP: if event.key == pygame.K_DOWN: fall_speed = 100.02 elif event.type == pygame.QUIT: sys.exit() # Get the number of milliseconds since the last frame delta_time = clock.get_rawtime() # Add the delta time to the fall time fall_time += delta_time if fall_time >= fall_speed: # Move the piece down game.update() # Reset the fall time fall_time = 0 # Fix hier dat de game niet correct stopt. # Draw the score on the screen draw_score(screen, game.score, 10, 10) # Draw the grid and the current piece game.draw(screen) if game.game_over: # Draw the "Game Over" message screen.fill(BLACK) draw_game_over(screen, WIDTH // 2 - 100, HEIGHT // 2 - 30) # Draw the "Game Over" message # You can add a "Press any key to restart" message here # Check for the KEYDOWN event dead = True i = 0 while i > 5: time.sleep(1) i += 1 if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: sys.exit() else: mode = "white" if white_mode else "" os.execl(sys.executable, sys.executable, *sys.argv[:1], mode) # Update the display pygame.display.flip() # Set the framerate clock.tick(60) if __name__ == "__main__": main()