I recently got to a certain exercise in a book I am reading, and am looking for feedback. It is a program in which the user picks a number and the computer uses algorithms to guess it. If there is any way that I can improve my code, feedback is really appreciated!
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0))); //seed random number generator
int compNumber = rand() % 100 + 1;
int yourNumber;
cout << "Please input a number between 1 and 100" << endl;
cin >> yourNumber;
cout << "Ok! I'm gonna try to guess it!" << endl;
while (compNumber != yourNumber)
{
if (compNumber > yourNumber)
{
do
{
--compNumber;
} while (compNumber != yourNumber);
}
else if (compNumber > yourNumber)
{
do
{
++compNumber;
} while (compNumber != yourNumber);
}
}
cout << "I guessed it! Your number is " << compNumber << endl;
return 0;
}
3 Answers 3
Sure this generates a random number from 1 -> 100.
int compNumber = rand() % 100 + 1;
BUT not all the numbers have an even probability. Assuming RAND_MAX is 32768 (a common value). Then the number 1->68 have a slightly higher probability than the number 69->100.
To get an even distribution you need to compensate for this:
int compNumber
do
{
compNumber = rand();
}
while (compNumber > (RAND_MAX / 100 * 100));
compNumber = compNumber % 100 + 1;
Better yet learn to use the modern random number generator that is built into C++.
// I have not tested this.
// Just copied and pasted from: http://stackoverflow.com/a/19666713/14065
// This is the modern equivalent of srand()
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<int> dist(1, 100);
// Then usage is.
// equivalent of rand().
std::cout << dist(mt) << "\n";
This does not look correct:
if (compNumber > yourNumber)
{}
else if (compNumber > yourNumber)
{}
The conditions look the same to me.
This does not look like guessing.
do
{
--compNumber;
} while (compNumber != yourNumber);
This looks like the computer counting down until it reaches your number.
-
\$\begingroup\$ Note modern random number generator requires a
C++11
compiler. \$\endgroup\$Richard Dally– Richard Dally2015年12月30日 13:09:14 +00:00Commented Dec 30, 2015 at 13:09 -
\$\begingroup\$ To be more precise, point about
rand() % N
matters asN
approachesRAND_MAX
. If we compare probabilities of generating 2 numbers - one from higher part and one from lower, the latter would be around1 + N / RAND_MAX
of the former, which translates to about 0.3% difference in our particular case, but gets to around 1/3 ifN
is 10000. \$\endgroup\$Daerdemandt– Daerdemandt2017年01月18日 14:39:02 +00:00Commented Jan 18, 2017 at 14:39
Based on your (vague) description of the exercise, it seems like the user should keep the number in their head until the very end, and each time the computer guesses a number the user tells the computer if the number is higher or lower. That's the exact reverse of the usual programming exercise. In that case, what you could do is:
int compNumber = 50;
int low = 1;
int high = 100;
int yourNumber;
do
{
yourNumber=0;
cout << "Please input a number between 1 and 100" << endl;
cin >> yourNumber;
} while(yourNumber<1||yourNumber>100); /* a check to make sure the number is actually between 1 and 100 */
while(compNumber!=yourNumber)
{
if(yourNumber<compNumber)
{
cout << "I guessed " << compNumber << " (too low)" << end1;
high = compNumber;
compNumber=(compNumber+low-1)/2;
}
else
{
cout << "I guessed " << compNumber << " (too high)" << end1;
low = compNumber;
compNumber=(compNumber+high+1)/2;
}
}
cout << "I guessed it! Your number is " << compNumber << end1;
If i'm correct, the answer that Blue gave is entirely correct. Although i have one minor improvement. Using his code actually makes the computer guess your number but it always starts guessing at 50. If you would like the computer to start at a different number each time you can add the line:
srand(static_cast<unsigned int>(time(0)));
and change the line after that too:
int compNumber = rand() % 100+1;
This will only change the starting number, so that the computer will start at a different number each times, either enlarging the chances of the computer guessing the number or making them smaller. this would be the entire code:
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(static_cast<unsigned int>(time(0)));
int compNumber = rand() % 100+1;
int low = 1;
int high = 100;
int yourNumber;
do
{
yourNumber = 0;
cout << "Please input a number between 1 and 100" << endl;
cin >> yourNumber;
} while (yourNumber < 1 || yourNumber>100); /* a check to make sure the number is actually between 1 and 100 */
while (compNumber != yourNumber)
{
if (yourNumber < compNumber)
{
cout << "I guessed " << compNumber << " (too high)" << endl;
high = compNumber;
compNumber = (compNumber + low - 1) / 2;
}
else
{
cout << "I guessed " << compNumber << " (too low)" << endl;
low = compNumber;
compNumber = (compNumber + high + 1) / 2;
}
}
cout << "I guessed it! Your number is " << compNumber << endl;
return 0;
}
You could even show after the guesses how many tries it took the computer to guess the number. Just add the variable: int guesses = 0;
and directly after:
compNumber = (compNumber + low - 1) / 2;
put
++guesses;
and after:
cout << "I guessed it! Your number is " << compNumber << endl;
you could put:
cout << "Number of guesses it took me: " << guess << endl;
now it will show how many guesses it took the computer to guess it
-
\$\begingroup\$ Thanks for editing my comment @rolfl, it was the first comment I made and I'm quite sure I made some mistakes. I'm new to C++ and am quite eager to learn a lot about it! \$\endgroup\$user128548– user1285482017年01月18日 18:40:31 +00:00Commented Jan 18, 2017 at 18:40
compNumber = yourNumber;
? \$\endgroup\$