mardi 21 mai 2019

What is the proper way of seeding std::mt19937 with std::chrono::high_resolution_clock inside a class?

First off, hello everyone! This is my first ever question here, so I hope I am not screwing up. I googled a lot before writing here. I am new to coding, to c++ and I am learning it on my own.

Considering that I was told that it is a good practice (i'm probably wrong here) to only seed any Random Engine once, what is the proper / best / more efficient way of using std::mt19937 from the random standard library inside a class, seeded by std::chrono::high_resolution_clock::now().time_since_epoch().count() from the chrono standard library?

I want to use that chrono value, because it changes really fast and it generates a hell of a creepy number. I never considered std::random_device because I think it is kinda shady. I'm probably wrong again.

I've done it successfully before I knew what a class is, but I am now learning classes and did a lot of trial and error (putting static_casts everywhere, trying const, static, etc, because the code was always giving errors) to get this done:

class Deck
{
private:
    std::array<Card, 52> m_card;
    const int m_seed {static_cast<int>(std::chrono::high_resolution_clock::now().time_since_epoch().count())};

    std::mt19937 m_rng {m_seed};

    int rng(int min, int max)
    {
        std::uniform_int_distribution<> rng{min, max};
    return rng(m_rng);
    }

    void swapCard(Card &a, Card &b)
    {
        Card temp {a};
        a = b;
        b = temp;
    }

public:

    Deck()
    {
        int index{0};
        for (int iii {0}; iii < Card::CS_MAX; ++iii)
        {
            for (int jjj {0}; jjj < Card::CR_MAX; ++jjj)
            {
                m_card[index] = Card(static_cast<Card::CardSuit>(iii), static_cast<Card::CardRank>(jjj));
                ++index;
            }
        }
    }

    void printDeck() const
    {
    for (int iii {0}; iii < 52; ++iii)
        {
            m_card[iii].printCard();
            if (((iii + 1) % 13 == 0) && iii != 0)
                std::cout << '\n';
            else
                std::cout << ' ';
        }
    }

    void shuffleDeck(int xTimes = 1)
    {
        for (int iii {0}; iii < xTimes; ++iii)
        {
            for (int jjj {0}; jjj < 52; ++jjj)
            {
                swapCard(m_card[jjj], m_card[rng(0, 51)]);
            }
        }
    }

};

This works, but I don't know if this is the proper way of doing it. Also, I was told that variables that never change can be made static to be shareable between all objects of the class, but I can not make m_seed static...

I am pretty sure there's a more effective way of doing this. Can you guys help?




Aucun commentaire:

Enregistrer un commentaire