/*
File name: hw5.cpp
Author: Bo Bayles
E-mail address: bmb3h6@umr.edu  
Description: This program generates random numbers to quiz the user,
  and tallies score.
*/

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
//Include iostream for cin and cout, cstdlib for rand and srand,
//  and ctime to seed the randomizer.

char displayMenu();
int randomInt(int iMin, int iMax);
int plusOrMinus();
void generateOperands(char cLevel, int &iOp1, int &iOp2);
int displayProblem(int iOp1, int iOp2);
bool isCorrect(int iOp1, int iOp2, int iUserAnswer);
void displayMessage(bool bCorrect);
void displayFinalResults(int iNumberRight, int iNumberWrong);
char cGoAgain();
//Function declarations from the assignment.

int main()
{
  bool bCorrect;
  char cLevel, cRepeat = 'y';
  int iOp1 = 0, iOp2 = 0, iNumberWrong = 0, iNumberRight = 0;
  int iUserAnswer;
  //Declare variables for correctness, user choice, operands, numbers
  //  right and wrong, and user answer.
  
  srand(time(NULL));
  //Seed the randomizer here, outside the loop, since it should only
  //  be done once.
  
  while ((cRepeat != 'n') && (cRepeat != 'N'))
  {
  iNumberRight = 0;
  //Repeat as long as the user doesn't say not to, and reset the counter.
  
  cLevel = displayMenu();
  //Call the function to display the menu.
  
    for (int iCounter = 0; iCounter < 10; iCounter++)
    {
    //Ask a set of 10 questions.
    
      generateOperands(cLevel, iOp1, iOp2);
      //Call the function to generate the operands, passing the user's
      //  difficulty choice, and two operands to be manipulated.

      iNumberWrong = 0;
      while (iNumberWrong < 2)
      //Repeat until the user gets a wrong answer twice.
      {
        cout << endl << (iCounter + 1) << ") ";
        //Display problem number.

        iUserAnswer = displayProblem(iOp1, iOp2);
        //Call the function that displays the problem to get the user
        //  answer, passing it the operands.
        
        bCorrect = isCorrect(iOp1, iOp2, iUserAnswer);
        //Call the function to see if the user answer was right,
        //  passing it the operands and user answer.

        if (bCorrect == false)
        {
          iNumberWrong++;
          displayMessage(bCorrect);
          //If they were wrong, keep track, and call the function
          //  to tell if they were correct, pasing it true or false.
        }
        else
        {
          iNumberRight++;
          displayMessage(bCorrect);
          break;
          //If they were right, break out of the loop that gives
          // the user a second chance.
        }
      }
      //End of the while loop.
  }
  //End of the for loop.
  
  iNumberWrong = (10 - iNumberRight);
  //The number wrong is the total minus the number right.
  
  displayFinalResults(iNumberRight, iNumberWrong);
  //Call the function to display the final results, passing it the
  //  number right and number wrong.

  
  cRepeat = cGoAgain();
  }
  //End of the big while loop.
  
  return 0;
}

char displayMenu()
{
  char cLevel;
  
  cout << endl << "DIFFICULTY LEVEL" << endl
       << "1. Easy" << endl
       << "2. Moderate" << endl
       << "3. Advanced" << endl
       << "Enter 1 - 3 for your difficulty level: ";
  cin >> cLevel;
  
  return cLevel;
}
//This function displays the menu for difficulty and gets the user's
// choice. Then it returns the choice variable.

int randomInt(int iMin, int iMax)
{
  int iRandomInt = iMin + (rand() % iMax);
  
  return iRandomInt;
}
//This function generates a random integer, based on its to parameters.
//  It generates a random integer, which is modulus-ed with the max
//  parameter, then added to the minimum parameter to get a value
//  in between min and max. Then it returns the random integer.

