From 10d8ee015cddbeb14f9546f272e90a587a427cc3 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 30 Mar 2026 08:45:59 +0200 Subject: [PATCH] feat(VocabLessonView): improve vocab question generation and answer validation - Introduced a new method to retrieve equivalent vocabulary answers based on user prompts and direction, enhancing the accuracy of answer options. - Updated the buildChoiceOptions method to handle multiple correct answers and ensure the prompt is excluded from choices. - Enhanced the current vocab question structure to support multiple acceptable answers, improving user feedback and engagement during exercises. --- frontend/src/views/social/VocabLessonView.vue | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue index d0a3953..5e667c5 100644 --- a/frontend/src/views/social/VocabLessonView.vue +++ b/frontend/src/views/social/VocabLessonView.vue @@ -1589,11 +1589,30 @@ export default { // Starte neue Frage im Multiple Choice Modus this.nextVocabQuestion(); }, - buildChoiceOptions(correctAnswer, allVocabs, excludePrompt = null) { - const options = new Set([correctAnswer]); + getEquivalentVocabAnswers(prompt, direction, allVocabs) { + const normalizedPrompt = this.normalizeVocab(prompt); + const matches = []; + + allVocabs.forEach((entry) => { + const source = direction === 'L2R' ? entry.learning : entry.reference; + const target = direction === 'L2R' ? entry.reference : entry.learning; + if (!source || !target) return; + if (this.normalizeVocab(source) !== normalizedPrompt) return; + if (!matches.includes(target)) { + matches.push(target); + } + }); + + return matches; + }, + buildChoiceOptions(correctAnswers, allVocabs, excludePrompt = null) { + const normalizedCorrectAnswers = Array.isArray(correctAnswers) ? correctAnswers : [correctAnswers]; + const options = new Set(normalizedCorrectAnswers.filter(Boolean)); // Normalisiere alle Werte für den Vergleich (trim + lowercase) const normalizedExcludeSet = new Set(); - normalizedExcludeSet.add(this.normalizeVocab(correctAnswer)); + normalizedCorrectAnswers.forEach((answer) => { + normalizedExcludeSet.add(this.normalizeVocab(answer)); + }); // Wichtig: Der Prompt (die Frage) darf nicht in den Optionen erscheinen if (excludePrompt) { normalizedExcludeSet.add(this.normalizeVocab(excludePrompt)); @@ -1698,10 +1717,22 @@ export default { const randomIndex = Math.floor(Math.random() * sourcePool.length); const vocab = sourcePool[randomIndex]; this.vocabTrainerDirection = Math.random() < 0.5 ? 'L2R' : 'R2L'; + const allTrainerVocabs = [...this.importantVocab, ...this.vocabTrainerMixedPool]; + const prompt = this.vocabTrainerDirection === 'L2R' ? vocab.learning : vocab.reference; + const acceptableAnswers = this.getEquivalentVocabAnswers( + prompt, + this.vocabTrainerDirection, + allTrainerVocabs + ); this.currentVocabQuestion = { vocab: vocab, - prompt: this.vocabTrainerDirection === 'L2R' ? vocab.learning : vocab.reference, - answer: this.vocabTrainerDirection === 'L2R' ? vocab.reference : vocab.learning, + prompt, + answers: acceptableAnswers.length > 0 + ? acceptableAnswers + : [this.vocabTrainerDirection === 'L2R' ? vocab.reference : vocab.learning], + answer: acceptableAnswers.length > 0 + ? acceptableAnswers.join(' / ') + : (this.vocabTrainerDirection === 'L2R' ? vocab.reference : vocab.learning), key: this.getVocabKey(vocab), source: questionSource }; @@ -1720,8 +1751,8 @@ export default { debugLog('[VocabLessonView] Answer:', this.currentVocabQuestion.answer); // Wichtig: Der Prompt (die Frage) darf nicht in den Optionen erscheinen this.vocabTrainerChoiceOptions = this.buildChoiceOptions( - this.currentVocabQuestion.answer, - [...this.importantVocab, ...this.vocabTrainerMixedPool], + this.currentVocabQuestion.answers, + allTrainerVocabs, this.currentVocabQuestion.prompt // Exkludiere den Prompt ); debugLog('[VocabLessonView] Choice-Optionen erstellt:', this.vocabTrainerChoiceOptions); @@ -1757,8 +1788,9 @@ export default { } const normalizedUser = this.normalizeVocab(userAnswer); - const normalizedCorrect = this.normalizeVocab(this.currentVocabQuestion.answer); - this.vocabTrainerLastCorrect = normalizedUser === normalizedCorrect; + const normalizedCorrectAnswers = (this.currentVocabQuestion.answers || [this.currentVocabQuestion.answer]) + .map(answer => this.normalizeVocab(answer)); + this.vocabTrainerLastCorrect = normalizedCorrectAnswers.includes(normalizedUser); // Update Stats const stats = this.getVocabStats(this.currentVocabQuestion.vocab);