-2

I am new to C++ and I have some problems with (pseudo-)random numbers.

This cpp file is supposed to give 3 arrays. 1 float array of [16] 2 integer arrays of [16] (total: 32).

The float array is different from the integer arrays (as expected) but my integer arrays are exactly the same... Can someone help me with this problem?

PS. It does not output any error messages for this problem When I restart the program the int Array will be completely different but AGAIN 2 exact copies...

CODE: GenerateWorld.cpp

#include "GenerateWorld.h"
#include "CalculateBiomeBoundries.h"
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include "write.h"
#include <random>
#include <ctime>



GenerateWorld::GenerateWorld()
{
}


GenerateWorld::~GenerateWorld()
{
}

bool GenerateWorld::generate() {

    exportData = "";
    createRand(1);
    createRand(2);
    createRand(3);

    std::cout << "DATA: " << exportData << std::endl;

    Write write;
    write.save("World12", "biomes", exportData);
    CalculateBiomeBoundries biome;
    biome.calculate("World12", exportData);


    return true;

}

void GenerateWorld::createRand(int type) {
    std::stringstream stream;
    std::default_random_engine randomGenerator(time(0));
    std::uniform_real_distribution<float> rf(-0.001f, 0.001f);
    std::uniform_int_distribution<int> ri(-10000, 10000);

    for (int i = 0; i < 16; i++) {
        if (type == 1) data[i] = rf(randomGenerator); //float
        else data[i] = ri(randomGenerator); //int

        stream << data[i];
        std::string s(stream.str());
        exportData += s;
        if (i != 15) exportData += ",";
        stream.str(std::string());
    }

    if(type != 3) exportData += "\n"; //if not the last one
    stream.str(std::string());
}

CODE: GenerateWorld.h

#pragma once
#include <string>
class GenerateWorld
{
public:
    GenerateWorld();
    ~GenerateWorld();
    bool generate();

private:
    float data [200];
    std::string exportData;
    void createRand(int type);
};

OUTPUT:

DATA: -0.000774365,-7.83865e-05,-8.13702e-05,-0.000535194,-4.61116e-05,-0.000753322,0.000817172,-0.000967061,-0.000489403,-0.000969965,0.00026489,0.000407262,-0.000975306,-0.000866959,-6.6199e-05,-0.000780731
-6988,1037,-6061,3309,7252,1025,1222,3339,-5866,7040,5405,-8961,-1645,-107,-8060,3380
-6988,1037,-6061,3309,7252,1025,1222,3339,-5866,7040,5405,-8961,-1645,-107,-8060,3380

The last two rows are exact duplicates (same array data). How can I fix this?

I would like to have two different (psuedo-)random int Arrays. Any help would be awesome!

thank you in advance

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Bjorn
  • 83
  • 1
  • 10
  • Don't seed with `time()` see: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful – Richard Critten Jul 08 '19 at 21:24
  • hoe does that work? – Bjorn Jul 08 '19 at 21:24
  • Please do not vandalize your posts. By posting on the Stack Exchange network, you've granted a non-revocable right for SE to distribute that content (under the [CC-BY-SA 3.0 license](//creativecommons.org/licenses/by-sa/3.0)). By SE policy, any vandalism will be reverted and subsequent attempts will get you banned. If you would like to disassociate this post from your account, see [What is the proper route for a disassociation request](//meta.stackoverflow.com/q/323395/584192)? – Samuel Liew Jul 08 '19 at 23:17

1 Answers1

2

You're repeatedly reseeding with time(0) which only has second-level granularity, so as long as the code doesn't cross a second boundary, you're always seeding with the same value.

Make your engine once, and reuse it instead of reseeding over and over. The simplest solution would be to just change:

std::default_random_engine randomGenerator(time(0));

to:

static std::default_random_engine randomGenerator(time(0));

which initializes a single global copy once, and reuses it without reseeding. This is fine if you don't need crypto grade randomness, just something "randomish".

Better solutions involve using std::random_device to produce seed (though sadly, the C++ standard doesn't require it to be implemented with cryptographic randomness, so it's surprisingly difficult to do this properly and portably with any guarantees on behavior).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Do note that `std::random_device` is not guaranteed to give even random numbers. It may always give the same sequence. – NathanOliver Jul 08 '19 at 21:29