int plusOrMinus()
{
  int iMultiplier;
  
  iMultiplier = randomInt(1,2);
  
  if (iMultiplier == 2)
    iMultiplier = -1;
  else
    iMultiplier = 1;
    
  return iMultiplier;
}
//This function determines whether it will be an addition or subtraction
//  problem. It gets the randomInt function to generate a number, then
//  sees if it's 1 or 2. If it's 2, it will be a subtraction problem,
//  so it will return a -1 by which the second operand will be multiplied.

void generateOperands(char cLevel, int &iOp1, int &iOp2)
{
  switch (cLevel)
  {
    case '1':
            iOp1 = randomInt(1, 9);
            iOp2 = randomInt(1, 9);
            
            break;
    case '2':
            iOp1 = randomInt(10, 90);
            iOp2 = randomInt(10, 90);
            
            break;
    case '3':
            iOp1 = randomInt(1000, 9000);
            iOp2 = randomInt(1000, 9000);
            
            break;
  }
  
  iOp2 = iOp2 * plusOrMinus();

  return;
}
//This function uses a switch to do something based on the difficulty
//  level. If the user entered 1, it calls the randomInt function to
//  get a random integer between 1 and 9. Level 2 is between 10 and
//  100, and so on. Lastly, it calls the plusOrMinus function to
//  see if the second operand should be multiplied by -1 to make it
//  negative. 

int displayProblem(int iOp1, int iOp2)
{
  char cOperator = ' ';
  int iUserAnswer;
  
  if (iOp2 > 0)
    cOperator = '+';
  
  cout << "Your problem is " << iOp1 << cOperator << iOp2 << endl
       << "Enter your answer: ";
  cin >> iUserAnswer;
  
  return (iUserAnswer); 
}
//This function gets the operands as parameters. It sees if the second
//  one is negative (making it a subtraction problem). If it's not, it
//  displays the problem with a plus sign between the operands. Then
//  it gets the user's answer, and returns it.

bool isCorrect(int iOp1, int iOp2, int iUserAnswer)
{
  bool bCorrect;
  
  if ((iOp1 + iOp2) == iUserAnswer)
    bCorrect = true;
  else
    bCorrect = false;
  
  return bCorrect;
}
//This function takes the operands and determines the right answer,
//  and compares it with the user's answer. It returns whether or
//  not they were equal.

void displayMessage(bool bCorrect)
{
  int iMessage;
  
  iMessage = randomInt(1,4);
  //Generate a random number for the message display.
  
  if (bCorrect == true)
  {
    switch (iMessage)
    {
      case 1:
            cout << endl << "That's right!" << endl;
            break;
      case 2:
            cout << endl << "Correct!" << endl;
            break;
      case 3:
            cout << endl << "Eso esta correcto!" << endl;
            break;
      case 4:
            cout << endl << "You got it right!" << endl;
            break;
    }
  }
  //Use the switch to decide which message to display.
  else if (bCorrect == false)
  {
    switch (iMessage)
    {
      case 1:
            cout << endl << "That's not right." << endl;
            break;
      case 2:
            cout << endl << "That's wrong." << endl;
            break;
      case 3:
            cout << endl << "You got it wrong." << endl;
            break;
      case 4:
            cout << endl << "Incorrect!" << endl;
            break;
    }
  }
    
  return;
}
//This function takes the correctness and displays whether or not
//  the user was right. It calls randomInt to get a random number
//  between 1 and 4 and displays a different message depending on what
//  the result was. It doesn't return anything.

void displayFinalResults(int iNumberRight, int iNumberWrong)
{
  cout << "You got " << iNumberRight << " correct out of 10." << endl
       << "You got " << iNumberWrong << " wrong out of 10." << endl
       << "That's " << ((iNumberRight / 10.0) * 100) << "%"<< endl;

  return;
}
//This function takes the numbers for right and wrong as parameters,
//  and displays how many the user got right. It returns nothing.

char cGoAgain()
{
  char cRepeat;
  
  cout << endl << "Do you want to play again?" << endl
       << "(Y or N): ";
  cin >> cRepeat;
  
  return cRepeat;
}
//This function asks the user if they want to play again, and returns
//  the answer.

