Schleife mit unterschiedlichen random Werten

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hi,


    ich möchte einem Set von Variablen zufällige Werte zuweisen. Soweit so gut.
    new Bitterling[18];


    for(new i = 0; i < sizeof(Bitterling); i++)
    {
    Bitterling[i] = random(101) + 1;
    }


    Nun möchte ich aber sicherstellen, dass die Variablen nicht dieselben Werte zugewiesen bekommen! Jede Bitterling[x] Variable soll einen unterschiedlichen Wert zugewiesen bekommen. Wie stelle ich das am besten an, dass überprüft wird, ob die bereits gesetzten Werte mit dem gerade gesetzten Wert (also dem momentanen Iterator), nicht übereinstimmen?

  • for(new i = 0; i < sizeof(Bitterling); i++)
    {
    enter:
    new bool: found = false;
    for(new x = 0; x < sizeof(Bitterling); x++){
    if(Bitterling[x] == Bitterling[i]) found = true;
    }
    if(found == false){
    Bitterling[i] = random(101) + 1;
    }else{
    goto enter;
    }
    }


    Ungetestet aus dem Stehgreif. Müsste eigentlich funktionieren.
    Bin mir gerade unsicher, ob es nicht auch eleganter, als mit der goto Methode geht.


  • Das wird so nicht funktionieren. Wenn du in die 2. Schleife gehst, hat Bitterling[i] noch gar kein Wert bekommen und da steht 0.
    Wie folgt müsste deine Variante funktionieren(Ist aber meiner Meinung nach mit "goto" nicht zu empfehlen!!)
    for(new i = 0; i < sizeof(Bitterling); i++)
    {
    enter:
    new bool: found = false;
    Bitterling[i] = random(101) + 1;
    for(new x = 0; x < i; x++)
    {
    if(Bitterling[x] == Bitterling[i]) found = true;
    }
    if(found == true)
    {
    goto enter;
    }
    }


    Anstatt mit goto würde ich es auch mit einer While Schleife machen.

    for(new i = 0; i < sizeof(Bitterling); i++)
    {
    new bool: found = false;
    do
    {
    found = false;
    Bitterling[i] = random(101) + 1;
    for(new x = 0; x < i; x++)
    {
    if(Bitterling[x] == Bitterling[i]) found = true;
    }
    } while(found != false)
    }

    //edit: ich bin mir nur gerade über die genau Syntax einer d while Schleife in pawn nicht mehr bewusst :D

    2 Mal editiert, zuletzt von [COE]CodeX ()

  • Ich frag mich die ganze zeit schon, ob die boolean Variable wirklich nötig ist...
    Würde diese Variante hier gehen? Wenn nicht, warum nicht?


    for(new i = 0; i < sizeof(Bitterling); i++)
    {
    Bitterling[i] = random(100);
    for(new j = 0; j < i; j++)
    {
    if(Bitterling[j] == Bitterling[i]) Bitterling[i] = random(100);
    }
    }

  • Also die Variante sollte gehen:

    new Bitterling[18];
    for(new i = 0; i < sizeof(Bitterling); i++) {
    Bitterling[i] = random(100) + 1;


    for(new l = 0; l < i; l++) {
    if(Bitterling[l] == Bitterling[i]) {
    i--;
    break;
    }
    }
    }


    Deine Variante hat das Problem das es zwar eine doppelte Zahl erkennt, das aber nur einmal!
    Sprich hast du bei deinem ersten Random eine Zahl die es schon gibt wird die erkannt, aber du überprüfst die Zahl des zweiten Random's nicht.


    // edit: Optimierung

  • Gehen wir mal ein Beispiel durch:


    Erster Durchgang:

    • Erste Schleife beginnt; i ist 0
    • Neuer Randomwert an der Stelle Bitterling[0] wird gesetzt
    • Zweite Schleife (irrelevant)


    Zweiter Durchgang:

    • Erste Schleife beginnt; i ist 1
    • Neuer Randomwert an der Stelle Bitterling[1] wird gesetzt
    • Zweite Schleife geht von 0 - 0
    • Zufällig ist der Wert von Bitterling[1] gleich mit dem von Bitterling[0]
    • i wird eins heruntergezählt: i ist 0


    Dritter Durchgang:

    • Erste Schleife beginnt; i ist 1
    • Neuer Randomwert an der Stelle Bitterling[1] wird gesetzt
    • usw.


    Das heißt gibt es den Wert schon wird einfach ein neuer Durchgang mit dem gleichen Index ausgeführt.

  • Wie wäre es mit einer for / While Konstruktion?


    Wozu?
    Die Variante von Silverdark ist doch völlig in Ordnung.


    Dafür müsstest du aber bestenfalls Bitterling global deklarieren


    Warum?
    So wie es jetzt ist, ist es völlig richtig

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski


  • Ah, ich verstehe.
    Anstatt eine Bedingung während dem Loop zu machen, lässt du also nach Übereinstimmung den "fehlerhaften" Iterator einfach nochmal laufen. Gutes work-around zu goto!^^
    Vielen Dank auch für deine Mühe mit dem Beispiel, hat mir sehr weiter geholfen. ;)