QT C++ Random Zahlen / Koordinaten



  • Hi, ich suche nach einer Lösung um meine Koordinaten die ich mit momentan Random über den QRandomGenerator erzeuge, zu überprüfen bevor ich sie an meinen Bot übergebe der mich damit beschießen soll ich meinem Spielfeld. Momentan kann er halt auch 100x auf das selbe Spielfeld schießen, und gewinnt dann bei genügend treffer, das möchte ich gerne Vermeiden

    Code:
    int index=QRandomGenerator::global()->bounded(0,99) ;
    int a = index%10;
    int b= index/10;
    QPushButton *button = gameBoardPlayer[index];
    bot.attack(a,b);

    Mein Spielfeld besteht aus 0-99 Buttons, die Attacke auf dem Spielfeld ist aber über Koordinaten gelöst, da er erstmal schaut ob das Feld leer ist oder ein Objekt beinhaltet. D.h. den Index übergebe ich an das "Board" direkt, aber benötige davon das x & y (Matrix 10x10) für den Beschuss. Allerdings sollte z.B. der Index bereits nur 1x vorkommen in den Random zahlen



  • @karooooo1234

    Bau dir nen vector mit allen gültigen Zufallszahlen und verwürfle ihn mit random_shuffle. Der nächste Schuss nimmt dann immer das erste Element aus dem Vektor und entfernt es aus dem Vektor. Damit haste dann die Garantie, dass jeder Wert in jedem Zyklus genau ein Mal verwendet wird. Du kannst auch das letzte Element des Vektors nehmen und entfernen, dann sparste dir das Rumkopieren, weil nicht mehr alle Elemente um eine Position nach vorn geschoben werden müssen. Oder du lässt nen Index laufen.



  • Einfach so:

    std::vector<int> number;
    
    for (int i=0; i<100; i++) {
        number.push_back(i);
        ++number[i]; 
    }
    

    Wie mache ich das jetzt mit dem random_schuffle?



  • @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    random_shuffle

    Das gibts seit C++17 nicht mehr. Nimm shuffle.

    // globaler Generator
    std::mt19937 rng(std::random_device{}());
    
    // vector mit Zahlen von 0..99 erstellen
    std::vector<int> v(100);
    std::iota(begin(v), end(v), 0);
     
    // durchmischen
    std::shuffle(begin(v), end(v), rng);
    


  • Hab in diesem neumodischen Dinges, diesem Internetz, Internet oder so das hier gefunden:
    random_shuffle



  • @wob sagte in QT C++ Random Zahlen / Koordinaten:

    @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    random_shuffle

    Das gibts seit C++17 nicht mehr. Nimm shuffle.

    Ah, danke. Wusste ich nicht, wir hängen bei C++11 fest.



  • @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    Hab in diesem neumodischen Dinges, diesem Internetz, Internet oder so das hier gefunden:
    random_shuffle

    Dann solltest du da aber auch rechts den Kommentar lesen - da steht sowas wie

    (deprecated in C++14)
    (removed in C++17)



  • @wob sagte in QT C++ Random Zahlen / Koordinaten:

    @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    Hab in diesem neumodischen Dinges, diesem Internetz, Internet oder so das hier gefunden:
    random_shuffle

    Dann solltest du da aber auch rechts den Kommentar lesen - da steht sowas wie

    (deprecated in C++14)
    (removed in C++17)

    Ich hab´s nur gefunden, nicht gelesen 😉 Bis gerade eben wusste ich nicht mal, dass es deprecated ist und ab C++17 nicht mehr zur Verfügung steht. Wollte durch meinen flapsigen Kommentar nur zum Ausdruck bringen, dass man, wenn man das Schlüsselwort schon kennt, auch mal selbst suchen kann. Das war an TE gerichtet.



  • @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    Ich hab´s nur gefunden, nicht gelesen 😉

    Ah, ich sehe, du hast ungefähr gleichzeitig wie ich geschrieben. Ich dachte, dein erster Kommentar wäre auch meinen Kommentar bezogen gewesen. War er offenbar nicht 🙂



  • @wob

    Viele Dinge die ich als C++ Anfänger noch nicht gesehen habe.
    Zeile 5 und 6 verstehe ich, dann 9 dann sozsagen nur das durchmischen aber warum am Ende nochmal rng? Kann mir aus der C++ doku gerade nichts sinnvolles zusammenreimen.
    Aber wird die rnd Zahl jetzt in rng gespeichert?



  • @karooooo1234
    Die shuffle() Funktion braucht noch einen RNG, um Zufallszahlen für´s Mischen zu ziehen. Sie erzeugt selbst keinen, sondern erwartet, dass der Aufrufer den RNG als Parameter übergibt. Die Zufallszahl wird nicht in rng gespeichert, sondern rng wird benutzt, um die nächste Zufallszahl zu erzeugen.



  • Wie speichere ich dann die Zufallszahl in einer varibalen? Ziehe ich mir einfach raus mit
    int index = v[rng]?
    Irgendwie checke ich es einfach nicht. Langer Tag..



  • eigentlich kann ich mit bei v[1] ja dann irgendeine stelle ausgeben lassen oder?



  • @karooooo1234
    Nein, das macht shuffle für dich. Nehmen wir mal wob´s Code:

    // globaler Generator
    std::mt19937 rng(std::random_device{}());
    
    // globaler vector 
    std::vector<int> v;
    
    void start_cycle()
    {
       v.resize( 100 );
       std::iota(begin(v), end(v), 0);
       
       // durchmischen
       std::shuffle(begin(v), end(v), rng);
    }
    
    // der vector enthält jetzt alle Zahlen von 0-99 in zufälliger Reihenfolge.
    void fire()
    {
       if( v.empty() )
       {
          // der Vektor ist leer -> neuen Zyklus beginnen
          start_cycle( v );
       }
       // erstes Element benutzen
       int val = v.front();
       v.erase( v.begin() );
    
       // oder letztes Element benutzen
       int val = v.back();
       v.erase( v.rbegin() );
    
       // tu was mit val
    }
    

    Jetzt solltest du nur noch zusehen, dass du die globalen Variablen loswirst.


  • Mod

    vector::pop_back anyone? Und es gibt bestimmt einen Grund, wieso vector nur pop_back kennt, und nicht, wie manche andere Container, pop_front



  • @DocShoe sagte in QT C++ Random Zahlen / Koordinaten:

    Jetzt solltest du nur noch zusehen, dass du die globalen Variablen loswirst.

    Vielleicht mit einer Klasse?

    struct FirepointGenerator {
        FirepointGenerator(size_t n_fields) :
            v(n_fields),
            current_pos(end(v))
        {
            std::iota(begin(v), end(v), 0);
        }
    
        template <typename URBG>
        int next(URBG &rbg) {
            if (current_pos == end(v)) {
                std::shuffle(begin(v), end(v), rbg);
                current_pos = begin(v);        
            }
            return *current_pos++;
        }
    
    private:
        std::vector<size_t> v;
        std::vector<size_t>::const_iterator current_pos;
    }
    
    int main() {
        std::mt19937 rng(std::random_device{}());
        FirepointGenerator fpg(10);
        for (int i = 0; i < 25; ++i) cout << fpg.next(rng) << " ";
    }
    


  • @wob

    Ja, vielleicht. Ich wollte TE jetzt nicht alles auf´m Silbertablett servieren.
    Du solltest noch´n Test auf n_fields > 0 machen.



  • #include <random>
    
    std::random_device random_device;
    std::uniform_int_distribution<> uniform_int_distribution(min, max);
    int random_number = uniform_int_distribution(random_device);
    


  • Ich hab sowas: (?)

    	template <typename T> T createRandomReal(const T begin, const T end)
    	{
    		std::random_device rd;
    		std::mt19937 gen(rd());
    		std::uniform_real_distribution<T> rnd(begin, end);
    		return rnd(gen);
    	}
    
    	template <typename T> T createRandomInt(const T begin, const T end)
    	{
    		std::random_device rd;
    		std::mt19937 gen(rd());
    		std::uniform_int_distribution<T> rnd(begin, end);
    		return rnd(gen);
    	}
    


  • @zeropage Ständig neue random devices und -generators zu erzeugen ist sicher nicht die feine Englische Art.


Log in to reply