std::random_shuffle wircklich so zufällig??



  • Hi Leute,
    code gerade für die Schule an einem Memory Spiel bin eigentlich so gut wie fertig nur nervt mich die die oben genannte funktion mit der ich das Karten Array mische. Bei jedem Neustart werden die Karten gleich gemischt 😞 und das ist sicherlich nicht im Sinne des Erfinders da man sich so ja das spiel ja einfach auswendig merken könnte weil man weiß dass nach nem neustart die karten gleich liegen.

    std::random_shuffle(kset, kset + game_size);
    


  • Du wirst den Zufallszahlengenerator wohl zeitabhängig initialisieren müssen. Gibt's schon hundert Threads dazu, such einfach nach "zufall".



  • random_shuffle hat doch auch noch nen 3. Übergabewert was macht dieser und wie kann ich ihn angeben?



  • MSDN is immer gut!

    MSDN schrieb:

    Predicate Version of random_shuffle (STL Sample)
    The sample code below illustrates how to use the predicate version of the random_shuffle STL function in Visual C++.

    Required Header:
    <algorithm>

    Prototype:

    template<class RandomAccessIterator, class Predicate> inline
    void random_shuffle(RandomAccessIterator first, RandomAccessIterator last, Predicate pred)

    Note: The class/parameter names in the prototype do not match the version in the header file. Some have been modified to improve readability.

    Description:
    The random_shuffle algorithm shuffles the elements of a sequence [first..last) in a random order. The predicate version uses the pred function to generate the indices of the elements to swap. The pred has to be a function object that takes a parameter n and returns an integral random number in the range 0 - (n - 1). The predicate version of random_shuffle uses operator= to perform swaps.

    Sample Code:

    //////////////////////////////////////////////////////////////////////
    //
    // Compile options needed: /GX
    //
    // random_shuffle.cpp: Illustrates how to use the predicate version
    // of the random_shuffle function.
    //
    // Functions:
    //
    // random_shuffle: Shuffle the elements in a random order.
    //
    // Rand: Given n, generates an integral random number in the
    // in the range 0 - (n - 1).
    //////////////////////////////////////////////////////////////////////

    // disable warning C4786: symbol greater than 255 character,
    // okay to ignore
    #pragma warning(disable: 4786)

    #include <iostream>
    #include <algorithm>
    #include <functional>
    #include <vector>

    using namespace std;

    // return an integral random number in the range 0 - (n - 1)
    int Rand(int n)
    {
    return rand() % n ;
    }

    void main()
    {
    const int VECTOR_SIZE = 8 ;

    // Define a template class vector of int
    typedef vector<int > IntVector ;

    //Define an iterator for template class vector of strings
    typedef IntVector::iterator IntVectorIt ;

    IntVector Numbers(VECTOR_SIZE) ;

    IntVectorIt start, end, it ;

    // Initialize vector Numbers
    Numbers[0] = 4 ;
    Numbers[1] = 10;
    Numbers[2] = 70 ;
    Numbers[3] = 30 ;
    Numbers[4] = 10;
    Numbers[5] = 69 ;
    Numbers[6] = 96 ;
    Numbers[7] = 100;

    start = Numbers.begin() ; // location of first
    // element of Numbers

    end = Numbers.end() ; // one past the location
    // last element of Numbers

    cout << "Before calling random_shuffle:\n" << endl ;

    // print content of Numbers
    cout << "Numbers { " ;
    for(it = start; it != end; it++)
    cout << *it << " " ;
    cout << " }\n" << endl ;

    // shuffle the elements in a random order.
    // the pointer_to_unary_function adapter converts a function to a
    // function object.
    random_shuffle(start, end, pointer_to_unary_function<int, int>(Rand));

    cout << "After calling random_shuffle:\n" << endl ;

    cout << "Numbers { " ;
    for(it = start; it != end; it++)
    cout << *it << " " ;
    cout << " }\n" << endl ;
    }

    Program Output is:

    Before calling random_shuffle

    Numbers { 4 10 70 30 10 69 96 100 }

    After calling random_shuffle

    Numbers { 10 30 4 70 96 100 69 10 }

    Du kannst deine eigene Zufallsfunktion definieren (im MSDN-Beispiel Rand()) und diese als unäre Funktion angeben. Aber aufpassen! Auch hier muss wieder zeitabhängig initialisiert werden. Also srand(time(NULL)) oder ähnlich.



  • random_shuffle(kset,kset + game_size+1,pointer_to_unary_function<int, int>(Rand));
    

    Hi Leute also das obige funktioniert leider nicht (Compiler meldet keine Übereinstimmung blabla...)

    kset ist das [0] Objekt kset + game_size + 1 ist das letzte Objekt.
    kset ist kein Vector sondern ein normales Arrray



  • Jungs vergesst es habs jetzt so gelöst.

    srand(time(NULL));
     for (int i=0; i<game_size; i++)
            {
                int r = rand() % game_size;  // zufällig postion ermitteln
                TKarte temp = kset[i];
                kset[i] = kset[r];
                kset[r] = temp;
            }
    

    aber hab noch ne frag wieso liefert

    srand(time(NULL));
    

    einen zufallswert obwohl ein NULL Zeiger übergeben wird?



  • srand liefert keinen Zufallswert sondern initialisiert den Zufallsgenerator. und time(NULL) liefert AFAIK einfach einen aktuellen Zeitwert zurück (in ms)...

    Mfg, smasher1985



  • Exakt! "unsigned time(unsigned*)" erwartet nur zusätzlich die Adresse eines Wertes, damit er dort auch noch die Zeit reinschreiben kann.



  • time(NULL) liert die vergangenen sekunden seit dem 01.01.1970

    glaub mich jedenfalls daran zu erinnern



  • danke jungs!


Anmelden zum Antworten