Funktionen mit einer ID versehen



  • Tach allerseits 😉

    Ich habe verschieden Funktionen (24 an der Zahl) und möchte diese irgendwie aufrufen können, wenn ich die ID irgendwie benutze...

    So sehen im Grunde alle meine Funktionen aus...

    void Noten::spieleC() {
    
    	soundEngine = createIrrKlangDevice();
    
    	soundFile = "C.mp3";
    
    	soundEngine->play2D(soundFile.c_str());
    
    	this->id = 1;
    }
    

    und der Aufruf:

    Noten note;
    
    				 if(note.getId() == 1) {
    					// rufe diese Funktion mit der ID 1 auf
    				 }
    

    Hat da jemand eine Idee wie das gehen kann?

    Gruß Zel 😉



  • Du könntest Funktionspointer in einer std::map speichern - wenn deine IDs fortlaufend sind, geht auch ein std::vector.

    Willst du für jeden Buchstaben eine eigene Funktion? Warum übergibst du nicht einfach den Buchstaben als Parameter?



  • daddy_felix schrieb:

    Willst du für jeden Buchstaben eine eigene Funktion? Warum übergibst du nicht einfach den Buchstaben als Parameter?

    void Noten::spieleNote(string name) {
    
    	soundEngine = createIrrKlangDevice();
    
    	soundFile = name;
    
    	soundEngine->play2D(soundFile.c_str());
    
    }
    

    und im Aufruf:

    string s1 = "C.mp3";
    note.spieleNote(s1);
    

    funktioniert auch sehr gut - jetzt muss ich ja meinen Vektor befüllen, meine Methode wäre jetzt sehr simpel:

    string s1 = "C.mp3";
    string s2 = "CisDes.mp3";
    // ...
    string s24 = "H1.mp3";
    
    vector.push_back(s1);
    vector.push_back(s2);
    // ...
    vector.push_back(s24);
    

    Gibts da ne schönere Variante oder geht das halt nur so?^^

    Zweite Frage dann:

    wie kann ich aus nem

    vector<string>
    

    nen zufällig gewählten string-wert rauspicken?^^

    Und schonmal vielen Dank für deine Idee mit dem übergebenen Parameter... (dass ich da auch nicht selbst drauf komme... 😡 ) 😃



  • Zel2491 schrieb:

    string s1 = "C.mp3";
    string s2 = "CisDes.mp3";
    // ...
    string s24 = "H1.mp3";
    
    vector.push_back(s1);
    vector.push_back(s2);
    // ...
    vector.push_back(s24);
    

    Gibts da ne schönere Variante oder geht das halt nur so?^^

    du kannst die strings direkt übergeben, ohne den Zwischenschritt 😉

    vector.push_back("C.mp3");
    

    Wenn sich die Dateien alle in einem Verzeichnis befinden, könntest du eventuell dieses Verzeichnis durchsuchen und alle mp3-Dateien hinzufügen. Allerdings kann ich dir nicht sagen, wie das genau geht. Google könnte helfen 😉

    Zel2491 schrieb:

    wie kann ich aus nem

    vector<string>
    

    nen zufällig gewählten string-wert rauspicken?

    Lass dir eine Zufallszahl im Bereich [0, vector.size()-1] berechnen.


  • Mod

    Zel2491 schrieb:

    funktioniert auch sehr gut - jetzt muss ich ja meinen Vektor befüllen, meine Methode wäre jetzt sehr simpel:

    string s1 = "C.mp3";
    string s2 = "CisDes.mp3";
    // ...
    string s24 = "H1.mp3";
    
    vector.push_back(s1);
    vector.push_back(s2);
    // ...
    vector.push_back(s24);
    

    Gibts da ne schönere Variante oder geht das halt nur so?^^

    In C++11 kannst du die Standardcontainer direkt initialisieren:

    vector<int> foo = {1,2,3,4};
    

    In C++98 kannst du aber immerhin schöner aufschreiben:

    char *values[]={"A.mp3", "B.mp3", "C.mp3"};
    vector<string> foo(values, values + sizeof(values)/sizeof(*values));
    

    Oder eine dritte Möglichkeit(falls man kein C++11 hat) ist, sich die Zuweisung schön in einer Bibliothek zu kapseln, gibt's schon fertig:
    http://www.boost.org/doc/libs/1_50_0/libs/assign/doc/index.html

    Zweite Frage dann:

    wie kann ich aus nem

    vector<string>
    

    nen zufällig gewählten string-wert rauspicken?^^

    Du nimmst eine zufällige Zahl zwischen 0 und dem maximalen Index und den zugehörigen Wert nimmst du dann.



  • char* buchstaben[] = {"C.mp3", "CisDes.mp3", "D.mp3", "DisEs.mp3", "E.mp3", "F.mp3",
    		"FisGes.mp3", "G.mp3", "GisAs.mp3", "A.mp3", "AisB.mp3", "H.mp3", "C1.mp3",
    		"CisDes1.mp3", "D1.mp3", "DisEs1.mp3", "E1.mp3", "F1.mp3", "FisGes1.mp3", "G1.mp3",
    		"GisAs1.mp3", "A1.mp3", "AisB1.mp3", "H1.mp3"};
    
    	vector<string> buchstabenVektor(buchstaben, buchstaben + sizeof(buchstaben) / sizeof(*buchstaben));
    
    	srand(time(NULL));
    
    	zufall = rand()%24;
    
    	note.spieleNote(buchstabenVektor.at(zufall));
    	Sleep(1000);
    	zufall = rand()%24;
    	note.spieleNote(buchstabenVektor.at(zufall));
    

    Klappt wunderbar 🙂 Vielen Dank 🙂

    Nur eine Frage hab ich noch:

    bei der rand()-Funktion hab ich im Internet beim Beispiel eines Würfels folgendes gefunden:

    srand(time(NULL));
    int zufall=rand()%6+1;
    

    Wieso nimmt der 6+1? Ein Würfel hat doch nur 6 Seiten? 😃 Und falls das doch Sinn macht - wieso nimmt er 6+1 und nicht direkt 7?^^ Und was hat in dem Fall das "%" zu bedeuten?

    Gruß Zel 😉



  • Weil irgendwas % 6 Ergebnisse von 0 - 5 bringt, ein Würfel aber die Werte 1 - 6 hat.



  • % ist der modulo operator
    das ist eine division wo aber der rest rauskommt und nicht das ergebnis der division

    9 / 3 = 3 Rest 0 (9%3 also = 0)
    9 / 5 = 1 Rest 4 (9%5 = 4)
    ...

    edit: haha erster, daddy



  • Zel2491 schrieb:

    Und was hat in dem Fall das "%" zu bedeuten?

    Das ist der "Modulo"-Operator. Der liefert den Rest einer ganzzahligen Division:

    24 % 5 = 4

    und da dieser Operator eine höhere Priorität als "+" hat, steht in dem Code auch nicht "+7". Wenn du "%6" anwendest, erhältst du Zahlen im Bereich [0,5]. Da steht noch "+1", weil der Autor den Bereich [1,6] haben möchte - dies entspricht dann exakt den Seiten eines Würfels.



  • Ah okay 😉 Schon wieder was gelernt 😛

    Direkte Frage wieder dazu^^

    Wenn ich einen Ton abspiele, möchte ich, dass der nächste Ton höher ist, als der vorherige

    sprich:

    24 Töne zur Auswahl

    wenn ich

    srand(time(NULL));
    	zufall = rand()%24;
    
    	note.spieleNote(buchstabenVektor.at(zufall));
    
    	Sleep(1000);
    
    	zufall = rand()%???; // von zufall - 24
    	note.spieleNote(buchstabenVektor.at(zufall));
    

    wie sage ich hier, dass er eine Zahl AB der vorherigen Zufallszahl wählen soll, also von zufall - 24 (wenn zufall = 13, zwischen 13 und 24)


  • Mod

    Och, das solltest du dir mit den genannten Mitteln eigentlich selber denken können. Ganz dicker Tipp: rand() % range + minimum gibt dir eine Zufallszahl zwischen minimum (inklusive) und minimum + range (exklusive). Den Rest schaffst du dann hoffentlich alleine. Denk aber auch mal nach, warum das so ist!



  • Ja, bedingt:

    srand(time(NULL));
    	zufall = rand() % sizeof(buchstabenVektor);
    
    	note.spieleNote(buchstabenVektor.at(zufall));
    
    	Sleep(1000);
    
    	srand(time(NULL)); // die zeile hatte ich vorher nicht
    	zufall = rand() % sizeof(buchstabenVektor) + zufall; // Hier Fehler
    	note.spieleNote(buchstabenVektor.at(zufall));
    

    Nur hat er noch die Möglichkeit, außerhalb des Vektors zu gelangen schätze ich mal, da er ab und zu nen Fehler auswirft und das Programm beendet - ich denk halt mal, dass er außerhalb der Grenzen des Vektors sucht, nix findet und abbricht.

    Edit: Denkfehler oder? Wenn ich beim ersten mal die 24 ziehe hat er ja nix mehr nach oben schätz ich mal^^ Also beim ersten mal die Grenze bei 23 ziehen schätze ich mal, oder?^^


  • Mod

    Alles falsch. Und hat auch nicht im geringsten mit den Antworten zu tun. Wo hast du das denn her? srand benutzt man so nicht. sizeof erst recht nicht. Der Fehler tritt auch bestimmt erst eine Zeile später aus, oder? Guck nochmal nach.

    Fehlerkorrekturen:
    1. Ansehen und verstehen, was srand genau macht, ggf. mal ein paar Beispiele angucken
    2. Oje. Da kann ich nicht helfen, außer dich auf ein Lehrbuch zu verweisen. sizeof hat bei einem Container gar nichts zu suchen und wenn du das anders denkst, dann musst du noch einmal die Grundlagen wiederholen.



  • SeppJ schrieb:

    In C++98 kannst du aber immerhin schöner aufschreiben:

    char *values[]={"A.mp3", "B.mp3", "C.mp3"};
    vector<string> foo(values, values + sizeof(values)/sizeof(*values));
    

    const-correctness? 😉



  • SeppJ schrieb:

    Alles falsch. Und hat auch nicht im geringsten mit den Antworten zu tun. Wo hast du das denn her? srand benutzt man so nicht. sizeof erst recht nicht. Der Fehler tritt auch bestimmt erst eine Zeile später aus, oder? Guck nochmal nach.

    Fehlerkorrekturen:
    1. Ansehen und verstehen, was srand genau macht, ggf. mal ein paar Beispiele angucken
    2. Oje. Da kann ich nicht helfen, außer dich auf ein Lehrbuch zu verweisen. sizeof hat bei einem Container gar nichts zu suchen und wenn du das anders denkst, dann musst du noch einmal die Grundlagen wiederholen.

    Ich hab mit srand noch nie gearbeitet - muss ich mich da nochmal einlesen.

    sizeof...haste Recht - ich verwechsel das iwie dauernd mit

    vector.size()
    

    -.-


  • Mod



  • Okay...falls ich jetzt nicht ganz falsch liege...

    int iMax = buchstabenVektor.size() - 1;
    
    	srand(static_cast<int>(time(NULL)));
    
    	assert(iMax - 0 < RAND_MAX);
    
    	zufall = rand() % iMax;
    
    	spieleNote(buchstabenVektor.at(zufall));
    
    	Sleep(1000);
    
    	zufall = rand() % iMax + zufall;
    
    	spieleNote(buchstabenVektor.at(zufall));
    

    Trotzdem kommt immer noch folgende Fehlermeldung - bzw. nicht immer, sondern ab und zu, ich schätze irgendwie, wenn er außerhalb des Vektors nach einer Zahl sucht...?

    http://www.file-upload.net/download-4651007/Fehlermeldung.png.html


  • Mod

    Wenn du Zahlen zwischen zufall und buchstabenVektor.size() suchst, wie groß ist dann der Bereich, aus dem die Zahlen kommen können?



  • Das ist das Ding...

    falls ich am Anfang die 23 ziehe, hab ich ja...gar keine Zahl mehr übrig 😃

    Dann muss ich meine Bedingung noch iwie ändern...^^

    zufall = rand() % iMax;
    
    // ...
    
    zufall = rand() % iMax + (zufall - 1);
    

    iMax = 23

    sagen wir mal, wir ziehen beim ersten Mal die 23 direkt, dann ergibt sich:

    zufall = 23 + 22 - also könnte er von 22 - 23 noch etwas ziehen, oder seh ich das falsch?



  • Ich verstehe zwar nicht was du meinst, aber falls du den Vektor beliebig durchmischen möchtest, kannst du das mit random_shuffle tun.

    #include <algorithm> // ganz oben im File
    
    // Benutzung:
    std::random_shuffle (buchstabenVektor.begin(), buchstabenVektor.end());
    // jetzt ist buchstabenVektor zufällig durchmischt
    


  • Nochmal:

    ich spiele zuerst einen zufälligen Ton ab aus meinem Vektor - in meinem Vektor befinden sich 24 Noten, also 0-23 zur Auswahl.

    Jetzt spiele ich zum ersten Mal einen Ton ab

    zufall = rand() % iMax;
    spieleNote(buchstabenVektor.at(zufall));
    

    jetzt möchte ich, dass der nächste Ton höher ist, als der schon gespielte - also muss ich dann die Ziehung eingrenzen - von der eben gezogenen Zahl bis zum Ende des Vektor.

    Wenn ich z.B. beim ersten Mal die 13 ziehe, will ich danach nur von 13 - 23 ziehen können. Von durchmischen hatte ich nie etwas erwähnt...

    Das Problem ist jetzt aber nur, dass er anscheinend außerhalb meines Vektors auch sucht, darum hatte ich es mit

    zufall = rand() % iMax + zufall;
    spieleNote(buchstabenVektor.at(zufall));
    

    probiert.

    Meiner Hoffnung nach wäre das, wenn wir beim Beispiel 13 bleiben:

    zufall = rand() % 23 + 13

    also zieht er jetzt von 13 - 23. Nur schmeißt er mir immer noch den Fehler (da hatte ich das Bild ja zu hochgeladen...)


Anmelden zum Antworten