Sample solution of Assignment 1

Notice how the Quiz model class is separate from the QuizRunner which sets up the console UI

Important points to note:

  1. no hard coding for the size of quiz - the Quiz object supplies its size via the getQuizSize() method
  2. use of private methods
  3. use of static for some methods and data
  4. notice how the methods of Quiz class are kept as simple as possible
#include <cctype>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
 
//The Quiz model class 
class Quiz {
    public:
        Quiz() {
            initMap();
            nextQuestion = 0;
        }
 
        int getQuizSize() {
            return qaMap.size();
        }
 
        string getNextQuestion() {
            if(nextQuestion == qaMap.size()) {
               return "";
            }
            nextQuestion++;
            return questions.at(nextQuestion - 1);
        }
 
        string getAnswerFor(string question) {
            return qaMap.find(question)->second;
        }
 
    private:
        void initMap() {
            qaMap["Oman"] = "Muscat";
            qaMap["Yemen"] = "Sanaa";
            qaMap["Saudi Arabia"] = "Riyadh";
            qaMap["Qatar"] = "Doha";
            initQuestions();
        }
 
        void initQuestions() {
            map<string, string>::iterator it;
            for(it=qaMap.begin(); it != qaMap.end(); it++) {
                questions.push_back((*it).first);
            }
            random_shuffle(questions.begin(), questions.end());
        }
 
        map<string, string> qaMap;
        vector<string> questions;
        int nextQuestion;
};
 
class StringUtils {
public:
    static void toLower(string *str) {
        for(int i = 0; i < str->length(); i++)
            str->at(i) = tolower(str->at(i));
    }
};
 
class QuizRunner {
    public:
        QuizRunner() {
            quiz = new Quiz();
            rightCount = 0;
            wrongCount = 0;
            mistakeQuestions = new set<string>();
        }
 
        void runQuiz() {
            static int tries = 0;
            tries++;
            attempt = tries;
 
            string userAnswer; string correctAnswer;
            string question;
            string questionText = "";
 
            int quizSize = quiz->getQuizSize();
 
            for(int i = 1; i <= quizSize; i++) {
                question = quiz->getNextQuestion();
                questionText = "What is the capital of "+question+"?";
                cout << i << "." << questionText << endl;
                cin >> userAnswer;
                StringUtils::toLower(&userAnswer);
 
                correctAnswer = quiz->getAnswerFor(question);
                StringUtils::toLower(&correctAnswer);
 
                if (userAnswer == correctAnswer) {
                    rightCount++;
                }
                else {
                    wrongCount++;
                    mistakeQuestions->insert(questionText);
                }
            }
 
            displayQuizResults();
 
            if (wrongCount > 0) {
                cout << "The quiz will now start again!" << endl;
                QuizRunner *repeatRunner = new QuizRunner();
                repeatRunner->runQuiz();
            }
        }
 
        void displayQuizResults() {
            cout << endl << "=== Result of Country Capitals Quiz ===" << endl;
            cout << "Total questions : "  << quiz->getQuizSize() << endl;
            cout << "Correct answers : " << rightCount << endl;
            cout << "Wrong answers : " << wrongCount << endl;
            cout << "You scored "
                 << ((double) rightCount / quiz->getQuizSize()) * 100.0 << "%"
                 << " on this quiz" << endl << endl;
            cout << "This was attempt no: " << attempt << endl << endl;
 
            if (wrongCount > 0) {
                cout << "The questions answered incorrectly are:" << endl;
                set<string>::iterator it;
                for(it=mistakeQuestions->begin();it!=mistakeQuestions->end(); it++)
                    cout << *it << endl;
            }
            cout <<endl << "  === End of Results ===" << endl;
        }
 
    private:
        Quiz *quiz;
        int rightCount;
        int wrongCount;
        int attempt;
        set<string> *mistakeQuestions;
};
 
int main() {
    QuizRunner runner;
    runner.runQuiz();
}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License