Math Game

Have to write a program that allows the user has to correctly identify whether each number is a multiple of two, or a multiple of three, or both, or neither.

the specifications include
The user starts with a score of 0 and must earn a score of 10 to win.
The game is played in rounds. Each round:
Print the user's score.
Generate a random number between 1 and 20, inclusive (meaning both 1 and 20 should be possible numbers).
Print the random number.
Ask the user which of the following is correct:
A. The number is a multiple of 2.
B. The number is a multiple of 3.
C. The number is a multiple of both 2 and 3.
D. None of these are true.
If the user gets the answer right, they gain a point.
If the user gets the answer wrong, they lose a point.
There is no penalty for losing points. The user's score can be negative and nothing will happen.
The user wins when they get 10 points.

include comments so i understand each function been behind for two week now trying to catch up and understand what going on
was there a question in there?
was there a question in there?
No, it is an order:
include comments so i understand each function


This is a beginners' forum. Beginners want to learn.
Last edited on
This is a beginners' forum. Beginners want to learn.
I am still a novice, so I tried:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* Have to write a program ... */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <iostream>     /* cout, cin, endl */
using namespace std;

int main()
{
    signed int score(0);
    unsigned   niq, cat;
    char       usrinpt;
    srand (time(NULL));
    cout << "For the numbers in question enter\nA if it's even,\n";
    cout << "B if uneven multiple of 3,\nC if an even multiple of 3,\n";
    cout << "D if A, B, and C don't match.\n";
    cout << "E to quit before winning.\n\n";
	
	do
	{
	    cout << "Your score is: " << score << ", only " << 10 - score << " round(s) left to win.\n";
	    niq = 1 + rand() % 20;
	    cout << ">>> " << niq << " -- ";
	    cin >> usrinpt;
	    cat = 1 - niq % 2;
	    cat += (niq % 3 == 0)? 2 : 0;
	    switch (usrinpt % 16)   // see ASCII table
	    {
	        case 1:
	            score += (cat == 1)? 1 : -1;
	            break;
	        case 2:
	            score += (cat == 2)? 1 : -1;
	            break;
	        case 3:
	            score += (cat == 3)? 1 : -1;
	            break;
	        case 4:
	            score += (cat == 0)? 1 : -1;
	            break;
	        case 5:
	            cout << "Program ends by user request.";
	            goto quit;  // Return (0);
	        default:
	            cout << "Wrong input, again pls.\n";
	    }
	} while (score < 10);
	cout << "You collected 10 points. Hats off!";
quit:;
}

Sample run:
For the numbers in question enter
A if it's even,
B if uneven multiple of 3,
C if an even multiple of 3,
D if A, B, and C don't match.
E to quit before winning.

Your score is: 0, only 10 round(s) left to win.
>>> 2 -- f
Wrong input, again pls.
Your score is: 0, only 10 round(s) left to win.
>>> 1 -- d
Your score is: 1, only 9 round(s) left to win.
>>> 9 -- b
Your score is: 2, only 8 round(s) left to win.
>>> 16 -- a
Your score is: 3, only 7 round(s) left to win.
>>> 8 -- e
Program ends by user request. 
Exit code: 0 (normal program termination)

The match of user input and factors of the number in question could be embellished.

include comments so i understand each function

Your exercise.
I am still malcontent with the error-prone "folding down" of user input and the unestheticly inclined switch gridiron.
Question: What would be the canonical way to leave the do loop from within a switch case?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* Have to write a program ... */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#include <iostream>     /* cout, cin, endl */
using namespace std;

int main()
{
    signed int score(0);
    unsigned   niq;
    char       usrinpt, cat;
    srand (time(NULL));
    cout << "For the numbers in question enter\nA if it's even,\n";
    cout << "B if uneven multiple of 3,\nC if an even multiple of 3,\n";
    cout << "D if A, B, and C don't match, or\nE to quit early.\n\n";
	
	do
	{
	    cout << "Your score is: " << score << ", only " << 10 - score << " round(s) left to win.\n";
	    niq = 1 + rand() % 20;
	    cout << ">>> " << niq << " -- ";
	    cin >> usrinpt;
	    usrinpt = usrinpt % 16;   // see ASCII table
	    cat = 1 - niq % 2;
	    cat += (niq % 3 == 0)? 2 : 0;
	    switch (usrinpt)
	    {
	        case 1:
	        case 2:
	        case 3:
	            score += (cat == usrinpt)? 1 : -1;
	            break;
	        case 4:
	            score += (cat == 0)? 1 : -1;
	            break;
	        case 5:
	            cout << "Repetition interrupted definitely by user request.";
	            return (EXIT_FAILURE);
	        default:
	            cout << "Wrong input, again pls.\n";
	    }
	} while (score < 10);
	cout << "You collected 10 points. Hats off!";
}


Edit: Removed the goto.
Hint: the idea behind "folding down" the user input is to allow for upper case and loser case entry. Even numbers will do, A=1, B=2, ...
Last edited on
why not
while(score < 10 && usrinpt != 5)
why not [...]
O yes, perfect. And make the following "you win" display conditional too.
Why I asked about the canonical way to leave nested loops/constructs, in REXX I have the chance to "baptise" a loop (as substitute the name of the control variable will do) and may define by this designation which loop (and if applicable with it also the inner ones) to leave.
For the moment I replaced the goto by return() with an uncapitalised R.
for nested loops, goto is the cleanest way out and is often used for that.
the second option is a bool that any of the loops can set and check.. but you pay to check the bool every iteration, so for big loops goto is faster.

1
2
3
4
5
6
7
bool stop = false;
while(something && !stop)
  while(other && !stop)
   {
     etc;
     if(epicfail) stop = true;
}

Last edited on
Thank you. Now, in a C++ forum I refrain from praising REXX. (But quietly I do so.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;

char scoreIt( int n )
{
        if ( n % 6 == 0 ) return 'C';
   else if ( n % 2 == 0 ) return 'A';
   else if ( n % 3 == 0 ) return 'B';
   else                   return 'D';
}

int main()
{
   srand( time( 0 ) );
   int userPoints = 0;
   char ans;
   while ( userPoints < 10 )
   {
      int n = 1 + rand() % 20;
      cout << "Number is " << n << '\n';
      cout << "Enter one of A-D as per question: ";   cin >> ans;
      if ( toupper( ans ) == scoreIt( n ) ) userPoints++;
      else                                  userPoints--;
      cout << "Your score is currently " << userPoints << "\n\n";
   }
}

Topic archived. No new replies allowed.