C++ random number generator only generates 0 - C++ 11 - c++

I am trying to generate a random number between 0 and 2 (inclusive) for a C++ program:
#include <iostream>
#include <string>
#include <cstdlib>
#include <random>
using namespace std;
int generateRowMovement(){
//http://www.cplusplus.com/reference/random/uniform_int_distribution/
default_random_engine generator;
uniform_int_distribution<int> distribution(0,2);
int row = distribution(generator);
return row;
}
int main(){
int row = generateRowMovement();
cout << row << endl;
int row2 = generateRowMovement();
cout << row2 << endl;
int row3 = generateRowMovement();
cout << row3 << endl;
return 0;
}
All 3 results are:
0
0
0
I have been testing this for 30 minute and it is always zero. I have tried following this link and this SO post (which posts link back to), but none of their solution is fix this problem. How can I generate 0, 1, and 2?

There are two issues with the code you posted that keeps it from working how you intend it to. The first is that generator is never given a seed, or as is commonly shown online, a random_device, ie
random_device rd;
default_random_engine generator(rd());
The second is that every time you call the function, you're creating a new random engine, and a new distribution. It would be better to create a random device, give it to to the engine only once, and then let your function return the values based on those.
#include <iostream>
#include <string>
#include <cstdlib>
#include <random>
using namespace std;
random_device rd;
default_random_engine generator(rd());
uniform_int_distribution<int> distribution(0,2);
int generateRowMovement(){
return distribution(generator);
}
int main(){
int row = generateRowMovement();
cout << row << endl;
int row2 = generateRowMovement();
cout << row2 << endl;
int row3 = generateRowMovement();
cout << row3 << endl;
return 0;
}

Related

Can I pick a random element from an array in C++?

