So I am determined to make an epic math console based game for fun.
I am curious as to why when the random enters a zero, the program slides through a series of multiplied by 0 and skips the "please enter: " portion of my code.. Is this because of the true and false boolean features of the test condition in the while loop? More importantly how can I stop this from happening?
Thank you for all of your help!
// multiplicationgame.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
void game();
int _tmain(int argc, _TCHAR* argv[])
{
// waiting.cpp : Defines the entry point for the console application.
//
cout << "Welcome to Math game!\n\n" << endl;
float secs;
secs = 3;
clock_t delay = secs * CLOCKS_PER_SEC;
clock_t start = clock();
while (clock() - start < delay )
;
char choice = 'z';
game();
while(choice != 'n')
{
cin >> choice;
if (choice == 'y')
{
cout << "\n\n";
game();
}
else
choice = 'n';
}
return 0;
}
void game()
{
float secs;
secs = 33;
clock_t delay = secs * CLOCKS_PER_SEC;
clock_t start = clock();
int correct = 0;
while (clock() - start < delay )
{
srand(time(NULL));
int a = rand() % 23;
int b = rand() % 23;
int c = (a * b);
int d = 0;
char choice = 0;
cout <<"What does " << a << " * " << b << " equal?" << endl << endl << endl;
cout << "\n";
while(d != c)
{
cout << "Please enter a number: ";
cin >> d;
if(d == c)
++correct;
}
cout << "\n\nCorrect! " << (a * b) << " is the answer!" << endl << endl;
}
cout << "Your score is: " << correct << "\n\n" <<endl;
cout << "Would you like to play again (Y) or (N)?\n\n\n";
}
You assume the answer is wrong if c is not equal to d, but if a or b are set to zero , c and d are equal before your user can ever enter a number. One solution would be to use a do { ... } while ( ... ); loop instead of a while loop to ensure the user is always asked for a number before your test for the correct answer is performed.
As Markku said, don't set d = 0, because if either a or b is equal 0, then c = a * b = 0 and then your while loop condition c != d won't hold and so it will be skipped
You initialize d to be 0, and anything times 0 is 0. Thus the (d != c) condition will always be false, and you don't enter the while(d!=c) loop.
You are getting 0 several times, because the while loop finishes very quickly, and so when you call srand(time(NULL)), time(NULL) will return the same value as the previous itteration, and you get the same random seed (which gets you 0 again).
initialize d to be -1 (or some other value that a*b can't be). Move the srand outside of your while loop -- you only have to (and only should) call srand once in your program.
John
Quick fix: initialize int d = -1; instead of int d = 0;.
You're initializing int c = a * b. Since either a or b is zero, the multiplication results in c being zero. You also initialize int d = 0;. Then you have while(d != c), but you assigned both of them to zero, hence your program skips over that loop because d != c is false.
#AEGIS No, the srand(time(NULL)) merely seeds the random number generator with a somewhat random value based on the current time whenever the program is run. This ensures that each run of the program will produce a different set of multiplication problems to solve.
#AEGIS The outer while (clock() - start < delay ) { ... } loop terminates when the "delay" time has expired. The inner while(d != c) { ... } loop is never entered at all when a or b are zero, or loops forever as long as the user enters wrong answers. So though it is not a real problem in practice -- any user is likely to finally get the correct answer or abort the program manually -- this is a program which is not certain to ever terminate.
#Ned Nowonty looking at the screen shot AEGIS provided the outer loop didn't terminate. If it did then the
Your score is: (some number)
Would you like to play again (Y) or (N)?
would have appeared. When you srand with the same initializer you end up with the same pseudo random numbers. So when one of the variables was initialized to 0 it would loop around until time(NULL) provided srand a different variable. In order to avoid that you could use an iterator as well as the time function so the seed would be different all the time.
Related
I made a program that prompts the user to guess numbers (which I have programmed to produce a random number)ranging from 1-10, if the user guesses the number successfully which is the same as the random number generated it prints "congratulation", else it prompts the user to try again. but I want to stop the user from answering after a certain amount of time(like Game Over). But the prompt keeps coming, I tried using the break in my while loop but it doesn't work, I also tried using the exit function, which actually stopped the program from running but it stopped it after answering 2 times which is not what I want.
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
int a,b,c,d,e,f;
// generate a random number, prompt the user for any number if the users guess is in line with the random number generated the user wins else try again
//generate a random number between 1 - 10 store it in a variable
cout << "Random Number Generator \n \n";
srand(time(0));
for(int i = 1; i == 1; i++){
a = 1+(rand() % 10);
cout << a << endl;
}
//prompt the user for numbers ranging from 1 - 10
cout << "type in a number from (1 - 10)\n";
cin >> b;
c++;
//check if the number is the same as the random number
//this checks to see if the user gets the question, else it continues running till he gets it
while(a != b){
cout << "You're incorrect!\n";
cout << "type in a number from (1 - 10)\n";
cin >> b;
while(b <= 3){
exit(3);
}
}
//print result
if(a == b){
cout << "congratulations";
}
return 0;
}
how can I make this work?
You could count the number of times the user answers and stop when it has executed for the number of times you want.
//prompt the user for numbers ranging from 1 - 10
cout << "type in a number from (1 - 10)\n";
cin >> b;
int answer_count = 1; // variable to count answers (there is already 1 answer here)
const int max_attempts = 10; // number of attempts the user has
//check if the number is the same has the random number
//this checks to see if the user gets the question, else it continues running till he gets it
while(a != b){
cout << "You're incorrect!\n";
cout << "type in a number from (1 - 10)\n";
cin >> b;
answer_count++; // count this new answer
if (answer_count >= max_attempts){ // check if the count reached the "certain amount of time"
break; // exit from this loop
}
}
Alternatively, you could also give the user a certain amount of time to guess. For example, 10 seconds. This can easily be achieved using the C++ chrono library:
#include <chrono>
#include <iostream>
#include <random>
int main(int argc, char **argv)
{
const int max_time = 10; // seconds
const int min_secret = 1;
const int max_secret = 10;
// This generates a random number between min_secret and max_secret using the STL random library
std::random_device r;
std::default_random_engine e(r());
std::uniform_int_distribution<int> uniform_dist(min_secret, max_secret);
int secret = uniform_dist(e);
auto start = std::chrono::system_clock::now();
int guess;
do {
std::cout << "Type a number from (1 - 10)\n";
std::cin >> guess;
if (guess == secret)
break;
std::cout << "Your guess is incorrect!\n";
// See if the time elapsed since the start is within max_time
auto now = std::chrono::system_clock::now();
auto elapsed_time = std::chrono::duration_cast<std::chrono::seconds>(now - start);
if (elapsed_time.count() > max_time) {
std::cout << "You ran out of time.\n";
exit(0);
} else {
std::cout << "You still have " << max_time - elapsed_time.count() << " seconds left\n";
}
} while (guess != secret);
std::cout << "Your guess was correct, congratulations!";
}
Note that the time check is only performed after the user tried to guess, so if the time limit is 10 seconds and the user waits 30 to type, it will still allow. To kill the program entirely with a timer in C++, you could use the thread library to spawn a second thread that handles the elapsed time, or even use an interruption based scheme (see https://stackoverflow.com/a/4001261/15284149 for an example of timer).
Also, note that the user input is not sanitized, and if the user writes anything other than a number your program has undefined behavior.
You need to fix up several things in your code:
The variable c is kept uninitialized and incremented later to use nowhere. Remove this. Note that d, e, f are unused as well.
In the loop:
for(int i = 1; i == 1; i++) {
a = 1 + (rand() % 10);
cout << a << endl;
}
You have told the compiler to iterate until i == 1, increment it by one, it is only done once – and that you might not want to do but i < 10.
Also, You are not using an array to store those 10 random numbers, but the last one. You need to make an array of 10 rooms and assign it to each of them:
int a[10];
// Since the array index begins at zero
for (int i = 0; i < 10; i++) {
a[i] = (rand() % 10) + 1;
cout << a[i] << endl;
}
After the successful assignment, it's time to introduce a randomly chosen index as the right answer (it should be put before the while loop):
// To choose the random index
int shuffle = a[rand() % 10];
Also, replace the congratulating statement:
// It was a == b previously
if (shuffle == b)
cout << "congratulations";
Lastly, to quit after three incorrect attempts, replace the while loop:
int count = 0;
while (shuffle != b) {
count++;
cout << "You're incorrect!\n";
cout << "type in a number from (1 - 10)\n";
cin >> b;
if (count == 2) {
cout << "Game Over" << endl;
exit(0);
}
}
I'm working in a simple program that calculates the root of any given function using Newton-Raphson's method. In this program I have to print the found root and the number of iterations made. The program itself is fine, I can find the root of any given function but I can't count properly the number of iterations. It is always 5 over the max. number of iterations or 1 less than it. Here's the code in C++:
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
double f(float x)
{
double function1;
function1 = exp(x)- 4*pow(x,2); // given function
return function1;
}
double derivative(float x)
{
double derivative1;
derivative1 = exp(x) - 8*x; // derivative of given function
return derivative1;
}
void newtonMethod(double x0, double error, int N)
{
double xNext, xPrevious, root;
int k;
xPrevious = x0;
for(int i = 0; i < N || f(xNext) > error; i++)
{
xNext = xPrevious - (f(xPrevious)/derivative(xPrevious)); // calculates the next value of x
xPrevious = xNext;
root = xNext;
k = i;
}
cout << endl;
cout << "Iterations made: " << k << endl;
cout << endl;
cout << endl;
cout << endl;
cout << "Root is: " << root << endl;
}
int main()
{
double x0, error;
int N; // max. number of iterations you can do
cout << "Enter x0: ";
cin >> x0;
cout << "Enter the error: ";
cin >> error;
cout << "Enter the max. number of iterations: ";
cin >> N;
newtonMethod(x0, error, N);
}
And I'm pretty sure the error is in this piece of code:
;i < N || f(xNext) > error;
If I run this program and put N = 100, it shows the right root but it prints "Iterations made = 99" but this is wrong. What do I do to print the right number of iterations made? For example, for the function in the program above (e^x - 4x²) it should stop in the fourth iteration if I enter x0 = 0.5 and error = 0.0001. How to fix it?
To answer your question, which was why the following piece of code does not work:
;i < N || f(xNext) > error;
It is simply because that, in a for loop condition, it is a continuing condition that is evaluated, and not a stopping condition.
In the above piece of code, what you are telling the compiler is: continue the loop as long as either i < N is true or f(xNext) > error is true. Therefore, when you input x0 = 0.5, error = 0.0001 and N = 100, what the loop does is that it will not stop until both criteria are false, i.e. when i reaches N AND the tolerance in f(x) is smaller than error.
Now, the solution is simply to swap the || operator to && operator. Like this:
i < N && f(xNext) > error;
but then, your xNext is not initialized. Because that your xNext and xPrevious are equal at the end of each loop, I would simply put xPrevious instead. In addition, as #Rathat has written, evaluating your tolerance in f(x) should take its absolute value, so:
i < N && abs(f(xPrevious)) > error;
Finally, you should output the number of iterations as k + 1 since you started with i = 0.
This should solve your problem.
thanks for all the answers. I found out what's wrong besides the logic behind the for condition that #yuxiangDev explained very well. Despite #RatHat code being totally right the error was in the math.h library I was using. I tried with <cmath> and it worked really well! lol.
I'm having trouble giving the user an option to loop a loop. This program works fine
#include <iostream>
using namespace std;
int main()
{
// goal is to calculate the sum of the first 10 terms of Leibniz's Series....
// calculated by 1 - 1/3 + 1/5 - 1/7 + 1/9 ..... - 1/19
int termNumber; // keeps track of term numbers
int numberOfTerms = 0;
cout << "Enter number of Terms";
cin >> numberOfTerms;
double sum = 0.0;
int sign = +1;
for (termNumber = 1; termNumber <= numberOfTerms; termNumber++)
{
sum += ( sign / (2.0 * termNumber - 1));
sign *= -1;
}
cout << "\n\n The sum is " << ( 4 * sum) << "\n\n";
} // end body of loop
I need to give the user an option to repeat the program if he would like so I thought I could put it in a do-while loop, but when I do that it only loops "enter number of terms" any way I try to format it. This is the best I have at the moment.
#include <iostream>
using namespace std;
int main()
{
// goal is to calculate the sum of the first 10 terms of Leibniz's Series....
// calculated by 1 - 1/3 + 1/5 - 1/7 + 1/9 ..... - 1/19
cout << "\nGiven a positive integer specifying some number of terms, this program\n approximates "
"pi using Leibniz' Formula and the given number of terms.\n\n" ;
cout << "Leibniz' formula is 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + ... = Pi / 4.\n\n";
char yes = 0;
double sum = 0.0;
do {
int termNumber; // keeps track of term numbers
int numberOfTerms = 0;
int sign = +1;
cout << "enter number of terms.\n";
cin >> numberOfTerms;
for (termNumber = 1; termNumber <= numberOfTerms; termNumber++)
{
sum += (sign / (2.0 * termNumber - 1));
sign *= -1;
}
}
while (yes = 1);
cout << "\n\n The sum is " << (4 * sum) << "\n\n";
cout << "would you like to go again? " << yes;
} // end body of loop
I would like to give them the option to try a different amount using term numbers where y/Y and n/N work.
Thanks for any help I may get.
You need a cin to set yes and your cout lines are in the wrong place. They need to be inside of your do while loop. And an == in your while
do {
int termNumber; // keeps track of term numbers
int numberOfTerms = 0;
int sign = +1;
cout << "enter number of terms.\n";
cin >> numberOfTerms;
for (termNumber = 1; termNumber <= numberOfTerms; termNumber++)
{
sum += (sign / (2.0 * termNumber - 1));
sign *= -1;
}
cout << "\n\n The sum is " << (4 * sum) << "\n\n";
cout << "would you like to go again? " << yes;
cin >> yes
}
while (yes == 1);
try that
Just my two cents but maybe you can combine both of your ideas and use functions. Put the code you have in the do part above into a function with a parameter of number of terms. Also use your for loop in the body of this function. Then on the outside of your for loop call another function that asks the user if they would like to continue and also ask a new number for the "terms" and pass that back into the first function if the user supplies a 'y' or 'Y' else if a 'n' or 'N' you can just stop the program
Have you learned to use
continue;
in a for loop? I think this fits your description, basically what
continue;
does is it returns to the beginning of the for-loop in this case in a certain scenario.
The problem with the do while loop is that the variable used in the while() statement must have been defined outside of the loop body, even though syntactically is belongs to the loop. This can be avoided when using a for loop instead, which allows the definition of such variables within the for statement. Here is an example.
inline double leibniz (int n) noexcept // function for Leibniz sum
{
double result=0;
for(int k=1,sign=1; n; --n,++++k,sign=-sign)
result += double(sign)/double(k);
return result;
};
int main()
{
// no loose variables defined outside loop
for(bool again=true; again; ) { // control variable only lives withing loop body
int n; // number of terms, only needed within loop body
std::cout<<"number of terms = ";
std::cin >> n;
std::cout<<"result = "<<leibniz(n)<<'\n'
<<"try again? (1/0)";
std::cin >>again;
}
}
Thanks everyone for the help.
I didn't know the continue; yet, but I learned about it.
The major problem was my cin and cout were not in the right spot like stated before. Redid the last line to while (yes == 'Y' || yes == 'y'); and now all works perfectly.
You guys are great!
#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
int min = 1;
int max = 100;
int count = 0;
int randomint = min + (rand() % (int)(max - min + 1));
bool isCorrect = true;
while(!isCorrect){
int guess = 0;
cout << "What is your guess? " << endl;
cin >> guess;
if(guess < randomint){
cout << "Too low!" << endl;
count++;
} else if (guess > randomint){
cout << "Too high!" << endl;
count++;
} else{
cout << "Correct!" << endl;
cout << "Number of Guesses: " << count << endl;
isCorrect = true;
}
}
}
New C++ Programming. I couldn't get this to compile one IDEOne because it doesn't have the input system I need to work this program. I have to submit this for a class shortly, but given that my larger disk (where all my software was stored) was corrupted last night.
I apologize for the silliness of this question.
Yes, it is syntactically correct, but not logically, due to
bool isCorrect = true;
which prevents loop from starting, it should be
bool isCorrect = false;
and works like a charm (but it would be reasonable to initialize the random number generator by for example running srand(time(NULL));)
There are two things logically wrong in your program:
The game won't run at all, since isCorrect is initially true.
The random number generator doesn't get a seed, so rand() will return the same value on every run and randomint is always the same. You should call srand( seed ) beforehand, where seed is a unsigned (for example time(0)).*
*actually, your game will still run if you don't do this, but it's easy to beat after the first try
I know I am probably just doing something dumb wrong, but I need to take a number from the user, create an infinite loop (by making my while statement true) of multiples of 2. I got the math to multiply the number from the user times itself, but I can't get it to loop. This is the last part of my homework for the week and my brain is fried, so I can't figure out where I went wrong!
Any help would be amazing! Here is what I have:
#include <iostream>
using namespace std;
int main (int argc, const char * argv[])
{
int d;
int e;
cin >> d;
while (true)
{
e = d * d;
}
cout << e << ", ";
}
There is unreachable code at: cout << e << ", ";
Perhaps this was meant to go in the while loop?
You are assigning e the value of d*d over and over. Because d*d does not change, the value of e never changes. Perhaps you should initialize e to the number you want outside of the loop, and then set e = e * 2 inside of the loop, then print e. This will print multiples of your number by successive powers of 2, which is what I think you want.
As written, your code will loop forever and, as a result, it will never get to that cout statement. Maybe you want to put the cout statement inside of the loop body so that the variable gets printed?
One of the the possible solutions:
int main (int argc, const char * argv[])
{
int d;
int e = 2;
cin >> d;
while (d>0)
{
cout << e << ", ";
e = e * 2;
d--;
}
}