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:
- no hard coding for the size of quiz - the Quiz object supplies its size via the getQuizSize() method
- use of private methods
- use of static for some methods and data
- 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(); }
page revision: 2, last edited: 23 Dec 2013 16:08