Search code examples
c++randomconsolefield

"Procedural" playground generation in c++ console application


Adventure for learning basics and more in c++ (Total noob). Now i made a Playground Array for all the fields to visit, but when it comes to the rand() function in a for loop it repeats the Nummber so it's not random generated. Some ideads to fix this issue? Note that iam not very into the rand func. Thanks in advance!

Here is my code

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
//**SETTINGS**
//Häufigkeit von field_type

#define VILLAGE 5
#define TOWN 2



int main()
{   
    //** THE PLAYGROUND ** 
    struct field {
        bool status;
        string field_type;

    };
    int x = 5;
    int y = 5;
    field playground[5][5];

    //Playground Typen definition
    int village_counter = 0;
    int town_counter = 0;
    int x2 = 0;
    int y2 = 0;

    
    for (int counter = 0; counter < x * y; counter++) {

        int Nummer;
        srand(time(NULL));
        Nummer = rand() % 4 + 1;      // generates always the same number!


        switch (Nummer) {
        case 1:

            village_counter++;
            if (VILLAGE >= village_counter) {
                playground[x2][y2].field_type = "VILLAGE";

            }
            else {
                goto a_switch;
            }
            break;

        case 2:

            town_counter++;
            if (TOWN >= town_counter) {
                playground[x2][y2].field_type = "TOWN";
                
            }
            else {
                goto b_switch;
            }

            break;

        case 3:
            a_switch:
            playground[x2][y2].field_type = "GRASSLAND";
            break;
        case 4:
            b_switch:
            playground[x2][y2].field_type = "FOREST";
            break;
        }
        x2++;
        if (x2 == x) {
            x2 = 0;
            y2++;
        }

    }

    //For test usage of all Field's
    x2 = 0;
    y2 = 0;

    for (int counter = 0; counter < x * y; counter++) {
        cout << counter << ": Field_TYPE = " << playground[x2][y2].field_type << endl;
        x2++;
        if (x2 == x) {
            x2 = 0;
            y2++;
        }
    }

}

Solution

  • time requests the current time in seconds as an integer. if your program takes less than a second to execute, then you will "seed" the random number generator with the same value every time. pseudo random number generators (i.e. your rand() call) return a deterministic series of values based on this state you seeded.

    as @Scheff said, you're much better off just seeding once (probably at the beginning of the program) and then just calling rand() when you need it. note that srand and rand are old historical artifacts from C, and you're much better off using more modern generators that come with recent C++ compilers

    see the docs on c++ random number generators for more information