1 /* 2 SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org> 3 SPDX-License-Identifier: GPL-2.0-or-later 4 */ 5 6 #include "multiplechoicebackendmode.h" 7 8 #include <KLocalizedString> 9 10 #include <QRandomGenerator> 11 12 #include "multiplechoicedata.h" 13 14 using namespace Practice; 15 MultipleChoiceBackendMode(AbstractFrontend * frontend,QObject * parent,Practice::SessionManagerBase * sessionManager)16MultipleChoiceBackendMode::MultipleChoiceBackendMode(AbstractFrontend *frontend, QObject *parent, Practice::SessionManagerBase *sessionManager) 17 : AbstractBackendMode(frontend, parent) 18 , m_sessionManager(sessionManager) 19 { 20 m_numberOfChoices = Prefs::numberMultipleChoiceAnswers(); 21 } 22 setTestEntry(TestEntry * current)23bool MultipleChoiceBackendMode::setTestEntry(TestEntry *current) 24 { 25 m_current = current; 26 m_hints.clear(); 27 m_choices.clear(); 28 m_question.clear(); 29 30 prepareChoices(current); 31 populateFrontEnd(); 32 return true; 33 } 34 prepareChoices(TestEntry * current)35void MultipleChoiceBackendMode::prepareChoices(TestEntry *current) 36 { 37 Q_UNUSED(current) 38 setQuestion(m_current->entry()->translation(m_current->languageFrom())->text()); 39 40 QStringList choices = m_sessionManager->multipleChoiceAnswers(m_numberOfChoices - 1); 41 for (const QString &choice : qAsConst(choices)) { 42 int position = QRandomGenerator::global()->bounded(m_choices.count() + 1); 43 m_choices.insert(position, choice); 44 } 45 int correctAnswer = QRandomGenerator::global()->bounded(m_choices.count() + 1); 46 m_choices.insert(correctAnswer, m_current->entry()->translation(m_current->languageTo())->text()); 47 setCorrectAnswer(correctAnswer); 48 } 49 populateFrontEnd()50void MultipleChoiceBackendMode::populateFrontEnd() 51 { 52 MultipleChoiceData data; 53 data.question = m_question; 54 data.choices = m_choices; 55 56 m_frontend->setQuestion(QVariant::fromValue<MultipleChoiceData>(data)); 57 m_frontend->setSolution(m_correctAnswer); 58 m_frontend->setQuestionSound(m_current->entry()->translation(m_current->languageFrom())->soundUrl()); 59 m_frontend->setSolutionSound(m_current->entry()->translation(m_current->languageTo())->soundUrl()); 60 m_frontend->setQuestionPronunciation(m_current->entry()->translation(m_current->languageFrom())->pronunciation()); 61 m_frontend->setSolutionPronunciation(m_current->entry()->translation(m_current->languageTo())->pronunciation()); 62 m_frontend->setResultState(AbstractFrontend::QuestionState); 63 m_frontend->showQuestion(); 64 } 65 setQuestion(const QString & question)66void MultipleChoiceBackendMode::setQuestion(const QString &question) 67 { 68 m_question = question; 69 } 70 numberOfChoices()71int MultipleChoiceBackendMode::numberOfChoices() 72 { 73 return m_numberOfChoices; 74 } 75 setChoices(const QStringList & choices)76void MultipleChoiceBackendMode::setChoices(const QStringList &choices) 77 { 78 m_choices = choices; 79 } 80 setCorrectAnswer(int index)81void MultipleChoiceBackendMode::setCorrectAnswer(int index) 82 { 83 qDebug() << "correct: " << index << m_choices.at(index); 84 m_correctAnswer = index; 85 } 86 checkAnswer()87void MultipleChoiceBackendMode::checkAnswer() 88 { 89 if (!m_frontend->userInput().isNull() && m_frontend->userInput().toInt() == m_correctAnswer) { 90 emit answerRight(); 91 } else { 92 if (!m_frontend->userInput().isNull()) { 93 m_current->addUserAnswer(m_choices.at(m_frontend->userInput().toInt())); 94 } 95 emit answerWrongShowSolution(); 96 } 97 } 98 hintAction()99void MultipleChoiceBackendMode::hintAction() 100 { 101 if (m_choices.count() - m_hints.count() <= 2) { 102 // show solution 103 m_frontend->setFeedback(i18n("You revealed the answer by using too many hints.")); 104 emit answerWrongShowSolution(); 105 return; 106 } 107 108 int hint = -1; 109 do { 110 hint = QRandomGenerator::global()->bounded(m_choices.count()); 111 } while (hint == m_correctAnswer || m_hints.contains(hint)); 112 m_hints.append(hint); 113 m_frontend->setHint(QVariant(hint)); 114 } 115