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));
}
// 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