Prefer high-performing distractors

This commit is contained in:
hz
2026-07-20 02:44:58 -05:00
parent dae3a31b71
commit 121e80b2ea
6 changed files with 152 additions and 20 deletions
+27 -2
View File
@@ -546,6 +546,7 @@ func _prepare_question_choices(question: Dictionary) -> Dictionary:
var all_choices: Array = question.get("choices", []).duplicate(true)
var correct_id := str(question.get("correct_choice_id", ""))
var percentages: Dictionary = question.get("choice_selection_percentages", {})
var correct_choice: Dictionary = {}
var distractors: Array = []
for choice in all_choices:
@@ -556,8 +557,7 @@ func _prepare_question_choices(question: Dictionary) -> Dictionary:
else:
distractors.append(choice)
distractors.shuffle()
var presented: Array = distractors.slice(0, min(4, distractors.size()))
var presented: Array = _select_weighted_distractors(distractors, percentages, 4)
if not correct_choice.is_empty():
presented.append(correct_choice)
elif not all_choices.is_empty():
@@ -567,6 +567,31 @@ func _prepare_question_choices(question: Dictionary) -> Dictionary:
return question
func _select_weighted_distractors(distractors: Array, percentages: Dictionary, count: int) -> Array:
var remaining: Array = distractors.duplicate(true)
var selected: Array = []
while selected.size() < count and not remaining.is_empty():
var total_weight := 0.0
for choice in remaining:
total_weight += _distractor_weight(str(choice.get("id", "")), percentages)
var threshold := randf() * total_weight
var cumulative := 0.0
var selected_index := remaining.size() - 1
for index in range(remaining.size()):
cumulative += _distractor_weight(str(remaining[index].get("id", "")), percentages)
if threshold < cumulative:
selected_index = index
break
selected.append(remaining[selected_index])
remaining.remove_at(selected_index)
return selected
func _distractor_weight(choice_id: String, percentages: Dictionary) -> float:
var selection_rate := clampf(float(percentages.get(choice_id, 0)), 0.0, 100.0)
return 1.0 + 5.0 * selection_rate / 100.0
func _build_core_question_pool() -> Array:
var pool: Array = []
var profile := ProfileService.get_profile()