Files
breakpilot-lehrer/backend-lehrer/game_models.py
Benjamin Admin 6811264756 [split-required] Split final batch of monoliths >1000 LOC
Python (6 files in klausur-service):
- rbac.py (1,132 → 4), admin_api.py (1,012 → 4)
- routes/eh.py (1,111 → 4), ocr_pipeline_geometry.py (1,105 → 5)

Python (2 files in backend-lehrer):
- unit_api.py (1,226 → 6), game_api.py (1,129 → 5)

Website (6 page files):
- 4x klausur-korrektur pages (1,249-1,328 LOC each) → shared components
  in website/components/klausur-korrektur/ (17 shared files)
- companion (1,057 → 10), magic-help (1,017 → 8)

All re-export barrels preserve backward compatibility.
Zero import errors verified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 23:17:30 +02:00

323 lines
11 KiB
Python

# ==============================================
# Breakpilot Drive - Game API Models & Data
# ==============================================
# Pydantic models, difficulty mappings, and sample questions.
# Extracted from game_api.py for file-size compliance.
from pydantic import BaseModel
from typing import List, Optional, Literal, Dict, Any
from datetime import datetime
# ==============================================
# Pydantic Models
# ==============================================
class LearningLevel(BaseModel):
"""Lernniveau eines Benutzers aus dem Breakpilot-System"""
user_id: str
overall_level: int # 1-5 (1=Anfaenger/Klasse 2, 5=Fortgeschritten/Klasse 6)
math_level: float
german_level: float
english_level: float
last_updated: datetime
class GameDifficulty(BaseModel):
"""Spielschwierigkeit basierend auf Lernniveau"""
lane_speed: float # Geschwindigkeit in m/s
obstacle_frequency: float # Hindernisse pro Sekunde
power_up_chance: float # Wahrscheinlichkeit fuer Power-Ups (0-1)
question_complexity: int # 1-5
answer_time: int # Sekunden zum Antworten
hints_enabled: bool
speech_speed: float # Sprechgeschwindigkeit fuer Audio-Version
class QuizQuestion(BaseModel):
"""Quiz-Frage fuer das Spiel"""
id: str
question_text: str
audio_url: Optional[str] = None
options: List[str] # 2-4 Antwortmoeglichkeiten
correct_index: int # 0-3
difficulty: int # 1-5
subject: Literal["math", "german", "english", "general"]
grade_level: Optional[int] = None # 2-6
# NEU: Quiz-Modus
quiz_mode: Literal["quick", "pause"] = "quick" # quick=waehrend Fahrt, pause=Spiel haelt an
visual_trigger: Optional[str] = None # z.B. "bridge", "house", "tree" - loest Frage aus
time_limit_seconds: Optional[float] = None # Zeit bis Antwort noetig (bei quick)
class QuizAnswer(BaseModel):
"""Antwort auf eine Quiz-Frage"""
question_id: str
selected_index: int
answer_time_ms: int # Zeit bis zur Antwort in ms
was_correct: bool
class GameSession(BaseModel):
"""Spielsession-Daten fuer Analytics"""
user_id: str
game_mode: Literal["video", "audio"]
duration_seconds: int
distance_traveled: float
score: int
questions_answered: int
questions_correct: int
difficulty_level: int
quiz_answers: Optional[List[QuizAnswer]] = None
class SessionResponse(BaseModel):
"""Antwort nach Session-Speicherung"""
session_id: str
status: str
new_level: Optional[int] = None # Falls Lernniveau angepasst wurde
# ==============================================
# Schwierigkeits-Mapping
# ==============================================
DIFFICULTY_MAPPING = {
1: GameDifficulty(
lane_speed=3.0,
obstacle_frequency=0.3,
power_up_chance=0.4,
question_complexity=1,
answer_time=15,
hints_enabled=True,
speech_speed=0.8
),
2: GameDifficulty(
lane_speed=4.0,
obstacle_frequency=0.4,
power_up_chance=0.35,
question_complexity=2,
answer_time=12,
hints_enabled=True,
speech_speed=0.9
),
3: GameDifficulty(
lane_speed=5.0,
obstacle_frequency=0.5,
power_up_chance=0.3,
question_complexity=3,
answer_time=10,
hints_enabled=True,
speech_speed=1.0
),
4: GameDifficulty(
lane_speed=6.0,
obstacle_frequency=0.6,
power_up_chance=0.25,
question_complexity=4,
answer_time=8,
hints_enabled=False,
speech_speed=1.1
),
5: GameDifficulty(
lane_speed=7.0,
obstacle_frequency=0.7,
power_up_chance=0.2,
question_complexity=5,
answer_time=6,
hints_enabled=False,
speech_speed=1.2
),
}
# ==============================================
# Beispiel Quiz-Fragen (spaeter aus DB laden)
# ==============================================
SAMPLE_QUESTIONS = [
# ==============================================
# QUICK QUESTIONS (waehrend der Fahrt, visuell getriggert)
# ==============================================
# Englisch Vokabeln - Objekte im Spiel (QUICK MODE)
QuizQuestion(
id="vq-bridge", question_text="What is this?",
options=["Bridge", "House"], correct_index=0,
difficulty=1, subject="english", grade_level=3,
quiz_mode="quick", visual_trigger="bridge", time_limit_seconds=3.0
),
QuizQuestion(
id="vq-tree", question_text="What is this?",
options=["Tree", "Flower"], correct_index=0,
difficulty=1, subject="english", grade_level=3,
quiz_mode="quick", visual_trigger="tree", time_limit_seconds=3.0
),
QuizQuestion(
id="vq-house", question_text="What is this?",
options=["House", "Car"], correct_index=0,
difficulty=1, subject="english", grade_level=3,
quiz_mode="quick", visual_trigger="house", time_limit_seconds=3.0
),
QuizQuestion(
id="vq-car", question_text="What is this?",
options=["Car", "Bus"], correct_index=0,
difficulty=1, subject="english", grade_level=3,
quiz_mode="quick", visual_trigger="car", time_limit_seconds=2.5
),
QuizQuestion(
id="vq-mountain", question_text="What is this?",
options=["Hill", "Mountain", "Valley"], correct_index=1,
difficulty=2, subject="english", grade_level=4,
quiz_mode="quick", visual_trigger="mountain", time_limit_seconds=3.5
),
QuizQuestion(
id="vq-river", question_text="What is this?",
options=["Lake", "River", "Sea"], correct_index=1,
difficulty=2, subject="english", grade_level=4,
quiz_mode="quick", visual_trigger="river", time_limit_seconds=3.5
),
# Schnelle Rechenaufgaben (QUICK MODE)
QuizQuestion(
id="mq-1", question_text="3 + 4 = ?",
options=["6", "7"], correct_index=1,
difficulty=1, subject="math", grade_level=2,
quiz_mode="quick", time_limit_seconds=4.0
),
QuizQuestion(
id="mq-2", question_text="5 x 2 = ?",
options=["10", "12"], correct_index=0,
difficulty=1, subject="math", grade_level=2,
quiz_mode="quick", time_limit_seconds=4.0
),
QuizQuestion(
id="mq-3", question_text="8 - 3 = ?",
options=["4", "5"], correct_index=1,
difficulty=1, subject="math", grade_level=2,
quiz_mode="quick", time_limit_seconds=3.5
),
QuizQuestion(
id="mq-4", question_text="6 x 7 = ?",
options=["42", "48"], correct_index=0,
difficulty=2, subject="math", grade_level=3,
quiz_mode="quick", time_limit_seconds=5.0
),
QuizQuestion(
id="mq-5", question_text="9 x 8 = ?",
options=["72", "64"], correct_index=0,
difficulty=3, subject="math", grade_level=4,
quiz_mode="quick", time_limit_seconds=5.0
),
# ==============================================
# PAUSE QUESTIONS (Spiel haelt an, mehr Zeit)
# ==============================================
# Mathe Level 1-2 (Klasse 2-3) - PAUSE MODE
QuizQuestion(
id="mp1-1", question_text="Anna hat 5 Aepfel. Sie bekommt 3 dazu. Wie viele hat sie jetzt?",
options=["6", "7", "8", "9"], correct_index=2,
difficulty=1, subject="math", grade_level=2,
quiz_mode="pause"
),
QuizQuestion(
id="mp2-1", question_text="Ein Bus hat 24 Sitze. 18 sind besetzt. Wie viele sind frei?",
options=["4", "5", "6", "7"], correct_index=2,
difficulty=2, subject="math", grade_level=3,
quiz_mode="pause"
),
QuizQuestion(
id="mp2-2", question_text="Was ist 45 + 27?",
options=["72", "62", "82", "70"], correct_index=0,
difficulty=2, subject="math", grade_level=3,
quiz_mode="pause"
),
# Mathe Level 3-4 (Klasse 4-5) - PAUSE MODE
QuizQuestion(
id="mp3-1", question_text="Was ist 7 x 8?",
options=["54", "56", "58", "48"], correct_index=1,
difficulty=3, subject="math", grade_level=4,
quiz_mode="pause"
),
QuizQuestion(
id="mp3-2", question_text="Ein Rechteck ist 8m lang und 5m breit. Wie gross ist die Flaeche?",
options=["35 m2", "40 m2", "45 m2", "26 m2"], correct_index=1,
difficulty=3, subject="math", grade_level=4,
quiz_mode="pause"
),
QuizQuestion(
id="mp4-1", question_text="Was ist 15% von 80?",
options=["10", "12", "8", "15"], correct_index=1,
difficulty=4, subject="math", grade_level=5,
quiz_mode="pause"
),
QuizQuestion(
id="mp4-2", question_text="Was ist 3/4 + 1/2?",
options=["5/4", "4/6", "1", "5/6"], correct_index=0,
difficulty=4, subject="math", grade_level=5,
quiz_mode="pause"
),
# Mathe Level 5 (Klasse 6) - PAUSE MODE
QuizQuestion(
id="mp5-1", question_text="Was ist (-5) x (-3)?",
options=["-15", "15", "-8", "8"], correct_index=1,
difficulty=5, subject="math", grade_level=6,
quiz_mode="pause"
),
QuizQuestion(
id="mp5-2", question_text="Loesung von 2x + 5 = 11?",
options=["2", "3", "4", "6"], correct_index=1,
difficulty=5, subject="math", grade_level=6,
quiz_mode="pause"
),
# Deutsch - PAUSE MODE (brauchen Lesezeit)
QuizQuestion(
id="dp1-1", question_text="Welches Wort ist ein Nomen?",
options=["laufen", "schnell", "Hund", "und"], correct_index=2,
difficulty=1, subject="german", grade_level=2,
quiz_mode="pause"
),
QuizQuestion(
id="dp2-1", question_text="Was ist die Mehrzahl von 'Haus'?",
options=["Haeuse", "Haeuser", "Hausern", "Haus"], correct_index=1,
difficulty=2, subject="german", grade_level=3,
quiz_mode="pause"
),
QuizQuestion(
id="dp3-1", question_text="Welches Verb steht im Praeteritum?",
options=["geht", "ging", "gegangen", "gehen"], correct_index=1,
difficulty=3, subject="german", grade_level=4,
quiz_mode="pause"
),
QuizQuestion(
id="dp3-2", question_text="Finde den Rechtschreibfehler: 'Der Hund leuft schnell.'",
options=["Hund", "leuft", "schnell", "Der"], correct_index=1,
difficulty=3, subject="german", grade_level=4,
quiz_mode="pause"
),
# Englisch Saetze - PAUSE MODE
QuizQuestion(
id="ep3-1", question_text="How do you say 'Schmetterling'?",
options=["bird", "bee", "butterfly", "beetle"], correct_index=2,
difficulty=3, subject="english", grade_level=4,
quiz_mode="pause"
),
QuizQuestion(
id="ep4-1", question_text="Choose the correct form: She ___ to school.",
options=["go", "goes", "going", "gone"], correct_index=1,
difficulty=4, subject="english", grade_level=5,
quiz_mode="pause"
),
QuizQuestion(
id="ep4-2", question_text="What is the past tense of 'run'?",
options=["runned", "ran", "runed", "running"], correct_index=1,
difficulty=4, subject="english", grade_level=5,
quiz_mode="pause"
),
]