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()