File size: 1,711 Bytes
676d6d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from __future__ import annotations
from dataclasses import dataclass
from quiz.models import QuizSession
from quiz.scoring import xp_for_question, streak_label, compute_grade

@dataclass
class AnswerResult:
    is_correct: bool
    correct_idx: int
    xp_delta: int
    streak_label: str
    grade: str
    was_boss: bool

class QuizEngine:
    def submit_next(self, session: QuizSession, selected_idx: int) -> AnswerResult:
        """Submit answer for the current question (regular or boss — auto-detected via is_boss)."""
        if session.is_finished:
            raise RuntimeError("Cannot submit answer: session is finished.")
        question = session.current_question
        is_correct = (selected_idx == question.correct_idx)
        xp_delta = 0

        if is_correct:
            session.score += 1
            xp_delta = xp_for_question(question.difficulty, is_boss=question.is_boss)
            session.xp_earned += xp_delta
            if not question.is_boss:
                session.consecutive_correct += 1
        else:
            session.consecutive_correct = 0
            if question.topic not in session.wrong_topics:
                session.wrong_topics.append(question.topic)

        session.current_idx += 1
        label = streak_label(session.consecutive_correct)
        grade = compute_grade(session.score, session.current_idx)
        return AnswerResult(is_correct=is_correct, correct_idx=question.correct_idx,
                            xp_delta=xp_delta, streak_label=label, grade=grade,
                            was_boss=question.is_boss)

    def final_grade(self, session: QuizSession) -> str:
        return compute_grade(session.score, len(session.questions))