TheMathGame: Your task is to develop a program that will teach youngsters the ba
ID: 3711789 • Letter: T
Question
TheMathGame:
Your task is to develop a program that will teach youngsters the basic math facts of addition, subtraction, multiplication and division. The program generates random math problems for students to answer. Students get a small reward for correct answers and suffer a small penalty for incorrect ones. User statistics need to be recorded in a text file so that they me loaded back into the program when the student returns to play the game again. In addition, the youngster should be allowed to see how (s)he is doing at any time while (s)he is playing the game. One of the MAJOR objectives of this assessment is for you to demonstrate your ability to use functions and employ reference and value parameters.
WARNING:
If you do not employ functions which use reference and value parameters you will NOT pass the midterm.
You should also note that your main() function should consist of mostly function calls and not be greater than 100 lines in total; however, your entire program will be closer to 500 - 800 lines of code!
PROGRAM REQUIREMENTS
Generate simple math fact problems:
Addition (the total must be an integer >= 0)
Subtraction (the difference must be an integer >= 0)
Multiplication (the product must be an integer >= 0)
Division (the quotient must be an integer >= 0)
Validate user input at every opportunity. If your program crashes because you allow the user to make an invalid entry and you did not write code to handle such potential exceptions, you will NOT pass the midterm!
The program should keep track of the following statistics:
The user’s name
The total correct answers
The total wrong answers
The total earnings ($0.05 is awarded for every correct response and $0.03 is subtracted from every incorrect response)
A separate text file must be created for every user:
Statistics are read from the file at the start of the game (if the user is a returning player).
Statistics are recorded at the end of every game.
The program must be developed using functions so that the main() function consists mostly of function calls. Below is a list of most of the required functions, you may add your own functions if you like, just remember that If you do not employ functions which use reference and value parameters you will NOT pass the midterm:
credits //This function is used to display your name and what the program does
menu // This function is used to display the menu with various options
validateUserResponse // This function is used to validate user input from the menu
validateUserAnswer // This function is used to validate user input and ensure that ONLY numeric answers are entered by the user.
checkUserAnswer // given a math problem, this function is used to check if the answer the user entered is correct or incorrect
updateStats // This function is used to keep a running total of game statistics (in RAM)
displayStats // This function is used to display statistics on screen
retireveStats // This function is used to retrieve player statistics from external txt file when the game starts, assuming the player is a returning player, else create a text file to store the stats.
saveStats // This function is used to save player statistics on an external txt file.
You may also want to consider the following four functions: generateAddition, generateSubtraction, generateMultiplication and generateDivision // use these to generate a problem of the appropriate type.
All functions must be correctly prototyped.
All functions must be correctly defined.
You must use meaningful variable names.
You must comment your code.
You must use variables of the correct type and initialize them with a proper value.
GENERAL RESTRICTIONS FOR ALL QUIZZES, MIDTERM AND FINAL EXAM
No global variables
No labels or go-to statements
No infinite loops, examples include:
for(;;)
while(1)
while(true)
do{//code}while(1);
No break statements to exit loops
If you violate any of these restrictions, you will automatically get a score of ZERO!
SPECIFIC RESTRICTIONS FOR THIS ACTIVITY
Do not use vectors
Do not use Pointers
Explanation / Answer
#include <iostream>
#include <string>
#include <fstream>
#include "Stats.h"
#include "Gen.h"
using namespace std;
void credits();
Gen nameValidatenLoad();
void inputValidation(string &name);
void alterStats(Stats *, int choice);
void menu();
string selection(Gen &);
void validateChoice(string& choice);
void gennUpdate(string choice, int&, Gen&); //generate question/display stats n change stats depending on answer
int main()
{
string choice;
int i = 0;
char cont = 'y';
credits(); //first screen where user sees credit and must answer Y/y in order to continue, any other answer will terminate program
Gen userStat = nameValidatenLoad();
cout << userStat; //fine here
for (i = 0; i < 1; i++)
{
menu();
choice = selection(userStat); //validate and return choice
gennUpdate(choice, i, userStat); //excludes n/N which exits program
//menu();
//choice = selection(userStat);
}
system("pause");
return 0;
}
void credits()
{
string cont;
cout << "***********************" << endl;
cout << "***********************" << endl;
cout << "***********************" << endl;
cout << "****** ******" << endl;
cout << "******TheMathGame******" << endl;
cout << "****** ******" << endl;
cout << "***********************" << endl;
cout << "***********************" << endl;
cout << "***********************" << endl;
cout << "y/Y to continue, other keys to exit ";
getline(cin, cont);
if (cont != "y" && cont != "Y")
{
exit(0);
}
}
void alterStats(Stats *userStat, int choice) //use of pointers to access Stats object & choice to indicate user's action
{
}
Gen nameValidatenLoad()
{
string name;
cout << "Enter your name and press <ENTER> ";
getline(cin, name);
inputValidation(name);
Gen userStat(name); //create Stats object(userStat)
return userStat;
}
string selection(Gen &userStat)
{
string choice; //user choice input
getline(cin, choice);
validateChoice(choice);
return choice;
}
void validateChoice(string& choice) //function header(same as function prototype but has body to define function); function inside selection
{
//cout << switchChoice << endl;
int counter = 0;
char choiceChar;
while (counter == 0) //has to be less than length because max index is length - 1
{ // or cond can be (counter <= userInputLength - 1)
while (choice.length() > 1 || choice.length() == 0) //if choice input more than 1 char or 0 capture whitespace?
{
cout << "enter the appropriate selection ";
getline(cin, choice);
}
choiceChar = choice[0]; //since only 1 char, take the 1 char stored at index 0 in string
while (counter < 1)
{
if (choiceChar == 49 || choiceChar == 50 || choiceChar == 51 || choiceChar == 52 || choiceChar == 53)
{
counter++;
}
else if (choiceChar == 'n' || choiceChar == 'N')
{
exit(0);
}
else
{
cout << "that is an invalid choice ";
cout << "enter the appropriate selection ";
getline(cin, choice);
while (choice.length() > 1 || choice.length() == 0) //if choice input more than 1 char or 0 capture whitespace?
{
cout << "enter the appropriate selection ";
getline(cin, choice);
}
choiceChar = choice[0]; //since only 1 char, take the 1 char stored at index 0 in string
}
}
}
}
void inputValidation(string &name) //function header(same as function prototype but has body to define function)
{
int userInputLength;
int counter = 0;
userInputLength = name.length(); //how many characters in string var userInput
while (userInputLength == 0) //check if they typed nothing, just press enter, first validation
{ /* use while than If since it loops until user gives right answer, user stuck in loop*/
system("cls");
cout << " you did not enter anything" << endl;
cout << "please enter it again" << endl;
getline(cin, name); //get another entry if wrong
userInputLength = name.length(); //check again and compares with condition, if cond still true, loop again
}
while (counter < userInputLength) /*has to be less than length because max index is length - 1*/
{ // or cond can be (counter <= userInputLength - 1)
if (!(isalpha(name[counter]))) //note ! in 1st outer parenthesis
{
cout << "you did not enter a proper name" << endl;
cout << "please enter it again" << endl;
getline(cin, name);
userInputLength = name.length();
counter = 0;
while (userInputLength == 0) //check if they typed nothing, just press enter, first validation
{ /* use while than If since it loops until user gives right answer, user stuck in loop*/
cout << " you did not enter anything" << endl;
cout << "please enter it again" << endl;
getline(cin, name); //get another entry if wrong
userInputLength = name.length(); //check again and compares with condition, if cond still true, loop again
}
}
else
{
counter = counter + 1; //or counter++;
}
}
system("cls");
}
void menu()
{
cout << "*****CHOOSE A PROBLEM*****" << endl;
cout << "**************************" << endl;
cout << "**************************" << endl;
cout << "***** *****" << endl;
cout << "***** 1. Add *****" << endl;
cout << "***** 2. Subtract *****" << endl;
cout << "***** 3. Divide *****" << endl;
cout << "***** 4. Multiply *****" << endl;
cout << "***** 5. Stats *****" << endl;
cout << "***** n/N to quit *****" << endl;
cout << "***** *****" << endl;
cout << "**************************" << endl;
cout << "**************************" << endl;
}
void gennUpdate(string choice, int &i, Gen &genQns)
{
char choiceChar = choice[0];
char rightOrWrong; //accepts 1 or 0 to indicate correct or wrong
ofstream outData;
if (choiceChar == 49)
{
rightOrWrong = genQns.Add();
//genQns.update(rightOrWrong); //update stats based on rightOrWrong(1 or 0)
genQns.saveStats(outData);
--i;
}
else if (choiceChar == 50)
{
rightOrWrong = genQns.Subtract();
//genQns.update(rightOrWrong);
genQns.saveStats(outData);
--i;
}
else if (choiceChar == 51)
{
rightOrWrong = genQns.Mult();
//genQns.update(rightOrWrong);
genQns.saveStats(outData);
--i;
}
else if (choiceChar == 52)
{
rightOrWrong = genQns.Divide(); //generate division question; check answer and output 1 or 0;
//genQns.update(rightOrWrong);
genQns.saveStats(outData);
--i;
}
else if (choiceChar == 53)
{
cout << genQns;
--i;
}
}
________________________________________________________________________
Stats.cpp
__________________________________________
#include "Stats.h"
#include <fstream>
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
Stats::Stats()
{
}
//constructor
void Stats::loadUser(string userName, ifstream& inData, ofstream& outData) //CONSTRUCTOR WORKS
{
string userFileName = userName + ".txt";
fstream file(userFileName, ios::in | ios::out);
inData.open(userFileName);
//if the user file does not exist, create one
if (!inData.is_open())
{
cout << "welcome new user " << userName << endl;
//create userFile for output. remember that when you issue the command outData.open(userFileName.c_str());
//if the file does not exist, it will get created.
outData.open(userFileName);
//we store values in the file to prevent an exception if we attempt to read data from an empty file
outData << userName << endl;
outData << 0 << endl;
outData << 0 << endl;
outData << 0 << endl;
outData.close();
cout << "A text file with your name was created ";
inData.open(userFileName);
inData >> name;
inData >> totalRight;
inData >> totalWrong;
inData >> totalEarnings;
inData.close();
cout << name;
cout << totalRight;
cout << totalWrong;
}
else //the file exists
{
//you may proceed to read statistics into variables
inData >> name;
inData >> totalRight;
inData >> totalWrong;
inData >> totalEarnings;
//close file once you read the data
inData.close();
//open for output to save the stats --you may or you may not want to do this; let's dicuss in class why!
//outData.open(userFileName.c_str());
cout << "welcome " << name << " ";
cout << name;
cout << totalRight;
cout << totalWrong;
}
}
void Stats::displayStats() //NOT WORKING
{
//return member variables
cout << setprecision(2) << fixed;
cout << "stats for " << name << endl;
cout << "total correct " << totalRight << endl;
cout << "total incorrect " << totalWrong << endl;
cout << "total wages " << totalEarnings << endl;
system("pause");
system("cls");
}
void Stats::saveStats(ofstream& outData)
{
//output member variables to file
string userFileName = name + ".txt";
outData.open(userFileName);
outData << name << endl;
outData << totalRight << endl;
outData << totalWrong << endl;
outData << totalEarnings << endl;
outData.close();
system("pause");
system("cls");
}
void Stats::updateStats(char rightorWrong)
{
//update stats using postfix op
if (rightorWrong == '1')
{
cout << "good job" << endl;
totalRight++;
//totalWages = totalWages + 0.05;
totalEarnings += 0.05;
}
else if (rightorWrong == '0')
{
cout << "WRONG!" << endl;
totalWrong++;
//totalWages = totalWages - 0.03;
totalEarnings -= 0.03;
}
}
ostream &operator <<(ostream &strm, const Stats &obj)
{
strm << setprecision(2) << fixed;
strm << "The stats for " << obj.name << endl;
strm << "total correct " << obj.totalRight << endl;
strm << "total wrong " << obj.totalWrong << endl;
strm << "total wages " << obj.totalEarnings << endl;
return strm;
system("pause");
}
___________________________________________________________________
Stats.h
______________________________________________________________________
#ifndef Stats_H
#define Stats_H
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
class Stats;
ostream &operator << (ostream & someStream, const Stats &someStats); // Overloaded << operator
class Stats
{
protected:
string name;
int totalRight;
int totalWrong;
double totalEarnings;
ofstream outfile;
public:
Stats::Stats();
void loadUser(string, ifstream&, ofstream&);
void updateStats(char);
void displayStats();
void saveStats(ofstream&);
friend ostream &operator << (ostream &, const Stats &);
};
#endif
____________________________________________________________________
Gen.cpp
________________________________________________________
#include "Gen.h"
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <cctype>
using namespace std;
Gen::Gen()
{
}
Gen::Gen(string userName)
{
ifstream inData;
ofstream outData;
loadUser(userName, inData,outData);
}
char Gen::Add()
{
srand((unsigned int)time(NULL));
num1 = rand() % 10;
num2 = rand() % 10;
theCorrectAnswer = num1 + num2; //com generate answer
cout << num1 << " + " << num2 << " = ";
getline(cin, theUserResponse);
//validate the userAnswer
validateUserInput(theUserResponse);
rightorWrong = checkTheAnswer(theUserResponse, &theCorrectAnswer, &rightorWrong); //decided whether 1 or 0; rightorWrong in void Genupdate in main.cpp
updateStats(rightorWrong); //update stats based on 1 or 0, in stats.h
saveStats(outfile); //in stats.h
return rightorWrong;
}
char Gen::Mult()
{
srand((unsigned int)time(NULL));
num1 = rand() % 10;
num2 = rand() % 10;
theCorrectAnswer = num1 * num2;
cout << num1 << " * " << num2 << " = ";
getline(cin, theUserResponse);
//validate the userAnswer
validateUserInput(theUserResponse);
rightorWrong = checkTheAnswer(theUserResponse, &theCorrectAnswer, &rightorWrong);
updateStats(rightorWrong);
saveStats(outfile);
return rightorWrong;
}
char Gen::Subtract()
{
num1 = 0;
num2 = 0;
theCorrectAnswer = 0;
do
{
srand((unsigned int)time(NULL));
num1 = rand() % 10 + 1;
num2 = rand() % 10;
theCorrectAnswer = num1 - num2;
} while (num1 < num2);
cout << num1 << " - " << num2 << " = ";
getline(cin, theUserResponse);
//validate the userAnswer
validateUserInput(theUserResponse);
rightorWrong = checkTheAnswer(theUserResponse, &theCorrectAnswer, &rightorWrong); //rightorWrong in void Genupdate in main.cpp
updateStats(rightorWrong);
saveStats(outfile);
return rightorWrong;
}
char Gen::Divide()
{
srand((unsigned int)time(NULL));
num1 = rand() % 10;
num2 = rand() % 10 + 1;
theCorrectAnswer = num1;
cout << num1*num2 << " / " << num2 << " = ";
getline(cin, theUserResponse);
//validate the userAnswer
validateUserInput(theUserResponse);
checkTheAnswer(theUserResponse, &theCorrectAnswer,&rightorWrong);
updateStats(rightorWrong);
saveStats(outfile);
return rightorWrong;
}
void Gen::validateUserInput(string &theUserResponse)
{
int userInputLength;
int counter = 0;
userInputLength = theUserResponse.length(); //how many characters in string var userInput
while (userInputLength == 0) //check if they typed nothing, just press enter, first validation
{ /* use while than If since it loops until user gives right answer, user stuck in loop*/
cout << " you did not enter anything" << endl;
cout << "please enter it again" << endl;
getline(cin, theUserResponse); //get another entry if wrong
userInputLength = theUserResponse.length(); //check again and compares with condition, if cond still true, loop again
}
while (counter < userInputLength) /*has to be less than length because max index is length - 1*/
{ // or cond can be (counter <= userInputLength - 1)
if (!(isdigit(theUserResponse[counter]))) //note ! in 1st outer parenthesis
{
cout << "you did not enter a proper digit" << endl;
cout << "please enter it again" << endl;
getline(cin, theUserResponse);
userInputLength = theUserResponse.length();
counter = 0;
while (userInputLength == 0) //check if they typed nothing, just press enter, first validation
{ /* use while than If since it loops until user gives right answer, user stuck in loop*/
cout << " you did not enter anything" << endl;
cout << "please enter it again" << endl;
getline(cin, theUserResponse); //get another entry if wrong
userInputLength = theUserResponse.length(); //check again and compares with condition, if cond still true, loop again
}//end of nested loop
}
else
{
counter = counter + 1; //or counter++;
}
}
}
char Gen::checkTheAnswer(string theUserResponse, int *theCorrectAnswer, char *rightorWrong) //check answer and issue 1 or 0
{
int userAnswer = stoi(theUserResponse);
if (userAnswer == *theCorrectAnswer)
{
*rightorWrong = '1';
}
else
{
*rightorWrong = '0';
}
return *rightorWrong;
}
________________________________________________________
Gen.h
_____________________________
#ifndef Gen_H
#define Gen_H
#include <string>
#include "Stats.h"
#include <cstdlib>
#include <iostream>
using namespace std;
class Gen : public Stats
{
private:
string theUserResponse;
char rightorWrong;
int num1;
int num2;
int theCorrectAnswer;
public:
Gen::Gen();
Gen::Gen(string userName);
char Add();
char Subtract();
char Mult();
char Divide();
char checkTheAnswer(string, int *, char *);
void validateUserInput(string &);
};
#endif
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.