kompakter programmieren mit Arrays?



  • Also das hier ist ein kleiner Auszug aus einem Roulette Programm.
    Nach Feststellen der Array Größe, wir für jede einzelne Setzmöglichkeit
    (für Schwarz, für Rot, für Gerade für ungerade, für....) eine eigene For-Schleife aufgerufen, die die Elemente einzeln durchgeht (und auf der Konsole ausgibt).

    PROBLEM ist jetzt, wenn ich später sagen will, die Zufallszahl war z.B. "14", durchsuche alle Arrays, ob die Zahl 14 vorkommt, wie vermeide ich die ganzen For-Schleifen (// Auflisten aller Chancen die in Frage kommen) und wie könnte ich mit einer Doppelschleife oder sonstigen Tricks den Code verkürzen? Vektoren vielleicht?
    Ich weiß, ich kann Gerade und ungerade mit einer Formel berechnen lassen, aber
    um die massenhaft Schleifen komme ich damit auch nicht rum.
    Wie kann man das anders lösen?

    Danke für die Mühe im voraus!

    int Schwarz   [] = {1,3,5,7,9,12,14,16,18,19,21,23,25, 27,30,32,34,36};
        int Rot       [] = {2,4,6,8,10,11,13,15,17,20,22,24,26,28,29,31,33,35};
        int Gerade    [] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36};
        int Ungerade  [] = {1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35};    
        int Manque    [] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
        int Passe     [] = {19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36};
    
    //erst mal Groesse des Arrays feststellen
    int GroesseSchwarz = sizeof(Schwarz)/sizeof(Schwarz[0]); cout<<"groesse von Schwarz: "<< GroesseSchwarz <<"\n";
    
    int GroesseRot = sizeof(Rot)/sizeof(Rot[0]); cout<<"groesse von Rot: "<< GroesseRot <<"\n";
    
    // Auflisten aller Chancen die in Frage kommen
    cout << "Schwarz: ";
            for (int ch = 0; ch < GroesseSchwarz; ch=ch+1) 
        {
                cout << Schwarz[ch] << ", ";
        }
    cout << endl;
    
    cout << "Rot: ";
            for (int ch = 0; ch < GroesseRot; ch=ch+1) 
        {
                cout << Rot[ch] << ", ";
        }
    cout << endl;
    
    .
    .
    ....usw.
    


  • -> sind denn die zahlen beim roulette nicht immer an der selben position?
    -> warum ermittelst du die grösse des array zur laufzeit, wenn diese doch fix ist?
    -> als programmierer weisst du doch wo die 14 drin steht, d.h.
    -> 14 ist gerade und kommt nur in Schwarz, Gerade und Manque
    -> damit braucht du nur diese 3 Array zu durchsuchen

    besser ist natürlich nur ein Array zu nehmen (von 1-36) und dort für jede zahl so eine art zugehörigkeitsflag zu setzen. wenn du dann deine zahl hast, greifst du mit dieser als index einfach auf das array zu und wertest das enthaltene flag aus. damit weist du, wo die zahl dazu gehört. und hast nicht mal eine schleife benötigt!

    könnte mir das in etwa so vorstellen...

    // mögliche Flags
    #define ROULETTE_BLACK  0x01
    #define ROULETTE_RED    0x02
    #define ROULETTE_EVEN   0x04
    #define ROULETTE_ODD    0x08
    #define ROULETTE_PASSE  0x10
    #define ROULETTE_MANQUE 0x20
    
    int Zahlen[36] = { ROULETTE_BLACK | ROULETTE_ODD | ROULETTE_MANQUE,  // 1 
                       ROULETTE_RED   | ROULETTE_ODD | ROULETTE_MANQUE,  // 2
                       ... // usw. fuer den Rest
    
    // Zugriff dann
    int zahl  = 14;
    int flags = Zahlen[Zahl - 1]; // Index beginnt bei 0, daher noch -1 
    
    // Zahl ist schwarz
    if (flags & ROULETTE_BLACK)
    ...
    
    // Zahl ist rot
    if (flags & ROULETTE_RED) 
    ...
    


  • Danke für die ausführliche Antwort!
    Hmm, warum hab ich mich mal wieder auf die aufwendigere Roulettezahlen-Darstellung verlegt. Deinen Ansatzz, daß man eher Werte der jeweiligen Zahl zuordnen sollte als andersrum, so wie ich hatte ich auch schon mal, aber leider wieder verworfen.
    Ich find aber Deine Methode besser. Vor Allem mit den Flags.

    Es gibt nur zwei Sachen mit denen ich irgendwie nichts anfangen kann:
    Was bedeuten die
    0x01
    0x02
    0x04
    0x08
    0x10
    0x20
    hinter dem #define Befehl? Mit #define wird doch ein konstanter Ausdruck festgelegt? Ist das der dafür reservierte Speicherplatz?

    und bei DEM Ausdruck

    int Zahlen[36] = { ROULETTE_BLACK | ROULETTE_ODD | ROULETTE_MANQUE,  // 1 
                       ROULETTE_RED   | ROULETTE_ODD | ROULETTE_MANQUE,  // 2 
                       ... // usw. fuer den Rest
    

    kenn ich z.B. nicht das Pipe | Zeichen. Was bewirkt das hier?
    Denn bei zweidimensionalen Arrays wird das ja anders aufgelistet...

    xyz = {{RB, RO, RM}, {RD, RO, RM}}...
    

    und wenn ichs dann richtig verstanden habe, braucht man ja zumindest so viele IF-Abfragen wie es Setzmöglichkeiten gibt, also ein IF für Schwarz, für Rot, für Gerade usw., stimmts? Naja das KANN man eben nicht vereinfachen, klar.

    Aber der Ansatz ist gut, ich versuch mal was draus zu machen (sofern ich das | Zeichen verstehe...

    Soweit ichs verstanden habe:

    wenn die Zahl, die vom Zufallsgenerator erzeugt wurde z.B. die 14 ist, wird der 14. Wert (14-1) im Array "Zahlen" aufgerufen, bei dem dann z.B. die Flags stehen: die Zahl 14 ist Schwarz, Gerade, und Manque usw.

    nur was soll dann bei dem

    if (flags & ROULETTE_BLACK)
    

    rauskommen?
    Wenn die Bedingung flags erfüllt ist (also der 14. Wert im Array Zahlen gefunden ist) und zugleich Roulette_BLACK erfüllt ist (also wenn die Zahl schwarz ist, dann soll WAS passieren?

    Ich dachte das Roulette_Black ist überflüssig, weil ich durch das Flag schon an der richtigen Stelle im Array Zahlen bin und dort schon steht, daß
    die Zahl ja schwarz ist?

    Wo ist mein Denkfehler?

    Ansonsten finde ich DEN Ansatz wie gesagt verfolgenswert besser, danke!


  • Mod

    Hallo

    Mit #define wird doch ein konstanter Ausdruck festgelegt?

    😕 😞 😮

    schau mal bitte nach was #define bedeutet 🙄

    und mit 0x01/0x02/0x04 ..... sind die einzelnen Bits gemeint
    (schau dir das mal binaer an)

    | == oder

    Das schreit doch ein bischen nach Grundlagen oder 😃

    MfG
    Klaus



  • Stimmt, es schreit. Gibt noch einiges nachzuholen.
    Inzwischen hab ich mich auch ein wenig schlauer gemacht. Wenn auch das Wissen, daß "| = oder" heißt nicht gleich zum Aha-Erlebnis geführt hat.
    Wollte nur diesen guten Ansatz komplett richtig verstehen und nicht einfach so drüberhudeln , nach dem Motto, danke, jetzt weiß ich wies geht und das wars.
    Im Gegenteil!



  • Hi,

    ich wollte noch anmerken, daß überhaupt keine Notwendigkeit besteht, die Konstanten über Präprozessor-Direktiven zu definieren.
    Also weg mit dem Faustkeil und her mit einem Aufzählungstyp!



  • #define ROULETTE_BLACK  0x01  // 0x01 (hex) ==  1 (dezimal)
    #define ROULETTE_RED    0x02  // 0x02 (hex) ==  2 (dezimal) 
    #define ROULETTE_EVEN   0x04  // 0x04 (hex) ==  4 (dezimal)
    #define ROULETTE_ODD    0x08  // 0x08 (hex) ==  8 (dezimal)
    #define ROULETTE_PASSE  0x10  // 0x10 (hex) == 16 (dezimal)
    #define ROULETTE_MANQUE 0x20  // 0x20 (hex) == 32 (dezimal)
    

    mit dem | bewirkst du eine logische oder verknüpfung der werte, d.h. jedes
    gesetzte bit ist auch im ergebnis gesetzt. siehe tabelle

    | | 0 | 1
    ---+---+---
     0 | 0 | 1
     1 | 1 | 1
    
    -> zahl 1  == ROULETTE_BLACK | ROULETTE_ODD | ROULETTE_MANQUE
               ==        1  |         8  |        32
               == 00000001  |  00001000  |  00100000
               == 00101001
    

    mit

    if (Flag & ROULETTE_BLACK)
    

    wertes du dann aus, welches bit gesetzt ist. die und-verknüpfung liefert 1
    wenn ein bit an beiden stellen gesetzt ist, sonst 0. siehe tabelle.

    & | 0 | 1
    ---+---+---
     0 | 0 | 0
     1 | 0 | 1
    

    was genau du mit den zufallszahlen machen willst, weiss ich ja nicht. wenn du mit der zufallszahl das array abfragst, weisst du noch nicht ob die zahl schwarz/rot, gerade/ungerade, passe/manque ist, dass bekommst du erst durch die auswertung der flags heraus.



  • Na DAS ist ja klasse, eine ausführliche Erklärung!
    Vielen Dank, damit werde ich jetzt mal ein wenig basteln, hoffe, es kommt was brauchbares raus!



  • Zitat:

    Also weg mit dem Faustkeil und her mit einem Aufzählungstyp!

    ALso einen VOrteil könnte es haben: Geschwindigkeit, nur könntest Du Recht haben, in dem Fall sinds so wenig Daten, daß es mit Aufzählung wohl auch gehen müßte!?


Anmelden zum Antworten