Warscheinlichkeit/Zufallszahlen



  • Hallo,
    ich bin C-Anfänger und bin gerade dabei mit allen möglichen Funktionen etc. rumzuspielen. Als Übungszwecke möchte ich ein kleines Programm schreiben das ein Fußballspiel simuliert.
    Zur Zeit läuft ganz einfach eine Uhr von Minute 1 bist Minute 90 mit einer leichten Verzögerung ( Also 1 Spiele dauert ca. 2 Minuten) durch eine einfache for Schleife. Ich möchte jetzt das jede virtuelle Minute berechnet wird ob ein TEAM ein Tor schiesst oder nicht. Also ganz einfach gesagt ich möchte z.B. einstellen das TEAM A eine Chance von 20% hat ein Tor zu schiessen und das jede Minute. Wie kann ich das realisieren ? Müsste doch irgendwie mit RANDOM da was geben ?
    Bin wie gesagt noch Anfänger aber würde mich über Eure Hilfe freuen.

    Vielen Dank!



  • Hier mal mein bisheriger Code, mit dem ich noch nicht ganz so zufrieden bin. Bisher wird einfach ne Zufallszahl zwischen 0 und 20 hergeholt. Team A hat ne Feste Zahl dazwischen und Team B hate eine feste Zahl. Wird nun einer der beiden Zahlen "gezogen" bekommt ein Team ein Tor. Vom Prinzip funzt das ja schonma, aber kann man das nicht noch irgendwie verfeinern ? Ich will später nochmal variable Stärken der Teams einbauen etc.!

    #include <stdio.h>
    #include <stdlib.h>
    
    #define  DELAY        200000000  
    
    int tor1=0,tor2=0;
    
    void zufall() {
    
    	int zufallsszahl = (int)rand()%21;
    	if (zufallsszahl==0)tor1=tor1++;
    	if (zufallsszahl==10)tor2=tor2++;
    
    }
    
    main(){
    
    	int warten,x;
    
    	for(x=1;x<=90;x++){
    	printf("\n%d. Minute\n", x);
    	printf("VfB - FCB : %d - %d\n", tor1, tor2);
    	zufall();
    	for( warten = 0 ; warten < DELAY ; ++warten)
    			;
    	system("cls");
    	}
    
    }
    


  • Meinst du so etwas?

    if(Zufallszahl % 5 == 1)
        ...
    
    for( warten = 0 ; warten < DELAY ; ++warten) 
                ;
    

    Kannst du durch Sleep() ersetzen, als Funktionswert muss die zu wartende Zeit (inms) angegeben werden.

    Sleep(2000);//wartet 2 Sekunden
    


  • Harvey schrieb:

    if (zufallsszahl==0)tor1=tor1++;
    	if (zufallsszahl==10)tor2=tor2++;
    

    Hier hast du eine Zuweisung zuviel, stört nicht, aber trotzdem zuviel.
    Der ++ Operator erhöht die Variable selbst, er liefert nicht nur den um eins erhöhten Wert zurück. Es reicht also tor1++ zu schreiben.

    Gruß
    Entyl Sa



  • Hallo,

    Entyl_Sa schrieb:

    Hier hast du eine Zuweisung zuviel, stört nicht, aber trotzdem zuviel.

    doch, das stört schon, denn das liefert ein "unvorhersehbares Ergebnis" auf der linken Seite.

    MfG



  • Probe-Nutzer schrieb:

    doch, das stört schon, denn das liefert ein "unvorhersehbares Ergebnis" auf der linken Seite.

    Im Fall das du recht hast könntest du mir noch verraten warum. 😕

    i=i++
    //hier wird meiner Meinung erst die Zuweisung ausgeführt
    i=i;
    //dann i erhöht;
    i++
    

    Sorry, das wir gerade das Topic verwerfen.

    Gruß
    Entyl Sa



  • Ja, deiner Meinung nach. Da wird eine Variable zwei mal modifiziert, ohne daß ein Sequenzpunkt dazwischenliegt. Das ist undefiniert.



  • kurz und gut gesagt, je nach Compiler bzw. Implementation kann der Ausdruck anders behandelt werden, weil in diesem Ausdruck keine vom Standard festgelegten "sequence points" vorhanden sind, erst mit dem Erreichen des Semikolons müssen die "Seiteneffekte" wirklich stattgefunden haben, denn dort ist ein "sequence point" im Standard festgelegt. Man kann deswegen auf keinen Fall diese Anweisung in irgendwelche Schritte zerlegen.

    MfG



  • noch ein Link zu dem Thema, in dem noch mehrere ähnliche Fälle (die vielleicht "bekannter" sind) diskutiert werden, unter "Section 3. Expressions":

    http://www.faqs.org/faqs/C-faq/abridged/

    MfG



  • Hallo,

    also von Sequenzpoints habe ich bisher noch nichts gehört, muss ich doch gerade mal meinen Prof anmotzen, das der mich hier hat so auflaufen lassen. Habe aber mal nachgeguckt was es damit aufsich hat.

    Probe-Nutzer schrieb:

    Man kann deswegen auf keinen Fall diese Anweisung in irgendwelche Schritte zerlegen.

    Hier muß ich trotzdem wiedersprechen. Wenn das so wäre könnte ja kein Kompiler diese Anweisung übersetzen. Im bleibt ja nichts anderes übrig als sie in Schritte zu zerlegen die der Rechner auch ausführen kann. Wobei sich für mich die Frage stellt in welche Schritte sie zerlegt wird. Die einzigen sinvollen Schritte sind:

    ADDI $1,$2,zahl  | $1 = $2 + zahl    //zum incrementieren
    ADD $1,$2,$3     | $1 = $2 + $3      //zum schreiben in ein Register
    

    Wobei ich hier von einem MIPS R300 Instruction Set ausgehe, dürfte aber bei anderen Prozessoren nicht großartig anders aussehen.
    $0 = Zeroregister, immer Null.
    $1 = i

    Dann geschieht das entwerder in der Reihnfolge:

    ADD  $1, $1 ,$0
    ADDI $1, $1, 1
    

    oder:

    ADDI $1, $1, 1
    ADD  $1, $1 ,$0
    

    wobei beides zum gleichen Ergebnis führt.

    Nicht missverstehen, ich habe verstanden das der Standard sagt das diese Anweisung undefiniert ist.

    Gruß
    Entyl Sa



  • Entyl_Sa schrieb:

    Hier muß ich trotzdem wiedersprechen

    naja, das meinte ich natürlich nicht mit "den Schritten", es geht schließlich immer noch um "sequentielle Ausführung" von Programmen, ich habe nirgends von "Parallelisierung" der Anweisung gesprochen 😉

    mit den "Schritten" waren die "sequence points" (daher auch der Name, es geht um die Sequenz der Teilschritte, und daß erst nach einer bestimmten Sequenz die Seiten-Effekte abgeschlossen sein müssen, und da es "mittendrin" in dieser Anweisung keine gibt, haben wir das unspezifizierte Verhalten) gemeint....

    MfG



  • Entyl_Sa schrieb:

    Hier muß ich trotzdem wiedersprechen. Wenn das so wäre könnte ja kein Kompiler diese Anweisung übersetzen. Im bleibt ja nichts anderes übrig als sie in Schritte zu zerlegen die der Rechner auch ausführen kann.

    Natürlich zerlegt es der Compiler - er kann ja nicht zaubern.

    Dein ASM Code ist natürlich Blödsinn, weil es nicht darum geht wie man 2 Zahlen addiert, sondern WANN i erhöht wird. Und wenn du Pech hast, wird es so erhöht:

    j=i;
    i=j;
    j=j+1;

    wobei j ein temporärer Wert ist, der danach einfach wieder zerstört wird.



  • Shade Of Mine schrieb:

    Dein ASM Code ist natürlich Blödsinn, weil es nicht darum geht wie man 2 Zahlen addiert, sondern WANN i erhöht wird. Und wenn du Pech hast, wird es so erhöht:

    j=i;
    i=j;
    j=j+1;

    wobei j ein temporärer Wert ist, der danach einfach wieder zerstört wird.

    Das ist doch genau das was ich sagen möchte, es ist egal wann i erhöht wird, vor oder nach der Zuweisung.
    Blödsinnig wäre hier eine temporäre Variable zu erzeugen, ausser man wollte erst irgendwas auswerten, was ja aber nur die rechte Seite der Zuweisung sein könnte. Und wenn man das dann zuweist ist ja wieder alles in Ordung.
    Das die theoretische Möglichkeit besteht das der Kompiler sowas macht sehe ich ja ein, nur der logische Grund warum er sollte sehe ich nicht.



  • Edit: ***


Anmelden zum Antworten