diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index 6d8c769..33d5a01 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -500,6 +500,33 @@ export default class VocabService { return normalized.replace(/\s+/g, ''); } + _expandComparableAnswerVariants(text) { + const raw = String(text || '').trim(); + if (!raw) return []; + const variants = new Set([raw]); + + // Beispiel: "heute (heute am Tag)" -> "heute" und "heute am Tag" + const withoutParentheses = raw.replace(/\s*\([^)]*\)\s*/g, ' ').replace(/\s+/g, ' ').trim(); + if (withoutParentheses) variants.add(withoutParentheses); + + const parenMatches = raw.match(/\(([^)]+)\)/g) || []; + parenMatches.forEach((chunk) => { + const content = chunk.replace(/[()]/g, '').trim(); + if (content) variants.add(content); + }); + + return Array.from(variants); + } + + _isEquivalentAnswer(userAnswer, canonicalAnswer) { + const normalizedUser = this._normalizeTextAnswer(userAnswer); + if (!normalizedUser) return false; + const canonicalVariants = this._expandComparableAnswerVariants(canonicalAnswer) + .map((entry) => this._normalizeTextAnswer(entry)) + .filter(Boolean); + return canonicalVariants.includes(normalizedUser); + } + _parseExercisePayload(value) { if (!value) return {}; if (typeof value === 'string') { @@ -3550,7 +3577,7 @@ export default class VocabService { if (typeof userAnswer === 'string') { const u = norm(userAnswer); if (!u) return false; - return correctTexts.some((t) => norm(t) === u); + return correctTexts.some((t) => this._isEquivalentAnswer(userAnswer, t)); } // Legacy: Index in die gespeicherten (nicht gemischten) Optionen