godot-flashcards/scripts/models/quiz_session.gd
2025-12-27 00:20:33 -05:00

112 lines
2.8 KiB
GDScript

class_name QuizSession
extends Resource
signal question_answered(is_correct: bool, card: Flashcard)
signal session_completed(results: Dictionary)
signal progress_updated(current: int, total: int)
@export var deck: Deck
@export var current_index: int = 0
@export var shuffled_cards: Array[Flashcard] = []
@export var session_correct: int = 0
@export var session_incorrect: int = 0
@export var start_time: float = 0.0
@export var is_active: bool = false
func start_session(deck_to_study: Deck, shuffle: bool = true) -> void:
if not deck_to_study or deck_to_study.cards.is_empty():
push_error("Cannot start session with empty or null deck")
return
deck = deck_to_study
current_index = 0
session_correct = 0
session_incorrect = 0
start_time = Time.get_ticks_msec() / 1000.0
is_active = true
shuffled_cards.clear()
for card in deck.cards:
shuffled_cards.append(card)
if shuffle:
shuffled_cards.shuffle()
progress_updated.emit(current_index, shuffled_cards.size())
func get_current_card() -> Flashcard:
if current_index < shuffled_cards.size():
return shuffled_cards[current_index]
return null
func answer_question(is_correct: bool) -> void:
if not is_active:
push_warning("Cannot answer question - session is not active")
return
var current_card = get_current_card()
if not current_card:
push_warning("No current card to answer")
return
if is_correct:
session_correct += 1
else:
session_incorrect += 1
question_answered.emit(is_correct, current_card)
current_index += 1
progress_updated.emit(current_index, shuffled_cards.size())
if current_index >= shuffled_cards.size():
complete_session()
func complete_session() -> void:
if not is_active:
return
is_active = false
var end_time = Time.get_ticks_msec() / 1000.0
var duration = end_time - start_time
var results = {
"total_questions": shuffled_cards.size(),
"correct": session_correct,
"incorrect": session_incorrect,
"accuracy": get_session_accuracy(),
"duration_seconds": duration,
"deck_id": deck.id if deck else "",
"deck_name": deck.name if deck else ""
}
session_completed.emit(results)
func get_session_accuracy() -> float:
var total = session_correct + session_incorrect
if total == 0:
return 0.0
return (float(session_correct) / float(total)) * 100.0
func get_progress_percentage() -> float:
if shuffled_cards.size() == 0:
return 0.0
return (float(current_index) / float(shuffled_cards.size())) * 100.0
func get_remaining_cards() -> int:
return shuffled_cards.size() - current_index
func has_more_cards() -> bool:
return current_index < shuffled_cards.size()
func reset_session(shuffle_again: bool = true) -> void:
current_index = 0
session_correct = 0
session_incorrect = 0
start_time = Time.get_ticks_msec() / 1000.0
is_active = true
if shuffle_again:
shuffled_cards.shuffle()
progress_updated.emit(current_index, shuffled_cards.size())