mirror of
https://github.com/mr0xb/godot-flashcards.git
synced 2026-08-27 20:44:56 -04:00
116 lines
3.3 KiB
GDScript
116 lines
3.3 KiB
GDScript
class_name Progress
|
|
extends Resource
|
|
|
|
@export var deck_id: String = ""
|
|
|
|
@export var total_sessions: int = 0
|
|
@export var total_cards_studied: int = 0
|
|
@export var total_correct: int = 0
|
|
@export var total_incorrect: int = 0
|
|
@export var current_streak: int = 0
|
|
@export var best_streak: int = 0
|
|
@export var last_session_at: String = ""
|
|
|
|
@export var card_stats: Dictionary = {}
|
|
|
|
func to_dict() -> Dictionary:
|
|
return {
|
|
"deck_id": deck_id,
|
|
"stats": {
|
|
"total_sessions": total_sessions,
|
|
"total_cards_studied": total_cards_studied,
|
|
"total_correct": total_correct,
|
|
"total_incorrect": total_incorrect,
|
|
"current_streak": current_streak,
|
|
"best_streak": best_streak,
|
|
"last_session_at": last_session_at
|
|
},
|
|
"card_stats": card_stats.duplicate()
|
|
}
|
|
|
|
func from_dict(data: Dictionary) -> void:
|
|
deck_id = data.get("deck_id", "")
|
|
|
|
var stats = data.get("stats", {})
|
|
total_sessions = stats.get("total_sessions", 0)
|
|
total_cards_studied = stats.get("total_cards_studied", 0)
|
|
total_correct = stats.get("total_correct", 0)
|
|
total_incorrect = stats.get("total_incorrect", 0)
|
|
current_streak = stats.get("current_streak", 0)
|
|
best_streak = stats.get("best_streak", 0)
|
|
last_session_at = stats.get("last_session_at", "")
|
|
|
|
card_stats = data.get("card_stats", {}).duplicate()
|
|
|
|
func record_answer(card_id: String, is_correct: bool) -> void:
|
|
if not card_stats.has(card_id):
|
|
card_stats[card_id] = {
|
|
"correct": 0,
|
|
"incorrect": 0,
|
|
"last_seen_at": "",
|
|
"next_review_at": "",
|
|
"ease_factor": 2.5
|
|
}
|
|
|
|
if is_correct:
|
|
total_correct += 1
|
|
card_stats[card_id]["correct"] += 1
|
|
current_streak += 1
|
|
if current_streak > best_streak:
|
|
best_streak = current_streak
|
|
else:
|
|
total_incorrect += 1
|
|
card_stats[card_id]["incorrect"] += 1
|
|
current_streak = 0
|
|
|
|
total_cards_studied += 1
|
|
var now = Time.get_datetime_string_from_system(true, true) + "Z"
|
|
card_stats[card_id]["last_seen_at"] = now
|
|
last_session_at = now
|
|
|
|
_update_next_review(card_id, is_correct)
|
|
|
|
func get_accuracy() -> float:
|
|
var total = total_correct + total_incorrect
|
|
if total == 0:
|
|
return 0.0
|
|
return (float(total_correct) / float(total)) * 100.0
|
|
|
|
func get_card_stats(card_id: String) -> Dictionary:
|
|
return card_stats.get(card_id, {
|
|
"correct": 0,
|
|
"incorrect": 0,
|
|
"last_seen_at": "",
|
|
"next_review_at": "",
|
|
"ease_factor": 2.5
|
|
})
|
|
|
|
func _update_next_review(card_id: String, is_correct: bool) -> void:
|
|
var stats = card_stats[card_id]
|
|
var ease_factor: float = stats.get("ease_factor", 2.5)
|
|
|
|
if is_correct:
|
|
ease_factor = min(ease_factor + 0.1, 3.0)
|
|
else:
|
|
ease_factor = max(ease_factor - 0.2, 1.3)
|
|
|
|
stats["ease_factor"] = ease_factor
|
|
|
|
var review_interval_days: int = 1
|
|
if is_correct:
|
|
var correct_count = stats.get("correct", 0)
|
|
review_interval_days = int(correct_count * ease_factor)
|
|
else:
|
|
review_interval_days = 1
|
|
|
|
var now_unix = Time.get_unix_time_from_system()
|
|
#var now_unix = Time.get_time_dict_from_unix_time(Time.get_unix_time_from_system())
|
|
var next_review_unix = now_unix + (review_interval_days * 86400) # 86400 seconds in a day
|
|
var next_review_dict = Time.get_datetime_dict_from_unix_time(int(next_review_unix))
|
|
stats["next_review_at"] = "%04d-%02d-%02dT%02d:%02d:%02dZ" % [
|
|
next_review_dict.year, next_review_dict.month, next_review_dict.day,
|
|
next_review_dict.hour, next_review_dict.minute, next_review_dict.second
|
|
]
|
|
|
|
func start_session() -> void:
|
|
total_sessions += 1
|