import pygame
import random
import sys
import time

# Konfiguration des Labyrinths
CELL_SIZE = 40
COLS = 15
ROWS = 15
WIDTH = COLS * CELL_SIZE
HEIGHT = ROWS * CELL_SIZE

# Farben
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# Richtungsdefinitionen
DIRS = {'N': (0, -1), 'S': (0, 1), 'E': (1, 0), 'W': (-1, 0)}
OPPOSITE = {'N': 'S', 'S': 'N', 'E': 'W', 'W': 'E'}

class Cell:
    def __init__(self, col, row):
        self.col = col
        self.row = row
        self.walls = {'N': True, 'S': True, 'E': True, 'W': True}
        self.visited = False

def generate_maze():
    # Erzeuge ein Gitter von Zellen
    grid = [[Cell(col, row) for row in range(ROWS)] for col in range(COLS)]
    
    stack = []
    current = grid[0][0]
    current.visited = True
    
    while True:
        neighbours = []
        for direction, (dx, dy) in DIRS.items():
            nx = current.col + dx
            ny = current.row + dy
            if 0 <= nx < COLS and 0 <= ny < ROWS:
                neighbour = grid[nx][ny]
                if not neighbour.visited:
                    neighbours.append((direction, neighbour))
        if neighbours:
            direction, next_cell = random.choice(neighbours)
            current.walls[direction] = False
            next_cell.walls[OPPOSITE[direction]] = False
            stack.append(current)
            next_cell.visited = True
            current = next_cell
        elif stack:
            current = stack.pop()
        else:
            break

    # Öffnungen: Start links (oben links) und Ziel rechts (unten rechts)
    grid[0][0].walls['W'] = False
    grid[COLS - 1][ROWS - 1].walls['E'] = False
    return grid

def draw_maze(screen, grid):
    for col in range(COLS):
        for row in range(ROWS):
            x = col * CELL_SIZE
            y = row * CELL_SIZE
            cell = grid[col][row]
            # Zeichne Wände
            if cell.walls['N']:
                pygame.draw.line(screen, WHITE, (x, y), (x + CELL_SIZE, y), 2)
            if cell.walls['S']:
                pygame.draw.line(screen, WHITE, (x, y + CELL_SIZE), (x + CELL_SIZE, y + CELL_SIZE), 2)
            if cell.walls['E']:
                pygame.draw.line(screen, WHITE, (x + CELL_SIZE, y), (x + CELL_SIZE, y + CELL_SIZE), 2)
            if cell.walls['W']:
                pygame.draw.line(screen, WHITE, (x, y), (x, y + CELL_SIZE), 2)

def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Labyrinth-Spiel")
    clock = pygame.time.Clock()
    font = pygame.font.SysFont(None, 24)
    
    grid = generate_maze()
    
    # Startposition des Balls (in der Mitte der Startzelle)
    ball_col, ball_row = 0, 0
    ball_x = ball_col * CELL_SIZE + CELL_SIZE // 2
    ball_y = ball_row * CELL_SIZE + CELL_SIZE // 2
    ball_radius = CELL_SIZE // 4
    
    show_maze = False
    start_time = None
    game_over = False
    
    while True:
        dt = clock.tick(30) / 1000.0  # Zeit seit dem letzten Frame
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if not show_maze and event.key == pygame.K_SPACE:
                    # Starte das Spiel: Labyrinth anzeigen und Timer starten
                    show_maze = True
                    start_time = time.time()
                elif show_maze and not game_over:
                    new_col, new_row = ball_col, ball_row
                    if event.key == pygame.K_UP:
                        new_row -= 1
                        direction = 'N'
                    elif event.key == pygame.K_DOWN:
                        new_row += 1
                        direction = 'S'
                    elif event.key == pygame.K_LEFT:
                        new_col -= 1
                        direction = 'W'
                    elif event.key == pygame.K_RIGHT:
                        new_col += 1
                        direction = 'E'
                    else:
                        direction = None
                    
                    if direction is not None:
                        # Prüfe, ob die Bewegung innerhalb des Gitters liegt und ob keine Wand im Weg ist
                        if 0 <= new_col < COLS and 0 <= new_row < ROWS:
                            current_cell = grid[ball_col][ball_row]
                            if not current_cell.walls[direction]:
                                ball_col, ball_row = new_col, new_row
                                ball_x = ball_col * CELL_SIZE + CELL_SIZE // 2
                                ball_y = ball_row * CELL_SIZE + CELL_SIZE // 2
        
        screen.fill(BLACK)
        
        if show_maze:
            draw_maze(screen, grid)
            # Markiere Start (grün) und Ziel (rot)
            pygame.draw.rect(screen, GREEN, (0, 0, CELL_SIZE, CELL_SIZE))
            pygame.draw.rect(screen, RED, ((COLS - 1) * CELL_SIZE, (ROWS - 1) * CELL_SIZE, CELL_SIZE, CELL_SIZE))
            # Zeichne den Ball
            pygame.draw.circle(screen, BLUE, (ball_x, ball_y), ball_radius)
            
            # Zeige Timer an
            if start_time is not None:
                elapsed = time.time() - start_time
                timer_text = font.render(f"Zeit: {elapsed:.1f} sec", True, WHITE)
                screen.blit(timer_text, (10, HEIGHT - 30))
            
            # Überprüfe, ob das Ziel erreicht wurde
            if ball_col == COLS - 1 and ball_row == ROWS - 1:
                game_over = True
                over_text = font.render("Gewonnen!", True, WHITE)
                screen.blit(over_text, (WIDTH // 2 - 40, HEIGHT // 2))
        else:
            # Vor dem Start: Zeige Instruktion an
            text = font.render("Drücke SPACE zum Starten", True, WHITE)
            screen.blit(text, (WIDTH // 2 - 100, HEIGHT // 2))
        
        pygame.display.flip()

if __name__ == "__main__":
    main()
