Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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