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.
This commit is contained in:
Torsten Schulz (local)
2026-01-20 15:14:50 +01:00
parent eddbe5fa3f
commit 7765067d1b

View File

@@ -1046,16 +1046,36 @@ export default {
normalizedExcludeSet.add(this.normalizeVocab(excludePrompt)); normalizedExcludeSet.add(this.normalizeVocab(excludePrompt));
} }
// Füge 3 Distraktoren hinzu // 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);
}
}
});
// Entferne Duplikate
const uniqueDistractors = [...new Set(allDistractors)];
// Füge Distraktoren hinzu, bis wir 4 Optionen haben
let attempts = 0; let attempts = 0;
const maxAttempts = 100; // Erhöht, da wir mehr Filter haben const maxAttempts = 200;
while (options.size < 4 && allVocabs.length > 1 && attempts < maxAttempts) { while (options.size < 4 && uniqueDistractors.length > 0 && attempts < maxAttempts) {
attempts++; attempts++;
const randomVocab = allVocabs[Math.floor(Math.random() * allVocabs.length)]; const randomIndex = Math.floor(Math.random() * uniqueDistractors.length);
const distractor = this.vocabTrainerDirection === 'L2R' ? randomVocab.reference : randomVocab.learning; const distractor = uniqueDistractors[randomIndex];
// Prüfe: Distraktor darf nicht gleich correctAnswer oder excludePrompt sein (mit Normalisierung)
if (distractor && distractor.trim()) { if (distractor && distractor.trim()) {
const normalizedDistractor = this.normalizeVocab(distractor); const normalizedDistractor = this.normalizeVocab(distractor);
if (!normalizedExcludeSet.has(normalizedDistractor) && !options.has(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 // Falls immer noch nicht genug Optionen: Verwende auch die andere Richtung der aktuellen Vokabeln
if (options.size < 4) { if (options.size < 4 && allVocabs.length > 0) {
const genericOptions = ['Option A', 'Option B', 'Option C', 'Option D']; allVocabs.forEach(vocab => {
let index = 0; if (options.size >= 4) return;
while (options.size < 4 && index < genericOptions.length) {
const option = genericOptions[index]; // Verwende die andere Richtung als Distraktor
if (!normalizedExcludeSet.has(this.normalizeVocab(option)) && !options.has(option)) { const otherDirection = this.vocabTrainerDirection === 'L2R' ? vocab.learning : vocab.reference;
options.add(option); 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 // Shuffle