// Random Math is a program to allow users to choose the range of
// numbers to randomly generate math problems. The problems will be
// displayed and an answer will be accepted. There will be different
// responses depending on if the answer is correct or incorrect. Random
// positive and negative responses should be used.
// Written by Janine Bouyssounouse 01/07
#include <iostream>
#include <stdlib.h>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
void welcome();
float askNumber(string question);
char askChoice(string question, const vector<char>& choices);
bool isLegalChoice(char response, const vector<char>& choices);
bool isLegalHighLow(float high, float low);
bool isLegalHowMany(float numHigh, float numLow, float howMany);
float sum(float num1, float num2);
float difference(float num1, float num2);
float product(float num1, float num2);
float quotient(float num1, float num2);
float average(float num1, float num2);
char askYesNo(string question);
void result(char pick, float num1, float num2);
float random(float high, float low);
void letterGrade(float numCorrect, float howMany);
float percentage(float numCorrect, float howMany);
void displayProblem(float num1, float num2, char pick);
float getAnswer(float num1, float num2, char pick, const vector<string>& positives, const vector<string>& negatives);
void displayPositive(const vector<string>& positives);
void displayNegative(const vector<string>& negatives);
int main()
{
float high = 0;
float low = 0;
float howMany = 0;
float numLow = 1;
float numHigh = 10;
float numCorrect = 0;
char pick;
char negative;
vector<char> choices;
choices.push_back('a');
choices.push_back('s');
choices.push_back('m');
vector<string> positives;
positives.push_back("Great!");
positives.push_back("Good job!");
positives.push_back("You are on the right track.");
positives.push_back("Look how well you are doing.");
positives.push_back("Fantastic!");
positives.push_back("Wonderful!");
positives.push_back("Feel good about a job well done.");
vector<string> negatives;
negatives.push_back("Keep trying.");
negatives.push_back("Next time is the time you will get it. If not, keep trying.");
negatives.push_back("Practice improves your chances of getting it right.");
negatives.push_back("Improvement comes step by step.");
negatives.push_back("The harder you try, the better you will get.");
negatives.push_back("Giving up makes it harder to learn. Keep going.");
negatives.push_back("I think I can. I think I can. I KNOW I can!");
negatives.push_back("Failure is just another opportunity to try again.");
welcome();
cout << endl << endl;
do
{
cout << endl;
low = askNumber("What is the lowest number you would like to use?");
high = askNumber("What is the highest number you would like to use?");
while (!(isLegalHighLow(high, low)))
{
cout << "\nPlease remember the high number must be greater than the low number.\n\n";
low = askNumber("What is the lowest number you would like to use?");
high = askNumber("What is the highest number you would like to use?");
} // end while
// ask for which option the user wants
pick = askChoice("Would you like to add, subtract or multiply?", choices);
if (pick == 's')
{
negative = askYesNo("\nDo you want negative numbers?");
cout << endl;
}
// ask for how many problems in the set
howMany = askNumber("How many problems would you like for this round?");
while (!(isLegalHowMany(numHigh, numLow, howMany)))
{
cout << "\nPlease choose a number from " << numLow << " to " << numHigh << ".\n\n";
howMany = askNumber("How many problems would you like for this round?");
} // end while
srand(time(0));
for (int i = 1; i <= howMany; ++i)
{
// get two numbers in range
float num1 = random(high, low);
float num2 = random(high, low);
// check for subtraction
if (negative == 'n')
{
// check for possible negative answers in subtraction problems
if (num1 < num2)
{
// if negative answer, then switch numbers
float temp = num1;
num1 = num2;
num2 = temp;
}
}
// display problem with two numbers and operand
displayProblem(num1, num2, pick);
cout << endl;
// get answer
// decide if answer is correct
// if correct on first try, increment numCorrect
numCorrect = numCorrect + getAnswer(num1, num2, pick, positives, negatives);
}; // end for loop
// display results of problem set
cout << "\nYou got " << numCorrect << " out of " << howMany << " correct.\n\n";
cout << "Your percentage correct is " << percentage(numCorrect, howMany);
cout << "%.\n\n";
} while (askYesNo("\nWould you like another round?") == 'y');
// (problemSet function - high, low, opperator, howMany)
// take high, low, opperator and how many to make the random problems
// have (display function - num1, num2, opperator) show the problems
// check to see if the answer is correct (isCorrect function - opperator, num1, num2)
// (feedback function - correct y/n) give random positive/negative feedback as needed
// give three chances for user to get the problem correct
// after three chances, tell the user the correct answer and move on
// keep track of how many problems are done correctly the FIRST time
// (results function - numCorrect, howMany)give overall results of how many problems done correctly
// give percentage of correct in seperate (percentage function - numCorrrect, howMany)
// (letterGrade function - numCorrect, howMany) give OPTIONAL feedback on percentage matching to letter grades
system("PAUSE");
return 0;
} // end main
// Functions:
//------------------------------------------------------------------------------
void welcome() // intro text only displayed at start of program
{
cout << "\tWelcome to Random Math.\n\n";
cout << "You will be asked for a low and high number. These numbers\n";
cout << "will allow you to choose the range of numbers used in the \n";
cout << "random math problems. You will also be asked to choose which\n";
cout << "type of math problems you would like to do. The problems\n";
cout << "will use only numbers in the range you selected.\n";
} // end welcome function
// ---------------------------------------------------
char askYesNo(string question) // allows open question for y/n answers
{
char response;
do
{
cout << question << " (y/n): "; // writes question and y/n prompt
cin >> response;
} while (response != 'y' && response != 'n'); // keep going until y or n is entered
return response;
} // end askYesNo function
// ---------------------------------------------------
float askNumber(string question) // allows open question for numbers
{
// floats can be entered, so positive, negative, and decimal
// numbers are allowed
float number;
cout << question << " ";
cin >> number;
cout << endl;
return number;
} // end askNumber function
// ---------------------------------------------------
char askChoice(string question, const vector<char>& choices)
{
char response;
vector<char>::const_iterator iter; // this will point to the items in a vector
do
{
cout << question;
cout << "\nYour choices are: ";
// this is using the constant iterator to walk through the vecor
for (iter = choices.begin(); iter != choices.end(); ++iter)
cout << *iter << " "; // this refers to the item in the vector
cout << endl;
cin >> response;
} while (!isLegalChoice(response, choices)); // keep going until it is a valid choice
return response;
} // end askChoice function
//-----------------------------------------------------
bool isLegalChoice(char response, const vector<char>& choices)
{
// is the choice one of the menu options?
for (int i = 0; i < choices.size(); ++i) // walk through the menu items
{
if (choices[i] == response)
return true; // yes, it is part of the menu
}
return false; // not part of the menu
} // end isLegalChoice function
//-----------------------------------------------------
bool isLegalHighLow(float high, float low)
{
return (high > low);
} // end isLegalHighLow function
//-----------------------------------------------------
bool isLegalHowMany(float numHigh, float numLow, float howMany)
{
return (howMany >= numLow && howMany <= numHigh);
} // end isLegalHowMany function
//-----------------------------------------------------
float sum(float num1, float num2) // add
{
return (num1 + num2);
} // end sum function
//-----------------------------------------------------
float difference(float num1, float num2) // subtract
{
return (num1 - num2);
} // end difference function
//-----------------------------------------------------
float product(float num1, float num2) // multiply
{
return (num1 * num2);
} // end product function
//-----------------------------------------------------
float quotient(float num1, float num2) // divide
{
if (num2 != 0) // check for dividing by zero
return (num1 / num2);
else
{
cout << "\nIt is illegal to divide by zero.\n";
return 0;
}
} // end quotient function
//-----------------------------------------------------
float average(float num1, float num2) // computes average of two numbers
{
return ((num1 + num2) / 2);
} // end average function
//-----------------------------------------------------
void result(char pick, float num1, float num2)
{
cout << "Your answer is:\n";
// give a different result for each menu item
switch (pick)
{
case 'a':
cout << num1 << " + " << num2 << " = " << sum(num1, num2);
break;
case 's':
cout << num1 << " - " << num2 << " = " << difference(num1, num2);
break;
case 'm':
cout << num1 << " * " << num2 << " = " << product(num1, num2);
break;
case 'd':
if (num2 != 0)
cout << num1 << " / " << num2 << " = " << quotient(num1, num2);
break;
case 'v':
cout << "The average of " << num1 << " and " << num2 << " is ";
cout << average(num1, num2);
break;
default:
cout << "You made an illegal choice.\n"; // just here for syntax, it should never run
} // end switch
} // end result function
//--------------------------------------------------------------------
float random(float high, float low) // chooses numbers to be used in problems
{
vector<float>::const_iterator iter;
// fill vector with possible number choices
vector<float> numbers;
for (int i = static_cast<int>(low); i <= static_cast<int>(high); ++i)
{
numbers.push_back(i);
} // end for (filling vector with choices)
random_shuffle(numbers.begin(), numbers.end());
iter = numbers.begin();
return *iter;
} // end random function
//--------------------------------------------------------------------
void letterGrade(float numCorrect, float howMany) // assigns letter grade to percentage score
{
if ((numCorrect/howMany) >= .9)
{
cout << percentage(numCorrect, howMany);
cout << " Gives you an A.";
}
else if ((numCorrect/howMany) >= .8)
{
cout << percentage(numCorrect, howMany);
cout << " Gives you a B.";
}
else if ((numCorrect/howMany) >= .7)
{
cout << percentage(numCorrect, howMany);
cout << " Gives you a C.";
}
else if ((numCorrect/howMany) >= .6)
{
cout << percentage(numCorrect, howMany);
cout << " Gives you a D.";
}
else
{
cout << percentage(numCorrect, howMany);
cout << " Gives you an F.";
}
} // end letterGrade function
//--------------------------------------------------------------------
float percentage(float numCorrect, float howMany)
{
return ((numCorrect/howMany) * 100);
} // end percentage function
//--------------------------------------------------------------------
void displayProblem(float num1, float num2, char pick) // show problem
{
// give a different result for each menu item
switch (pick)
{
case 'a':
cout << num1 << " + " << num2 << " = ";
break;
case 's':
cout << num1 << " - " << num2 << " = ";
break;
case 'm':
cout << num1 << " x " << num2 << " = ";
break;
case 'd':
if (num2 != 0)
cout << num1 << " / " << num2 << " = ";
break;
case 'v':
cout << "The average of " << num1 << " and " << num2 << " is ";
break;
default:
// just here for syntax, it should never run
cout << "This operator is not supported.\n";
} // end switch
} // end displayProblem function
//--------------------------------------------------------------------
float getAnswer(float num1, float num2, char pick, const vector<string>& positives, const vector<string>& negatives)
{
float answer;
cout << "\nEnter your answer: ";
cin >> answer;
// give a different result for each menu item
switch (pick)
{
case 'a':
if (answer == sum(num1, num2))
{
cout << "Yeah!";
// displayPositive(positives); // random positive comment
cout << endl;
return 1;
}
else
{
cout << "Oops...";
// displayNegative(negatives); // random negative comment
cout << endl;
cout << num1 << " + " << num2 << " = " << sum(num1, num2);
cout << endl << endl;
return 0;
};
break;
case 's':
if (answer == difference(num1, num2))
{
cout << "Yeah!";
// displayPositive(positives);
cout << endl;
return 1;
}
else
{
cout << "Oops...";
// displayNegative(negatives);
cout << endl;
cout << num1 << " - " << num2 << " = " << difference(num1, num2);
cout << endl << endl;
return 0;
};
break;
case 'm':
if (answer == product(num1, num2))
{
cout << "Yeah!";
// displayPositive(positives);
cout << endl;
return 1;
}
else
{
cout << "Oops!";
// displayNegative(negatives);
cout << endl;
cout << num1 << " x " << num2 << " = " << product(num1, num2);
cout << endl << endl;
return 0;
};
break;
case 'd':
if (num2 != 0)
cout << num1 << " / " << num2 << " = ";
break;
case 'v':
cout << "The average of " << num1 << " and " << num2 << " is ";
break;
default:
// just here for syntax, it should never run
cout << "This operator is not supported.\n";
} // end switch
} // end getAnswer function
//--------------------------------------------------------------------
void displayPositive(const vector<string>& positives) // displays random positives
{
int randNumber = rand();
int number = (randNumber % positives.size()) + 1;
cout << positives[number] << endl;
} // end displayPositive function
//-------------------------------------------------------------------
void displayNegative(const vector<string>& negatives) // displays random negatives
{
int randNumber = rand();
int number = (randNumber % negatives.size()) + 1;
cout << negatives[number] << endl;
} // end displayNegative function
//-------------------------------------------------------------------