# utils/score_tracker.py import json import os from datetime import datetime from config.settings import BASE_POINTS, DIFFICULTY_LEVELS, BADGES, ACHIEVEMENTS class ScoreTracker: def __init__(self, user_id: str): self.user_id = user_id self.scores_file = f"data/scores_{user_id}.json" self.load_scores() def load_scores(self): """Load scores from a JSON file.""" if os.path.exists(self.scores_file): with open(self.scores_file, "r") as f: self.scores = json.load(f) else: self.scores = { "total_score": 0, "quizzes_completed": 0, "quiz_history": [], "badges": [], "achievements": [], "current_streak": 0, "best_streak": 0, } def save_scores(self): """Save scores to a JSON file.""" os.makedirs("data", exist_ok=True) with open(self.scores_file, "w") as f: json.dump(self.scores, f, indent=4) def add_quiz_result( self, mode: str, score: int, total: int, difficulty: str ) -> int: """Adds a quiz result and updates the total score.""" self.scores["quizzes_completed"] += 1 multiplier = DIFFICULTY_LEVELS.get(difficulty, {}).get("multiplier", 1) points_earned = int(score * BASE_POINTS * multiplier) self.scores["total_score"] += points_earned self.scores["quiz_history"].append( { "timestamp": datetime.now().isoformat(), "mode": mode, "score": score, "total": total, "difficulty": difficulty, "percentage": (score / total) * 100 if total > 0 else 0, "points_earned": points_earned, } ) self.update_streak(score > 0) self.check_for_badges() self.check_for_achievements() self.save_scores() return points_earned def update_streak(self, successful: bool): """Updates the user's streak.""" if successful: self.scores["current_streak"] += 1 else: self.scores["current_streak"] = 0 if self.scores["current_streak"] > self.scores["best_streak"]: self.scores["best_streak"] = self.scores["current_streak"] def check_for_badges(self): """Checks if the user has earned any new badges.""" for badge_id, badge_info in BADGES.items(): if ( self.scores["total_score"] >= badge_info["threshold"] and badge_id not in self.scores["badges"] ): self.scores["badges"].append(badge_id) def check_for_achievements(self): """Checks for new achievements.""" # Example: First quiz achievement if ( "first_quiz" not in self.scores["achievements"] and self.scores["quizzes_completed"] > 0 ): self.scores["achievements"].append("first_quiz") # Example: Streak achievement if ( "streak_5" not in self.scores["achievements"] and self.scores["current_streak"] >= 5 ): self.scores["achievements"].append("streak_5") def get_stats(self) -> dict: """Returns all user statistics.""" return self.scores