feat: Erweiterung der Antwortvarianten für Vokabelübungen zur Unterstützung von Alternativen und Phrasen
All checks were successful
Deploy to production / deploy (push) Successful in 1m58s
All checks were successful
Deploy to production / deploy (push) Successful in 1m58s
This commit is contained in:
@@ -4152,6 +4152,67 @@ export default {
|
||||
: s;
|
||||
return this.normalizeComparableText(source);
|
||||
},
|
||||
expandSingleAnswerVariants(answer) {
|
||||
const base = String(answer || '').trim();
|
||||
if (!base) return [];
|
||||
|
||||
const words = base.split(/\s+/).map((word) => {
|
||||
if (!word.includes('/')) {
|
||||
return [word];
|
||||
}
|
||||
|
||||
const match = word.match(/^([([{„\"'“‘]*)(.*?)([)\]}.,!?;:»\"'”’]*)$/);
|
||||
const prefix = match?.[1] || '';
|
||||
const core = match?.[2] || word;
|
||||
const suffix = match?.[3] || '';
|
||||
const parts = core
|
||||
.split('/')
|
||||
.map((part) => part.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
if (parts.length < 2 || parts.length > 8) {
|
||||
return [word];
|
||||
}
|
||||
|
||||
return parts.map((part) => `${prefix}${part}${suffix}`);
|
||||
});
|
||||
|
||||
const variants = [''];
|
||||
for (const options of words) {
|
||||
const next = [];
|
||||
for (const current of variants) {
|
||||
for (const option of options) {
|
||||
next.push(`${current}${current ? ' ' : ''}${option}`);
|
||||
}
|
||||
}
|
||||
if (next.length > 48) {
|
||||
return [base];
|
||||
}
|
||||
variants.splice(0, variants.length, ...next);
|
||||
}
|
||||
|
||||
return [...new Set([base, ...variants])];
|
||||
},
|
||||
splitPhraseAlternatives(answer) {
|
||||
const base = String(answer || '').trim();
|
||||
if (!base) return [];
|
||||
// Splits full-phrase alternatives like "A / B" into ["A", "B"] when they look like phrase-level alternatives.
|
||||
const parts = base.split(/\s*[\/|;]\s*/).map(p => p.trim()).filter(Boolean);
|
||||
if (parts.length >= 2 && parts.length <= 6) return parts;
|
||||
return [base];
|
||||
},
|
||||
expandAnswerVariants(answer) {
|
||||
const base = String(answer || '').trim();
|
||||
if (!base) return [];
|
||||
|
||||
const phraseAlternatives = this.splitPhraseAlternatives(base);
|
||||
if (phraseAlternatives.length >= 2) {
|
||||
const expanded = phraseAlternatives.flatMap((part) => this.expandSingleAnswerVariants(part));
|
||||
return [...new Set(expanded)];
|
||||
}
|
||||
|
||||
return this.expandSingleAnswerVariants(base);
|
||||
},
|
||||
reportSrsReviewForCurrentQuestion(isCorrect) {
|
||||
if (!this.currentVocabQuestion?.vocab || !this.courseId) {
|
||||
return;
|
||||
@@ -4185,10 +4246,11 @@ export default {
|
||||
const normalizedUser = this.normalizeVocab(userAnswer, {
|
||||
ignoreTrailingParentheticalNotes: useTypingNormalization
|
||||
});
|
||||
const normalizedCorrectAnswers = (this.currentVocabQuestion.answers || [this.currentVocabQuestion.answer])
|
||||
.map(answer => this.normalizeVocab(answer, {
|
||||
ignoreTrailingParentheticalNotes: useTypingNormalization
|
||||
}));
|
||||
const rawAnswers = this.currentVocabQuestion.answers || [this.currentVocabQuestion.answer];
|
||||
// Expand alternatives like "A / B" into separate acceptable answers
|
||||
const expandedAnswers = rawAnswers.flatMap(a => this.expandAnswerVariants(a));
|
||||
const normalizedCorrectAnswers = expandedAnswers
|
||||
.map(answer => this.normalizeVocab(answer, { ignoreTrailingParentheticalNotes: useTypingNormalization }));
|
||||
this.vocabTrainerLastCorrect = normalizedCorrectAnswers.includes(normalizedUser);
|
||||
|
||||
// Update Stats
|
||||
|
||||
Reference in New Issue
Block a user