I am implementing a Guessing game where computer generates random number with the following code:
int main()
{
srand(time(NULL));
while (true){
int num = rand() % 10, guess, tries = 0;
while (true){
cout << "Enter number 1 to 10:";
cin >> guess;
if (tries > 2)
{
break;
}
if (guess > num)
{
cout << "Too High ! Try again"<<endl;
}
if (guess > 10)
{
cout << "Error ReEnter 1 to 10\n";
}
else if (guess < num)
{
cout << "Too Low! Try again"<<endl;
}
else
{
break;
}
tries++;
}
if (tries > 2)
{
cout <<"\nYou ran out of tries!\n";
cout << "\nThe answer is:" << num << endl;
}
else
{
cout << "\nCONGRATZ!! You guess correctly!\n";
}
return 0;
}
}
One of the problems is: yet when user attempt 3 times, the program shows "ran out of tries" even though the user input is correct on 3rd try.
Questions:
1.How do I inform user that their input exceeds 10 and show an error message to user to enter values from 1 to 10 ?
2.How to correct the aforementioned problem?
instead of writing the program for you here is some pseudo code.
get a random number rand()%10+1 1..10 call it R
loop
get user input N
if N == R then show OK and break loop
if N < R show too low
else show too high
increment tries
if tries == 3 then break loop
end loop
You have too many if else conditions that make your code unnecessarily complex, to answer your second question specifically the unwanted behaviour is caused from the:
if (tries > 2)
{
break;
}
which exits the loop regardless of the guess, as it is dependant only on the number of tries. Regarding your first question, I decided to provide you with more simple implementation that includes an answer to it as well.
You could replace your while loop with a do-while loop, terminated when the random number is guessed, i.e.:
int main(){
// initialize random seed
srand (time(NULL));
// generate a random number within [1,10]
int secretRandom = rand() % 10 + 1;
// initialize
int yourGuess = 11;
// input loop
string promptMessage = "Type a a number from 1 to 10."
do{
cout << promptMessage << '\n';
// read input
cin >> yourGuess >> endl;
// guessed number relatively to the randomly generated
if (secretRandom < yourGuess) cout << "The secret number is lower\n";
else if (secretRandom > yourGuess) cout << "The secret number is higher\n";
}while(yourGuess != secretRandom)
// if you guess the random number exit the loop and display success message
cout << "You guessed right!\n";
return 0;
}
To reduce the amount of guesses to specific number you can enclose the do-while loop and the success message in a for loop, for example:
int numberOfGuesses = 3;
for (int i = 0; i <= numberOfGuesses; ++i){
//...
}
If you want to enforce the user to input a number in the range from 1 to 10, you could do it by:
int yourGuess = 11;
int lowerBound = 0;
int upperBound = 10;
do{
cin >> yourGuess;
// not type safe
}while(yourGuess < lowerBound || yourGuess > upperBound);
Related
// cai.cpp (Computer Assisted Instruction)
// This program uses random number generation to assist students learn multiplication
#include <iostream>
#include <iomanip>
#include <cstdlib> // contains prototypes for srand and rand
#include <ctime>
#include <cctype>
using namespace std;
int main() {
int question();
string status;
int score{0};
cout << "\nThis program will present you with 10 multiplication problems\n"
<< "enter the correct answer after the prompt\n"
<< "Enter Y for YES and N for NO\n"
<< "Do you want to try a game?";
cin >> status;
while(status == "Y" || status == "y") {
for(int x{0}; x < 11; x++) {
question();
score = score + question();
}
// report total score
cout << "\nTotal score is " << score << " out of 10";
cout << "\nWould you like to play again?";
cin >> status;
if(status == "n" || status == "N") {
break;
}
}
cout << endl;
}
int question() {
string responses();
// use srand to generate the random nmber for the various problems
srand(static_cast<unsigned int> (time(0)));
int number1 = 1 + rand() % 12; // initialize random number
int number2 = 1 + rand() % 12; // initialize random number
int total = number1 * number2;
int response;
int score{0};
cout << "\nWhat is " << number1 << + " times " << + number2 << + " ?";
cin >> response;
while (response != total) { // while answer is wrong, repeat question and wait for response
cout << " \nThat is incorrect, try again: ";
cin >> response;
}
if ( response == total) {
cout << responses();
score++; // increment score after each correct answer
}
return score;
}
string responses() {
string res1 = "Well done, that is correct!\n";
string res2 = "Congratulations, that is very accurate!\n";
string res3 = "Wow!, I'm impressed\n";
string res4 = "You're doing great! Keep up the good work.\n";
srand(static_cast<unsigned int> (time(0)));
int select{1 + rand() % 4};
switch(select) {
case 1: return res1;
break;
case 2: return res2;
break;
case 3: return res3;
break;
case 4: return res4;
break;
default: return " ";
}
}
When I compile and run this program, I expect it to loop only 10 times but it loops more than 10 times, I'm thinking it has to do with the switch statement in the responses function but I do not understand why it should be causing a problem. Any explanation would be greatly appreciated. I have modified the while loop condition in the main function to loop different times but it always loops to display all the possible responses in the switch statement. Screen shot of results attached, I modified the while statement to loop only twice but I still had all my responses showing so it ended up looping 4 times.
expect it to loop only 10 times but it loops more than 10 times
In your loop:
for(int x{0}; x < 11; x++)
x goes from 0 to 10, so it loops 11 times.
A few things to note. Your for loop goes up to < 11, meaning 10. So x from 0 to 10 (inclusive) is actually 11 times. You need to change the condition to < 10, or change x to start at 1.
Second issue, inside the for loop, you are actually calling the question function twice; with the first call's result being ignored. This is why you are getting 4 questions, each answered correctly, but only a score of 2.
Third, not so much an issue, but a bit redundant. At the end of the while loop, you check status == "n" || status == "N", however, this is unnecessary, since the while loop's condition checks for y and Y already.
I've cleaned up your while loop a bit here:
while(status == "Y" || status == "y") {
for(int x = 0; x < 10; ++x) {
score += question();
}
// report total score
cout << "\nTotal score is " << score << " out of 10";
cout << "\nWould you like to play again?";
cin >> status;
}
Unrelated thing to also clean up. You don't need to call srand in the question() function, instead just call it once in main. Also, since this is C++, you can use newer random generators from the <random> header.
Write a program that continues to ask the user to enter any number other than 5 until the user enters the number 5.
Then tell the user "Hey! you weren't supposed to enter 5!" and exit the program.
★ Modify the program so that after 10 iterations if the user still hasn't entered 5 will tell the user "Wow, you're more patient then I am, you win." and exit.
★★ Modify the program so that it asks the user to enter any number other than the number equal to the number of times they've been asked to enter a number. (i.e on the first iteration "Please enter any number other than 0" and on the second iteration "Please enter any number other than 1"m etc. etc. The program must behave accordingly exiting when the user enters the number they were asked not to.)
I got most of the program to work. I have it to a point where it asks for a number starting at 0 and going up, it gives the user the patient message after 10 tries, and exits the program if they enter the number they are not supposed to. However if the user inputs the number above what it tells you not to enter, the program exits with no message.
I do not really know what to search to fix this issue. I have however tried to move some things around, and got rid of some redundant variables.
Any hints would be appreciated, please do not give me the answer up front! Here's what I have so far.
#include <iostream>
int main()
{
const int GUESS = 1; // constant for number of tries
const int PATIENCE = 10; // constant for message at 10 tries
int UserNum; // player input
int InputNum = GUESS; // intializes GuessNumber
// asks for player input
do
{
std::cout << "Enter any number other then "<< InputNum << ": ";
std::cin >> UserNum;
// exits program if user inputs the number displayed
if (UserNum == InputNum)
{
std::cout << "Hey! you weren't supposed to enter " << InputNum << "!\n";
}
// increase the Guess counter if they dont enter the number displayed
else if (UserNum != InputNum)
{
InputNum++;
}
if (InputNum == PATIENCE)
{
std::cout << "Wow, you're more patient then I am, you win.\n";
break;
}
} while (UserNum != InputNum);
return 0;
}
your problem is in do while loop condition
statements are executed first and condition are checked later
for example
InputNum is initialized as 1
so if you enter 2 as input for UserNum , in the else if condition ,InputNum will be incremented to 2
when this condition is evaluated
while (UserNum != InputNum)
it will be false as 2==2
loop breaks
solution
change PATIENCE = 11 and use
while (1)
// this will run infinitely but it will break after 10 iteration or when u press the same number which u shouldn't
instead of
while (UserNum != InputNum)
the full program
#include <iostream>
int main()
{
const int GUESS = 1; // constant for number of tries
const int PATIENCE = 11; // constant for message at 10 tries
int UserNum; // player input
int InputNum = GUESS; // intializes GuessNumber
// asks for player input
do
{
std::cout << "Enter any number other then " << InputNum << ": ";
std::cin >> UserNum;
// exits program if user inputs the number displayed
if (UserNum == InputNum)
{
std::cout << "Hey! you weren't supposed to enter " << InputNum << "!\n";
break;
}
// increase the Guess counter if they dont enter the number displayed
else if (UserNum != InputNum)
{
InputNum++;
}
if (InputNum == PATIENCE)
{
std::cout << "Wow, you're more patient then I am, you win.\n";
break;
}
} while (1);
system("pause");
return 0;
}
Hey try this program it does exactly what you want.
#include <iostream>
int main ()
{
int GUESS = -1; //loop variable
const int PATIENCE = 10; // constant for message at 10 tries
int InputNum; // input from user
std::cout << "PATIENCE Test" << "!\n";
do
{
GUESS++;
// asks for player's input
std::cout << "Enter any number other than " << GUESS << ": ";
std::cin >> InputNum;
// exits program if user inputs the number displayed
if (GUESS == InputNum)
{
std::
cout << "Hey! you weren't supposed to enter " << GUESS << "!\n";
break;
}
if (GUESS == PATIENCE)
{
std::cout << "Wow, you're more patient then I am, you win.\n";
break;
}
}
while (GUESS != InputNum);
return 0;
}
I am creating a simple code to take integer value 10 times. If at any point, the users enters the value '5', the system should print a message, "You entered 5, you lose". Here is the code
int main()
{
int num = 0;
int i;
for (i = 1; i<= 10; i++)
{
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5)
{
cout << "Hey, you entered 5. You lose!\n";
break;
}
}
cout << "You win!";
return 0;
}
Now what I dont know is, how do close the program after users enters 5. I am very new to coding so Im really sorry if this question sound stupid. Also, it would be vet nice of you if you could explain in the most easiest way you can. Thank you
You could do this:
for (i = 1; i<= 10; i++)
{
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5)
{
cout << "Hey, you entered 5. You lose!\n";
return 0; // This will end function main and return 0. Thus your program will end.
}
}
And some more reading.
The way you had it break would simply stop the for loop. This however:
cout << "You win!";
would still get printed. If you use return, no more statements from main will get executed. Because return will end the function in which it is called, in this case, main.
Now what I dont know is, how do close the program after users enters 5.
Replace
break;
with
exit(0);
or
return 0;
break will only exit from the loop, and you're printing cout << "You win!"; unconditionally.
The other two approaches mentioned above are undoubtedly the best. But still, if you have some unfinished business that you want to take care of even after the user enters 5 you can take help of a temporary variable say temp.
int main()
{
int num = 0,tmp=0;
int i;
for (i = 1; i<= 10; i++) {
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5) {
tmp=1;
cout << "Hey, you entered 5. You lose!\n";
break;
}
//unfinished work
}
//unfinished work
if(tmp==0)
cout << "You win!";
return 0;
}
I've created a program that allows the user to enter 10 grades. I've used a while loop to store grades in the array, but if the user only has 5 grades to input, he can type done to exit the program.
After the loop has finished, it will then calculate and display. the highest grade, lowest grade, and the average grade within the array
Unfortunately, when the user types done, the program will display the rest of the grade lines that were not entered.
Can you help me find out how to stop the while loop from displaying the rest of unentered grades of the loop?
#include <iostream>
using namespace std;
int main()
{
const int SIZE = 10;
int grade[SIZE];
int count = 0;
int lowestGrade;
int highestGrade;
bool done = false;
cout << "This program is limited to entering up to 10 grades." << endl;
while ( grade[count] != done && count < SIZE)
{
cout << "Enter a grade #" << count + 1 << " or done to quit: ";
cin >> grade[count];
count++;
}
//LOWEST GRADE
lowestGrade = grade[0];
for (count = 0; count < SIZE; count++)
if (grade[count] < lowestGrade)
{
lowestGrade = grade[count];
}
//HIGHEST GRADE
highestGrade = grade[0];
for (count = 0; count < SIZE; count++)
{
if (grade[count] > highestGrade)
{
highestGrade = grade[count];
}
}
//AVERAGE GRADE
double total = 0;
double average;
for (int count = 0; count < SIZE; count++)
total += grade[count];
average = (total / SIZE);
cout << endl;
cout << "Your highest grade is: " << highestGrade << endl;
cout << "Your lowest grade is: " << lowestGrade << endl;
cout << "Your average grade is: " << average << endl;
system("pause");
return 0;
}
Here are two problems with your code.
First:
....
cout << "Enter a grade #" << count + 1 << " or done to quit: ";
cin >> grade[count];
count++;
....
The code above will attepmpt to read word "done" into integer variable, producing 0. Not what you want to do!
Second:
...
for (count = 0; count < SIZE; count++)
...
Code above will try to iterate over all possible elements (SIZE). However, you might have enetered less than that! You need to use count calculated in the previous loop as your boundary (and of course, use a different name for control variable in the loop).
There are a couple of things to unpack here.
Basically, the input you are retrieving is a char * and the >> operator is casting that to an int to fit into your array of grades.
Next what you are checking with grade[count] != done is if the integer in "grade" at the id "count" is not equal to the bool false. This will always return true in this case.
For your use case what you want to be checking is if your input is equal to the char * "done"
This cannot be happening in the predicate of the while loop because your grade array stores only int.
Therefore the simplest solution to the problem in my opinion, is to check whether the input is equal to "done".
If it is you want to set the done boolean to true
Otherwise we can try to cast it to an int and store that in the grades array.
Here is the revised loop:
while (!done && count < SIZE)
{
cout << "Enter a grade #" << count + 1 << " or done to quit: ";
string input = "";
cin >> input;
if (input == "done")
{
done = true;
}
else
{
grade[count] = stoi(input);
}
count++;
}
The following is somewhat outside the scope of the question, but an additionnal advantage to using stoi() is that it ignores input that is not a number, which will shield against someone entering invalid input like "potato". This is why I immediately cast the input into a string.
Use another variable to store the amount ofgrades the user entered. You also cannot store a string in your integer array:
std::string input = "";
while(count < SIZE)
{
cout << "Enter a grade #" << count + 1 << " or done to quit: ";
getline(cin, input);
if(input == "done")
break;
try
{
grade[count] = std::stoi(input);
count++;
}
catch(std::invalid_argument)
{
cout << "not a valid number\n";
}
}
int actualsize = count;
and then use this variable to abort your for loops:
for (int i = 0; i < actualsize; i++)
There are two simple ways to solve your problem:
You can read strings instead of integers and in case the read string is "done", break the loop, else, convert the read string to an integer, something as follows:
```
// rest of the code
int total_count = 0;
while (count < SIZE) {
cout << "Enter a grade #" << count + 1 << " or done to quit: ";
string temp;
cin >> temp;
if(temp == "done") {
break;
} else {
grade[count] = stoi(temp);
count++;
total_count = count;
}
}
// rest of the code
```
If you don't want to use strings, then, assuming grades will be non-negative, you can stop reading input when the user types a negative number, say "-1". So, you will need to do something as follows:
```
// rest of the code
int total_count = 0;
while (count < SIZE) {
cout << "Enter a grade #" << count + 1 << " or -1 to quit: ";
int temp;
cin >> temp;
if(temp == -1) {
break;
} else {
grade[count] = temp;
count++;
total_count = count;
}
}
// rest of the code
```
Also, don't forget to replace SIZE by total_count in rest of the loops i.e. the ones computing 'LOWEST GRADE', 'HIGHEST GRADE' and 'AVERAGE GRADE'.
NOTE: You will have to do #include <string> at the top as well, if you use the first option.
I have a simple recursive factorial program. The main point of this exercise is to handle exceptions. We've been imposed with the limitations of having no negative numbers and no number larger than 12.
{
int factorial(int);
int number = 0;
string s;
while(number != -1)
{
cout << "Please enter a number 1 - 12 " <<endl;
cout << "or -1 to quit the program: ";
try{
cin >> number;
if (number < 0 || number > 12)
throw number;
else
cout << number << " factorial is: " << factorial(number)<<"\n" << endl;
}catch(int number)
{
cout<< "Your number violates the rules; " <<number<<" is either negative or greater than 12.\n"<<endl;
}
}
}
int factorial(int number) {
int temp;
if(number <=1)
return 1;
temp = number * factorial(number - 1);
return temp;
}
My error handling seems like it's working fine, and it's a new concept to me. However, I'd like to do a better job of handling errors. For example, when I type in anything that's not a number, like say a "p" the program starts an infinite loop. How could I code to check and make sure that it's indeed a number a user is putting in?
Thank you.
Add another condition to test the input. For example you can do this.
...
try{
cin >> number;
if (!cin) {
//error msg here
break;
} else if (number < 0 || number > 12)
...