From 7765067d1b65915bc4fffe5357b65f5c3a44f498 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Tue, 20 Jan 2026 15:14:50 +0100 Subject: [PATCH] Refine distractor selection logic in VocabLessonView to enhance vocabulary options - Updated the logic for generating distractors by collecting unique vocabulary entries from both learning and reference directions, ensuring no duplicates are included. - Increased the maximum attempts for finding distractors and adjusted fallback mechanisms to ensure a minimum of two options are provided, improving the overall user experience. --- frontend/src/views/social/VocabLessonView.vue | 62 ++++++++++++++----- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue index b0c681a..3522154 100644 --- a/frontend/src/views/social/VocabLessonView.vue +++ b/frontend/src/views/social/VocabLessonView.vue @@ -1046,16 +1046,36 @@ export default { normalizedExcludeSet.add(this.normalizeVocab(excludePrompt)); } - // Füge 3 Distraktoren hinzu - let attempts = 0; - const maxAttempts = 100; // Erhöht, da wir mehr Filter haben + // Sammle alle verfügbaren Distraktoren aus beiden Richtungen + const allDistractors = []; + allVocabs.forEach(vocab => { + // Füge beide Richtungen hinzu (learning und reference) + if (vocab.learning && vocab.learning.trim()) { + const normalized = this.normalizeVocab(vocab.learning); + if (!normalizedExcludeSet.has(normalized)) { + allDistractors.push(vocab.learning); + } + } + if (vocab.reference && vocab.reference.trim()) { + const normalized = this.normalizeVocab(vocab.reference); + if (!normalizedExcludeSet.has(normalized)) { + allDistractors.push(vocab.reference); + } + } + }); - while (options.size < 4 && allVocabs.length > 1 && attempts < maxAttempts) { + // Entferne Duplikate + const uniqueDistractors = [...new Set(allDistractors)]; + + // Füge Distraktoren hinzu, bis wir 4 Optionen haben + let attempts = 0; + const maxAttempts = 200; + + while (options.size < 4 && uniqueDistractors.length > 0 && attempts < maxAttempts) { attempts++; - const randomVocab = allVocabs[Math.floor(Math.random() * allVocabs.length)]; - const distractor = this.vocabTrainerDirection === 'L2R' ? randomVocab.reference : randomVocab.learning; + const randomIndex = Math.floor(Math.random() * uniqueDistractors.length); + const distractor = uniqueDistractors[randomIndex]; - // Prüfe: Distraktor darf nicht gleich correctAnswer oder excludePrompt sein (mit Normalisierung) if (distractor && distractor.trim()) { const normalizedDistractor = this.normalizeVocab(distractor); if (!normalizedExcludeSet.has(normalizedDistractor) && !options.has(distractor)) { @@ -1064,17 +1084,25 @@ export default { } } - // Falls nicht genug Optionen gefunden wurden, füge generische Optionen hinzu - if (options.size < 4) { - const genericOptions = ['Option A', 'Option B', 'Option C', 'Option D']; - let index = 0; - while (options.size < 4 && index < genericOptions.length) { - const option = genericOptions[index]; - if (!normalizedExcludeSet.has(this.normalizeVocab(option)) && !options.has(option)) { - options.add(option); + // Falls immer noch nicht genug Optionen: Verwende auch die andere Richtung der aktuellen Vokabeln + if (options.size < 4 && allVocabs.length > 0) { + allVocabs.forEach(vocab => { + if (options.size >= 4) return; + + // Verwende die andere Richtung als Distraktor + const otherDirection = this.vocabTrainerDirection === 'L2R' ? vocab.learning : vocab.reference; + if (otherDirection && otherDirection.trim()) { + const normalized = this.normalizeVocab(otherDirection); + if (!normalizedExcludeSet.has(normalized) && !options.has(otherDirection)) { + options.add(otherDirection); + } } - index++; - } + }); + } + + // Falls immer noch nicht genug Optionen: Verwende weniger Optionen (mindestens 2) + if (options.size < 2) { + console.warn('[buildChoiceOptions] Nicht genug Optionen gefunden, verwende nur', options.size, 'Optionen'); } // Shuffle