import pyxel
import random

class Game:
    def __init__(self):
        pyxel.init(160, 120, title="Level 2 - Strasse")
        pyxel.load("res.pyxres")
        pyxel.playm(0, loop=True)

        self.level = 1

        self.lanes = [30, 60, 90]
        self.current_lane = 1

        self.player_x = 20
        self.player_y = self.lanes[self.current_lane]

        self.outfit = 0

        self.speed = 1
        self.has_helmet = False

        self.cars = []
        self.items = []

        self.timer = 0
        self.max_time = 600

        self.show_level_complete_text = False
        self.level_complete_timer = 0

        self.level3_cars = []
        self.level3_items = []
        self.level3_timer = 0
        self.level3_max_time = 550
        self.level3_has_helmet = False
        self.level3_speed = 1
        self.level3_current_lane = 1
        self.level3_player_y = self.lanes[1]
        self.show_level3_complete_text = False
        self.level3_complete_timer = 0

        self.level4_timer = 0
        self.quiz_total = 10
        self.quiz_count = 0
        self.quiz_question = None
        self.quiz_answer = ""
        self.quiz_correct_answer = 0
        self.answer_color = 7
        self.correct_timer = 0
        self.wrong_timer = 0

        self.confetti = []

        pyxel.run(self.update, self.draw)

    def update(self):
        if self.level == 1:
            if pyxel.btnp(pyxel.KEY_RIGHT):
                self.outfit = (self.outfit + 1) % 3
            if pyxel.btnp(pyxel.KEY_LEFT):
                self.outfit = (self.outfit - 1) % 3
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.level = 1.5

        elif self.level == 1.5:
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.level = 2

        elif self.level == 2:
            self.timer += 1
            if self.timer > self.max_time and not self.show_level_complete_text:
                self.show_level_complete_text = True
                self.level_complete_timer = 60
                return

            if not self.show_level_complete_text:
                if pyxel.btnp(pyxel.KEY_UP):
                    self.current_lane = max(0, self.current_lane - 1)
                if pyxel.btnp(pyxel.KEY_DOWN):
                    self.current_lane = min(2, self.current_lane + 1)
                self.player_y = self.lanes[self.current_lane]

                for car in self.cars:
                    car["x"] -= 3
                self.cars = [c for c in self.cars if c["x"] > -40]

                if pyxel.frame_count % 30 == 0:
                    self.cars.append({"x": 160, "lane": random.randint(0, 2)})

                for item in self.items:
                    item["x"] -= 2
                self.items = [i for i in self.items if i["x"] > -20]

                if pyxel.frame_count % 120 == 0:
                    self.items.append({
                        "x": 160,
                        "lane": random.randint(0, 2),
                        "type": random.choice(["shoe", "helmet"])
                    })

                for car in self.cars:
                    if car["lane"] == self.current_lane and abs(car["x"] - self.player_x) < 20:
                        if self.has_helmet:
                            self.has_helmet = False
                            self.cars.remove(car)
                        else:
                            self.reset_level2()

                for item in self.items:
                    if item["lane"] == self.current_lane and abs(item["x"] - self.player_x) < 15:
                        if item["type"] == "shoe":
                            self.speed = 2
                        if item["type"] == "helmet":
                            self.has_helmet = True
                        self.items.remove(item)
            else:
                self.level_complete_timer -= 1
                if self.level_complete_timer <= 0:
                    self.level = 2.5
                    self.show_level_complete_text = False

        elif self.level == 2.5:
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.level = 3
                self.reset_level3()

        elif self.level == 3:
            self.level3_timer += 1
            if self.level3_timer > self.level3_max_time and not self.show_level3_complete_text:
                self.show_level3_complete_text = True
                self.level3_complete_timer = 60
                return

            if not self.show_level3_complete_text:
                if pyxel.btnp(pyxel.KEY_UP):
                    self.level3_current_lane = max(0, self.level3_current_lane - 1)
                if pyxel.btnp(pyxel.KEY_DOWN):
                    self.level3_current_lane = min(2, self.level3_current_lane + 1)
                self.level3_player_y = self.lanes[self.level3_current_lane]

                for car in self.level3_cars:
                    car["x"] -= 5

                    # Spurwechsel zufaellig ausloesen
                    if pyxel.frame_count % 40 == car.get("id", 0) % 40:
                        if random.random() < 0.4:
                            car["target_lane"] = random.randint(0, 2)

                    # Smooth interpolation: visual_y bewegt sich zur Zielspur
                    target_y = float(self.lanes[car["target_lane"]])
                    car["visual_y"] += (target_y - car["visual_y"]) * 0.08

                    # Kollisionsspur updaten sobald Auto nah genug an Zielspur
                    if abs(car["visual_y"] - self.lanes[car["target_lane"]]) < 3:
                        car["lane"] = car["target_lane"]

                self.level3_cars = [c for c in self.level3_cars if c["x"] > -40]

                if pyxel.frame_count % 25 == 0:
                    car_id = pyxel.frame_count
                    start_lane = random.randint(0, 2)
                    self.level3_cars.append({
                        "x": 160,
                        "lane": start_lane,
                        "target_lane": start_lane,
                        "visual_y": float(self.lanes[start_lane]),
                        "id": car_id
                    })

                for item in self.level3_items:
                    item["x"] -= 3
                self.level3_items = [i for i in self.level3_items if i["x"] > -20]

                if pyxel.frame_count % 120 == 0:
                    self.level3_items.append({
                        "x": 160,
                        "lane": random.randint(0, 2),
                        "type": random.choice(["shoe", "helmet"])
                    })

                for car in self.level3_cars:
                    if car["lane"] == self.level3_current_lane and abs(car["x"] - self.player_x) < 20:
                        if self.level3_has_helmet:
                            self.level3_has_helmet = False
                            self.level3_cars.remove(car)
                        else:
                            self.reset_level3()

                for item in self.level3_items:
                    if item["lane"] == self.level3_current_lane and abs(item["x"] - self.player_x) < 15:
                        if item["type"] == "shoe":
                            self.level3_speed = 2
                        if item["type"] == "helmet":
                            self.level3_has_helmet = True
                        self.level3_items.remove(item)
            else:
                self.level3_complete_timer -= 1
                if self.level3_complete_timer <= 0:
                    self.level = 3.5
                    self.show_level3_complete_text = False

        elif self.level == 3.5:
            if pyxel.btnp(pyxel.KEY_RETURN):
                self.level = 4
                self.player_x = 64
                self.player_y = 80
                self.level4_timer = 0
                self.generate_quiz()

        elif self.level == 4:
            self.level4_timer += 1

            if self.correct_timer > 0:
                self.correct_timer -= 1
                if self.correct_timer == 0:
                    if self.quiz_count < self.quiz_total:
                        self.generate_quiz()
                        self.quiz_answer = ""
                        self.answer_color = 7

            if self.wrong_timer > 0:
                self.wrong_timer -= 1
                if self.wrong_timer == 0:
                    self.quiz_answer = ""
                    self.answer_color = 7

            for i in range(10):
                if pyxel.btnp(getattr(pyxel, f"KEY_{i}")) and self.correct_timer == 0 and self.wrong_timer == 0:
                    self.quiz_answer += str(i)

            if self.quiz_answer != "" and self.correct_timer == 0 and self.wrong_timer == 0:
                if int(self.quiz_answer) == self.quiz_correct_answer:
                    self.answer_color = 10
                    self.correct_timer = 30
                    self.quiz_count += 1
                elif len(self.quiz_answer) >= len(str(self.quiz_correct_answer)):
                    self.answer_color = 8
                    self.wrong_timer = 30

            if pyxel.btnp(pyxel.KEY_BACKSPACE) and self.correct_timer == 0 and self.wrong_timer == 0:
                self.quiz_answer = self.quiz_answer[:-1]

            if self.quiz_count >= self.quiz_total:
                for _ in range(5):
                    self.confetti.append({
                        "x": random.randint(0, pyxel.width-1),
                        "y": 0,
                        "color": random.randint(8, 15),
                        "speed": random.uniform(1, 2.5)
                    })
                for particle in self.confetti:
                    particle["y"] += particle["speed"]
                self.confetti = [p for p in self.confetti if p["y"] < pyxel.height]

    def draw(self):
        pyxel.cls(0)

        if self.level == 1:
            pyxel.bltm(0,0,0,0,0, 1024, 1024,0)
            pyxel.text(20, 10, "Outfit waehlen", 7)
            pyxel.text(10, 100, "ENTER = Start", 7)
            player_x = 64
            player_y = 40
            pyxel.blt(player_x, player_y, 0, 0, 16, 32, 32, 8)
            dress_x = player_x + 8
            dress_y = player_y + 16
            pyxel.blt(dress_x, dress_y, 0, self.outfit * 16, 48, 16, 16, 7)
            mid_y = player_y + 16
            pyxel.line(player_x - 8, mid_y - 4, player_x - 12, mid_y, 7)
            pyxel.line(player_x - 8, mid_y + 4, player_x - 12, mid_y, 7)
            pyxel.line(player_x + 40, mid_y - 4, player_x + 44, mid_y, 7)
            pyxel.line(player_x + 40, mid_y + 4, player_x + 44, mid_y, 7)

        elif self.level == 1.5:
            pyxel.cls(0)
            pyxel.text(5, 10, "Weiche den Autos mit den", 7)
            pyxel.text(5, 20, "Pfeiltasten nach oben und", 7)
            pyxel.text(5, 30, "unten aus und sammle die", 7)
            pyxel.text(5, 40, "Helme, welche dir ein", 7)
            pyxel.text(5, 50, "zusaetzliches Leben geben", 7)
            pyxel.text(5, 60, "und die Turnschuhe, welche", 7)
            pyxel.text(5, 70, "dich schneller machen.", 7)
            pyxel.text(108, 110, "ENTER=Start", 7)

        elif self.level == 2:
            if not self.show_level_complete_text:
                pyxel.bltm(0,0,1,0,0,256,256)
                pyxel.blt(self.player_x, self.player_y, 0, 0, 16, 32, 32, 8)
                dress_x = self.player_x + 8
                dress_y = self.player_y + 16
                pyxel.blt(dress_x, dress_y, 0, self.outfit * 16, 48, 16, 16, 7)
                for car in self.cars:
                    pyxel.blt(car["x"], self.lanes[car["lane"]], 0, 32, 16, 32, 32, 8)
                for item in self.items:
                    y = self.lanes[item["lane"]]
                    if item["type"] == "shoe":
                        pyxel.blt(item["x"], y, 0, 64, 32, 16, 16, 8)
                    if item["type"] == "helmet":
                        pyxel.blt(item["x"], y, 0, 48, 48, 16, 16, 8)
                pyxel.text(5, 5, f"Time: {self.max_time - self.timer}", 7)
                if self.has_helmet:
                    pyxel.text(5, 15, "HELM!", 7)
                if self.speed > 1:
                    pyxel.text(5, 25, "FAST!", 7)
            else:
                pyxel.cls(0)
                text = "LEVEL GESCHAFFT!"
                text_width = len(text) * 4
                pyxel.text((pyxel.width - text_width) // 2, pyxel.height // 2, text, 10)

        elif self.level == 2.5:
            pyxel.cls(0)
            pyxel.text(5, 40, "Jetzt kommen die Autos", 7)
            pyxel.text(5, 50, "viel schneller!", 7)
            pyxel.text(108, 110, "ENTER=Start", 7)

        elif self.level == 3:
            if not self.show_level3_complete_text:
                pyxel.bltm(0,0,1,0,0,256,256)
                pyxel.blt(self.player_x, self.level3_player_y, 0, 0, 16, 32, 32, 8)
                dress_x = self.player_x + 8
                dress_y = self.level3_player_y + 16
                pyxel.blt(dress_x, dress_y, 0, self.outfit * 16, 48, 16, 16, 7)
                for car in self.level3_cars:
                    # visual_y fuer smooth Spurwechsel verwenden
                    pyxel.blt(car["x"], int(car["visual_y"]), 0, 32, 16, 32, 32, 8)
                for item in self.level3_items:
                    y = self.lanes[item["lane"]]
                    if item["type"] == "shoe":
                        pyxel.blt(item["x"], y, 0, 64, 32, 16, 16, 8)
                    if item["type"] == "helmet":
                        pyxel.blt(item["x"], y, 0, 48, 48, 16, 16, 8)
                pyxel.text(5, 5, f"Time: {self.level3_max_time - self.level3_timer}", 7)
                if self.level3_has_helmet:
                    pyxel.text(5, 15, "HELM!", 7)
                if self.level3_speed > 1:
                    pyxel.text(5, 25, "FAST!", 7)
            else:
                pyxel.cls(0)
                text = "LEVEL GESCHAFFT!"
                text_width = len(text) * 4
                pyxel.text((pyxel.width - text_width) // 2, pyxel.height // 2, text, 10)

        elif self.level == 3.5:
            pyxel.cls(0)
            pyxel.text(5, 40, "Loese die Matheaufgaben!", 7)
            pyxel.text(108, 110, "ENTER=Start", 7)

        elif self.level == 4:
            pyxel.bltm(0, 0, 2, 0, 0, 256, 256)
            pyxel.blt(self.player_x, self.player_y, 0, 0, 16, 32, 32, 8)
            dress_x = self.player_x + 8
            dress_y = self.player_y + 16
            pyxel.blt(dress_x, dress_y, 0, self.outfit * 16, 48, 16, 16, 7)

            if self.quiz_count < self.quiz_total:
                pyxel.text(self.player_x, self.player_y - 40, self.quiz_question, 7)
                if self.quiz_answer != "":
                    pyxel.text(self.player_x, self.player_y - 32, self.quiz_answer, self.answer_color)
            else:
                text = "Das Spiel ist fertig!"
                text_width = len(text) * 4
                pyxel.text((pyxel.width - text_width) // 2, self.player_y - 40, text, 32)

                for p in self.confetti:
                    pyxel.pset(int(p["x"]), int(p["y"]), p["color"])

    def reset_level2(self):
        self.cars = []
        self.items = []
        self.speed = 1
        self.has_helmet = False
        self.current_lane = 1
        self.player_y = self.lanes[self.current_lane]
        self.timer = 0

    def reset_level3(self):
        self.level3_cars = []
        self.level3_items = []
        self.level3_speed = 1
        self.level3_has_helmet = False
        self.level3_current_lane = 1
        self.level3_player_y = self.lanes[1]
        self.level3_timer = 0

    def generate_quiz(self):
        op = random.choice(["*", "+", "-"])
        if op == "-":
            a = random.randint(1, 12)
            b = random.randint(1, a)
            self.quiz_correct_answer = a - b
        else:
            a = random.randint(1, 12)
            b = random.randint(1, 12)
            self.quiz_correct_answer = a * b if op == "*" else a + b

        self.quiz_question = f"{a} {op} {b} = ?"
        self.quiz_answer = ""
        self.answer_color = 7

Game()