This has been bugging me for days:
#include <iostream>
using namespace std;
string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string word = words[rand() % 6];
string guess;
int lives = 3;
int main()
{
std::cout << "Can you guess what word I'm thinking of? I'll give you a hint: it's a food that starts with the letter C. You have three tries. Good luck!" << std::endl;
while(lives > 0)
{
std::cin >> guess;
std::cout << std::endl;
if(guess == word)
{
std::cout << "Wow, That's actually correct! Good job!" << std::endl;
break;
}
else
{
lives--;
std::cout << "Nope! You now have " << lives << " lives left." << std::endl;
}
}
if(lives <= 0)
{
std::cout << "And... you lose!" << std::endl;
}
return 0;
}
I'm currently working on a word-guessing game, but when I try to pick a random element from my words array, it gets stuck on element 1 (i.e "cookie"). I used:
string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string word = words[rand() % 6];
Help would be appreciated.
If you want to do it C++ style, use , and for maintenance I think std::vector of std::string is a good choice too.
#include <iostream>
#include <vector>
#include <string>
#include <random>
int main()
{
std::vector<std::string> words{ "cake", "cookie", "carrot", "cauliflower", "cherries", "celery" };
// gets 'entropy' from device that generates random numbers itself
// to seed a mersenne twister (pseudo) random generator
std::mt19937 generator(std::random_device{}());
// make sure all numbers have an equal chance.
// range is inclusive (so we need -1 for vector index)
std::uniform_int_distribution<std::size_t> distribution(0, words.size() - 1);
for (std::size_t n = 0; n < 40; ++n)
{
std::size_t number = distribution(generator);
std::cout << words[number] << std::endl;
}
}
rand() is a pseudo random number generator. That means, given the same starting conditions (seed), it will generate the same pseudo random sequence of numbers every time.
So, change the seed for the random number generator (e.g. use the current time as a starting condition for the random number generator).
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
static const string words[] = {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
int main() {
//variables moved to inside main()
string guess;
int lives = 3;
srand(time(NULL));
string word = words[rand() % 6];
if u didnt generate using a srand() function
ur programm will automatic generate for you with the seed 1
so you can proceed it like this:
#include<cstdlib>
#include<ctime>
...
int main()
{
srand(time(NULL));
....
}
You shouldn't use rand in C++, there are far better random engines.
#include <iostream>
#include <array>
#include <random>
using namespace std;
// use std::array as a better alternative to C arrays
array words {"cake", "cookie", "carrot", "cauliflower", "cherries", "celery"};
string guess;
int lives = 3;
int main()
{
std::mt19937 gen{std::random_device{}()}; // generates random numbers
std::uniform_int_distribution<std::size_t> dist(0, words.size() - 1); // maps the random number to [0..number of words]
int index = dist(gen);
string word = words[index];
...
}

How to create an array of normal distributed random number generators in c++?

I need a series of normally distributed random numbers, with different mean and variance, I know how to create one series with a particular mean and variance but can I have like an array of generators?
like for 1 series we have
#include <random>
#include <iostream>
using namespace std;
int main()
{
random_device rd;
mt19937 gen(rd());
normal_distribution<double> d(0.0, 1.0);
for (int i = 0; i < 5000; i++)
cout << " " << d(gen) << "\n";
return 0;
}
and this gives me a series of normally distributed random numbers, and i know i can create another d with another mean and variance for another series but is there any way to have a lot of such normal_distribution d together in an array so that i can choose a particular generator by simply choosing an element in the array.
I have tried a version where
#include <random>
#include <iostream>
using namespace std;
int main()
{
random_device rd;
mt19937 gen(rd());
normal_distribution<double> d(0.0, 1.0),d2(0.0,1.0);
normal_distribution<double> D[]={d,d2};
for (int i = 0; i < 5000; i++)
cout << " " << D[0](gen) << "\n";
system("pause");
return 0;
}
but I want to initialize it directly with the array like D0 some thing like that so that i can put it in a loop
Sure you can
#include <iostream>
#include <vector>
#include <random>
int main() {
std::vector<std::normal_distribution<double>> D{
std::normal_distribution<double>{0.0, 1.0 },
std::normal_distribution<double>{0.0, 2.0 } };
std::random_device rd;
std::mt19937 gen(rd());
std::cout << D[0](gen) << "\n";
std::cout << D[1](gen) << "\n";
return 0;
}
As you know C++ provide a functions for random numbers and we can also create and initialize array as given below. I hope it will helpful if not comment below.
const int nrolls=10000; // number of experiments
const int nstars=100; // maximum number of stars to distribute
std::default_random_engine generator;
std::normal_distribution<double> distribution(5.0,2.0);
int p[10]={};
for (int i=0; i<nrolls; ++i) {
double number = distribution(generator);
if ((number>=0.0)&&(number<10.0)) ++p[int(number)];
}
std::cout << "normal_distribution (5.0,2.0):" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << i << "-" << (i+1) << ": ";
std::cout << std::string(p[i]*nstars/nrolls,'*') << std::endl;
}

Dice roll not working C++ deafult_random_engine

For some reason I keep getting 6 every time. I know of another way to do a random dice roll, but I wanted to learn how to use the deafult_random_engine.
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
int main()
{
default_random_engine randomGenerator(time(0));
uniform_int_distribution<int> diceRoll(1, 6);
cout << "You rolled a " << diceRoll(randomGenerator) << endl;
}
But this bit of code works with the time(0).
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
// dice roll
{
srand(time(0));
for(int x = 1; x < 2; x++){
cout << 1+(rand()%6) << endl;
}
return 0;
}
It's almost certainly the use of time(0) as the culprit here.
You should probably opt for a method like this:
#include <iostream>
#include <string>
#include <chrono>
#include <random>
#include <ctime>
using namespace std;
int main() {
default_random_engine randomGenerator(std::random_device{}());
// OR:
// default_random_engine randomGenerator(
// (unsigned) chrono::system_clock::now().time_since_epoch().count());
uniform_int_distribution<int> diceRoll(1, 6);
cout << "You rolled a " << diceRoll(randomGenerator) << endl;
return 0;
}
While your original code always produced 6 on my system, this one seems a little more "adventurous":
pax> for i in {1..10}; do ./qq ; sleep 1 ; done
You rolled a 5
You rolled a 5
You rolled a 6
You rolled a 1
You rolled a 6
You rolled a 5
You rolled a 2
You rolled a 3
You rolled a 5
You rolled a 4
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
int main()
{
mt19937 randomGenerator(time(0));
uniform_int_distribution<int> diceRoll(1, 6);
cout << "You rolled a " << diceRoll(randomGenerator) << endl;
}

srand(time(0)) not making random numbers?

Here is the code, but the outputs aren't coming out random? Maybe cause when the program runs it has the same time as all the loops?
#include <iostream>
using namespace std;
#include <string>
#include <cmath>
#include <ctime>
#include <cstdlib>
int main()
{
long int x = 0;
bool repeat = true;
srand( time(0));
int r1 = 2 + rand() % (11 - 2); //has a range of 2-10
int r3 = rand();
for (int i = 0; i <5; i++)
{
cout << r1 << endl; //loops 5 times but the numbers are all the same
cout << r3 << endl; // is it cause when the program is run all the times are
} // the same?
}
You need to move your calls to rand() to inside your loop:
#include <iostream>
using namespace std;
#include <string>
#include <cmath>
#include <ctime>
#include <cstdlib>
int main()
{
long int x = 0;
bool repeat = true;
srand( time(0));
for (int i = 0; i <5; i++)
{
int r1 = 2 + rand() % (11 - 2); //has a range of 2-10
int r3 = rand();
cout << r1 << endl; //loops 5 times but the numbers are all the same
cout << r3 << endl; // is it cause when the program is run all the times are
} // the same?
}
That said: since you're writing C++, you really want to use the new random number generation classes added in C++ 11 rather than using srand/rand at all.
You must call rand() each loop iteration.
for (int i = 0; i <5; i++)
{
cout << 2 + rand() % (11 - 2) << endl;
cout << rand() << endl;
}
What was happening before was that you were calling rand() twice, one for r1 and once for r3, and then simply printing the result 5 times.

How do i get random value in c++ 11 [duplicate]

This question already has answers here:
c++ integer->std::string conversion. Simple function?
(3 answers)
Closed 9 years ago.
My code:
#include <iostream>
#include <random>
void main()
{
std::random_device rd;
std::cout << "Random value: " << rd() << std::endl;
system("pause");
}
How do i get the result rd(), and convert it to std::string?
Since you are asking how to convert the result of std::random_device to a string, and std::random_device returns an unsigned int. C++11 provides std::to_string, can be used to convert numbers to strings. See here.
#include <iostream>
#include <random>
#include <string>
int main()
{
std::random_device rd;
std::string str = std::to_string(rd());
std::cout << str << std::endl;
return 0;
}
Here's an example I found on http://en.academic.ru/dic.nsf/enwiki/11574016
#include <random>
#include <functional>
std::uniform_int_distribution<int> distribution(0, 99);
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(distribution, engine);
int random = generator(); // Generate a uniform integral variate between 0 and 99.
int random2 = distribution(engine); // Generate another sample directly using the distribution and the engine objects.
I haven't worked with it before, but this might help you get started.
std::stringstream is one way to convert a number to a string, the code below shows various engines and distributions possible. It defaults to Mersenne Twister for the engine and the normal distribution. This is good reference for the options available:
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <sstream>
int main()
{
std::random_device rd;
//
// Engines
//
std::mt19937 e2(rd());
//std::knuth_b e2(rd());
//std::default_random_engine e2(rd()) ;
//
// Distribtuions
//
std::normal_distribution<> dist(2, 2);
//std::student_t_distribution<> dist(5);
//std::poisson_distribution<> dist(2);
//std::extreme_value_distribution<> dist(0,2);
std::stringstream s1 ;
s1 << dist(e2) ;
std::string str1 = s1.str();
std::cout << str1 << std::endl ;
}
another method to convert to a string would be to use std::to_string:
str1 = std::to_string( dist(e2) ) ;
#include <stdlib.h>
#include <time.h>
int main(){
srand(time(NULL));
unsigned int maxValue = 50;
std::cout << "Random value: " << rand()%maxValue; //random between 0-50
return 0;
}