Guest User

Untitled

a guest
Feb 21st, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.94 KB | None | 0 0
  1. // Math Tutor.cpp : Defines the entry point for the console application.
  2. // Author: Ben Henning
  3. // Date: 10/18/2011
  4. // Updated: 10/27/2011
  5. //
  6. // No output provided because the program flow is too complex for standard output.
  7. // This satisfies criteria beyond chapters 3, 4 and 5 in which this problem is assigned.
  8. //
  9. // Ugh, probably contains memory leaks as well
  10.  
  11. #include <iostream>
  12. #include <iomanip>
  13. #include <cstdlib>
  14. #include <ctime>
  15. #include <conio.h>
  16. #include <cmath>
  17. #include <cctype>
  18.  
  19. using namespace std;
  20.  
  21. #define MODE_FLOAT false
  22. #define MODE_INT true
  23.  
  24. int difficulty = 1; // DEFAULT
  25.  
  26. int difficultyDigits[] = { 1, 1, 2, 3, 3 };
  27. bool difficultyModes[] = { MODE_INT, MODE_FLOAT, MODE_INT, MODE_INT, MODE_FLOAT };
  28.  
  29. int numDigits = difficultyDigits[difficulty - 1];
  30. bool mode = difficultyModes[difficulty - 1];
  31.  
  32. inline float fround(float val) {
  33.     float expansion = pow(10.f, numDigits);
  34.     float ipart = (float)(int)floorf(val);
  35.     // force the float to x number of decimal points
  36.     float fpart = (float)(int)floorf((val - ipart) * expansion);
  37.     // put it back together
  38.     return ipart + (fpart / expansion);
  39. }
  40.  
  41. struct OP {
  42.     bool typeInt;
  43.     OP() { this->typeInt = MODE_INT; };
  44.     union {
  45.         int ival;
  46.         float fval;
  47.     } val;
  48.     OP operator =(OP);
  49.     OP operator +(OP);
  50.     OP operator -(OP);
  51.     OP operator /(OP);
  52.     OP operator *(OP);
  53.     bool operator ==(OP);
  54. };
  55.  
  56. OP OP::operator=(OP op) {
  57.     if (typeInt)
  58.         this->val.ival = op.val.ival;
  59.     else
  60.         this->val.fval = op.val.fval;
  61.     return *this;
  62. }
  63.  
  64. OP OP::operator+(OP op) {
  65.     if (typeInt)
  66.         this->val.ival += op.val.ival;
  67.     else
  68.         this->val.fval = fround(this->val.fval + op.val.fval);
  69.     return *this;
  70. }
  71.  
  72. OP OP::operator-(OP op) {
  73.     if (typeInt)
  74.         this->val.ival -= op.val.ival;
  75.     else
  76.         this->val.fval = fround(this->val.fval - op.val.fval);
  77.     return *this;
  78. }
  79.  
  80. OP OP::operator*(OP op) {
  81.     if (typeInt)
  82.         this->val.ival *= op.val.ival;
  83.     else
  84.         this->val.fval = fround(this->val.fval * op.val.fval);
  85.     return *this;
  86. }
  87.  
  88. OP OP::operator/(OP op) {
  89.     if (typeInt)
  90.         this->val.ival /= op.val.ival;
  91.     else
  92.         this->val.fval = fround(this->val.fval / op.val.fval);
  93.     return *this;
  94. }
  95.  
  96. bool OP::operator==(OP op) {
  97.     if (typeInt)
  98.         return this->val.ival == op.val.ival;
  99.     else {
  100.         float expansion = pow(10.f, numDigits);
  101.         return (int)(this->val.fval * expansion) == (int)(op.val.fval * expansion);
  102.     }
  103. }
  104.  
  105. void init();
  106. bool handleMenu();
  107. template<typename T> void printResults(bool, int, bool (*func)(T, T, bool, OP *));
  108. void printOperation(OP, OP, char);
  109.  
  110. bool handleAddition(OP, OP, bool, OP *);
  111. bool handleSubtraction(OP, OP, bool, OP *);
  112. bool handleMultiplication(OP, OP, bool, OP *);
  113. bool handleDivision(OP, OP, bool, OP *);
  114.  
  115. // use function pointers for pratice
  116. bool (*add)(OP, OP, bool, OP *);
  117. bool (*sub)(OP, OP, bool, OP *);
  118. bool (*mul)(OP, OP, bool, OP *);
  119. bool (*divi)(OP, OP, bool, OP *); // 'div' is ambiguous for some reason...
  120.  
  121. int main() {
  122.     printf("Welcome to Math Tutor!\n");
  123.     // initialize...
  124.     init();
  125.     while (true)
  126.         if (!handleMenu())
  127.             break;
  128.     printf("Thank you for using Math Tutor!\n");
  129.     return 0;
  130. }
  131.  
  132. void init() {
  133.     add = handleAddition;
  134.     sub = handleSubtraction;
  135.     mul = handleMultiplication;
  136.     divi = handleDivision;
  137.     srand((unsigned int) time(0));
  138. }
  139.  
  140. bool handleMenu() {
  141.     printf("\nPlease enter an option (h for help): ");
  142.     cin.clear();
  143.     int val = tolower(cin.get());
  144.     // XXX: figure out how to get rid of newline by a cleaner means...
  145.     if (val == '\n')
  146.         val = tolower(cin.get());
  147.     switch (val) {
  148.     case '+': case 'a': // addition
  149.         printResults(mode, numDigits, add);
  150.         //cout << endl;
  151.         break;
  152.     case '-': case 's': // subtraction
  153.         printResults(mode, numDigits, sub);
  154.         //cout << endl;
  155.         break;
  156.     case '*': case 'm': // multiplication
  157.         printResults(mode, numDigits, mul);
  158.         //cout << endl;
  159.         break;
  160.     case '/': case 'd': // division
  161.         printResults(mode, numDigits, divi);
  162.         //cout << endl;
  163.         break;
  164.     case 'x': // settings
  165.         {
  166.         printf("Current difficulty level: %i\n     (number digits/decimals: %i, number mode: %s)\n", difficulty,
  167.             numDigits, mode ? "integers only" : "floating point digits");
  168.         printf("Would you like you change the difficulty mode? (y/n): ");
  169.         cin.clear();
  170.         int val = tolower(cin.get());
  171.         if (val == '\n')
  172.             val = tolower(cin.get());
  173.         if (val == 'y') {
  174.             cin.clear();
  175.             printf("New difficulty mode: ");
  176.             int diff;
  177.             cin >> diff;
  178.             if (diff < 1 || diff > 5)
  179.                 printf("Error: The difficulty mode must be between 1 and 5.\n");
  180.             else {
  181.                 difficulty = diff;
  182.                 numDigits = difficultyDigits[diff - 1];
  183.                 mode = difficultyModes[diff - 1];
  184.                 printf("New difficulty level: %i\n     (number of digits/decimals: %i, number mode: %s)\n", diff,
  185.                     numDigits, mode ? "integers only" : "floating point digits");
  186.             }
  187.         }
  188.         }
  189.         break;
  190.     case 'h': // help
  191.         printf("Menu options:\n");
  192.         printf("   a OR +   Run the addition tutor\n");
  193.         printf("   s OR -   Run the subtraction tutor\n");
  194.         printf("   m OR *   Run the multiplication tutor\n");
  195.         printf("   d OR /   Run the division tutor\n");
  196.         printf("   x        Change the difficulty for the tutor\n");
  197.         printf("   h        Print this help menu\n");
  198.         printf("   e        Exit the application\n");
  199.         break;
  200.     case 'e': // exit
  201.         return false;
  202.     default:
  203.         printf("Unknown menu option: %c.\n", val);
  204.     }
  205.     return true;
  206. }
  207.  
  208. bool handleAddition(OP first, OP second, bool typeInt, OP * result) {
  209.     printOperation(first, second, '+');
  210.     *result = first + second;
  211.     OP * input = new OP;
  212.     if (typeInt) {
  213.         int i;
  214.         cin >> i;
  215.         (*input).val.ival = i;
  216.     } else {
  217.         float f;
  218.         cin >> f;
  219.         (*input).val.fval = fround(f);
  220.     }
  221.     cin.clear();
  222.     return *input == *result;
  223. }
  224.  
  225. bool handleSubtraction(OP first, OP second, bool typeInt, OP * result) {
  226.     printOperation(first, second, '-');
  227.     *result = first - second;
  228.     OP * input = new OP;
  229.     if (typeInt) {
  230.         int i;
  231.         cin >> i;
  232.         (*input).val.ival = i;
  233.     } else {
  234.         float f;
  235.         cin >> f;
  236.         (*input).val.fval = fround(f);
  237.     }
  238.     cin.clear();
  239.     return *input == *result;
  240. }
  241.  
  242. bool handleMultiplication(OP first, OP second, bool typeInt, OP * result) {
  243.     printOperation(first, second, '*');
  244.     *result = first * second;
  245.     OP * input = new OP;
  246.     if (typeInt) {
  247.         int i;
  248.         cin >> i;
  249.         (*input).val.ival = i;
  250.     } else {
  251.         float f;
  252.         cin >> f;
  253.         (*input).val.fval = fround(f);
  254.     }
  255.     cin.clear();
  256.     return *input == *result;
  257. }
  258.  
  259. bool handleDivision(OP first, OP second, bool typeInt, OP * result) {
  260.     printOperation(first, second, '/');
  261.     *result = first / second;
  262.     OP * input = new OP;
  263.     if (typeInt) {
  264.         int i;
  265.         cin >> i;
  266.         (*input).val.ival = i;
  267.     } else {
  268.         float f;
  269.         cin >> f;
  270.         (*input).val.fval = fround(f);
  271.     }
  272.     cin.clear();
  273.     return *input == *result;
  274. }
  275.  
  276. inline float frand() {
  277.     return (float) (((double) rand()) / ((double) RAND_MAX));
  278. }
  279.  
  280. inline int powi(int a, int b) {
  281.     return (int) pow((float) a, (float) b);
  282. }
  283.  
  284. template<typename T> void printResults(bool typeInt, int numDigits, bool (*func)(T, T, bool, OP *)) {
  285.     OP * first = new OP;
  286.     OP * second = new OP;
  287.     OP * result = new OP;
  288.     (*first).typeInt = (*second).typeInt = (*result).typeInt = typeInt;
  289.     if (typeInt) {
  290.         int expansion = powi(10, numDigits);
  291.         (*first).val.ival = rand() % expansion;
  292.         (*second).val.ival = rand() % expansion;
  293.     } else {
  294.         float expansion = pow((float) 10, (float) numDigits);
  295.         (*first).val.fval = fround(frand() * expansion);
  296.         (*second).val.fval = fround(frand() * expansion);
  297.     }
  298.     if (func(*first, *second, typeInt, result))
  299.         printf("Congratulations! You gave the correct value. =)\n");
  300.     else if (typeInt)
  301.         cout << "Sorry, but the correct answer is " << (*result).val.ival << endl;
  302.     else
  303.         cout << "Sorry, but the correct answer is " << (*result).val.fval << endl;
  304. }
  305.  
  306. void printOperation(OP a, OP b, char oper) {
  307.     if (a.typeInt) {
  308.         cout << ' ' << a.val.ival << endl;
  309.         cout << oper << b.val.ival << endl;
  310.     } else {
  311.         cout << ' ' << a.val.fval << endl;
  312.         cout << oper << b.val.fval << endl;
  313.     }
  314.     cout << "-----" << endl;
  315. }
Add Comment
Please, Sign In to add comment