0

I'm creating a program in which I need to output a different thing a different time. It is random, but it is always outputs the same thing, and yes I put in srand.

void setcolor()
{
    srand(time(NULL));
    int col = rand() % 4 + 1;
    if (col == 1)
    { cout << "white "; }
    else if (col == 2)
    { cout << "brown "; }
    else if (col == 3)
    { cout << "black "; }
    else if (col == 4)
    { cout << "spotted "; }
}

int main() 
{
    for (int i = 0; i <= 5; ++i)
    {
         setcolor();
    }
} 

2 Answers2

1

srand must be called once and not in each loop.

void setcolor()
{
    int col = rand() % 4 + 1;
    if (col == 1)
    { cout << "white "; }
    else if (col == 2)
    { cout << "brown "; }
    else if (col == 3)
    { cout << "black "; }
    else if (col == 4)
    { cout << "spotted "; }
}

int main() 
{
    srand(time(NULL));
    for (int i = 0; i <= 5; ++i)
    {
         setcolor();
    }
}

It works this way because srand initialize a "global variable" that is used by rand() function.

time(null) return something like the number of seconds that are elapsed from 1st january 1970. So you are using 5 times the same value because of the initialisation of the "global variable".

However, in C++, it is not the right way to use random values. Please prefer use random header instead (http://en.cppreference.com/w/cpp/numeric/random) :

#include <iostream>
#include <string>
#include <map>
#include <random>

int main()
{
    std::random_device rd;
    std::map<int, int> hist;
    std::uniform_int_distribution<int> dist(0, 9);
    for (int n = 0; n < 20000; ++n) {
        ++hist[dist(rd)]; // note: demo only: the performance of many 
                          // implementations of random_device degrades sharply
                          // once the entropy pool is exhausted. For practical use
                          // random_device is generally only used to seed 
                          // a PRNG such as mt19937
    }
    for (auto p : hist) {
        std::cout << p.first << " : " << std::string(p.second/100, '*') << '\n';
    }
}
Antoine Morrier
  • 3,930
  • 16
  • 37
0

Using time to seed in your case srand(time(NULL)); may lead to situation when the value returned by time stays the same on each iteration because of its low precision so random generation restarts from the same spot. So you should call it only once before starting the loop.

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • Even if `time` was always different on different iterations, it is obviously a terrible idea to continuously re-seed an RNG from a non-random source, thus defeating the point. – underscore_d Aug 20 '17 at 10:33