FreeBasic: Zufall

Aus Wikibooks
Zur Navigation springen Zur Suche springen

Der Zufall[Bearbeiten]

Ein zufälliges Ereignis ist nicht vorhersehbar, wie zum Beispiel der Wurf einer Münze. Im Mittel landen 50% der geworfenen Münze auf der "Kopf"-Seite, die anderen 50% auf der "Zahl"-Seite. Eine genaue Vorhersage des nächsten Wurfes ist allerdings nicht möglich.

Zufallsfunktion in FreeBASIC[Bearbeiten]

FreeBASICs Funktion Rnd gibt eine Fließkommazahl größer/gleich 0 und kleiner 1 zurück. Diese Zahl ist pseudozufällig, da sich mit einem Computer keine echten Zufallszahlen erzeugen lassen. Das erreichte Maß an Zufälligkeit ist für Computerspiele etc. allerdings ausreichend.

Um Integerwerte ausserhalb des Bereiches von 0 bis ausschließlich 1 zu erhalten, wird der Rnd-Wert einfach mit der größten gewünschten Zahl plus 1 multipliziert. Int(Rnd*10) liefert also Integerwerte von 0 bis 9. Da bei jedem Start jeweils die gleiche Reihe Zufallszahlen verwendet wird (man spricht von der sogenannten Seed), sollte die Zufallszahlenfunktion Randomize mit jeweils einem anderen Wert initialisiert werden. Es bietet sich an, randomize timer zu verwenden, damit die Zufallszahlen bei jedem Programmstart variieren.

Beispiel[Bearbeiten]

randomize timer
 
dim a as integer
dim b as integer
 
input "Wie viele Zufallszahlen?", a
 
for b = 1 to a
   print int(rnd * 10) 'Zufallszahl von 0 bis 9.
next
 
sleep

Minimum[Bearbeiten]

So das Maximum ist jetzt einstellbar. Aber was wenn man Zahlen von 5-14 haben möchte?

randomize timer
 
dim a as integer
dim b as integer
 
input "Wie viele Zufallszahlen?", a
 
for b = 1 to a
   print int(5 + rnd * 10) 'Zufallszahl von 5 bis 14.
next
 
sleep

Wie man sieht verschiebt sich durch das +5 der Wertebereich von 0-9 zu 5-14. Wenn man das int() weglässt bekommt man den gleichen Wertebereich nur eben mit Kommazahlen.

Eine Hilfsfunktion[Bearbeiten]

Da man auf die Art oben viel nachdenken muss wäre eine Hilfsfunktion gut:

declare function RandInt(byval min as integer, byval max as integer) as integer

function RandInt(byval min as integer, byval max as integer) as integer
  return int(min + rnd * (max-min))
end function

oder für Kommazahlen:

declare function RandFloat(byval min as double, byval max as double) as double

function RandFloat(byval min as double, byval max as double) as double
  return min + rnd * (max-min)
end function

Natürlich musst du trotzdem "randomize timer" am Programmanfang aufrufen sonst bekommst du jedes mal die gleichen Zahlen. Diese Hilfefunktionen kannst du gerne für eigene Projekte benutzten, wenn du sie brauchst.

Beispiel[Bearbeiten]

Beschreibung des Zufall Versuchs[Bearbeiten]

Die Zahl PI kennen viele noch aus der Schule. Sie beschreibt das Verhältnis zwischen Umfang und Durchmesser eines Kreises oder das Verhältnis zwischen Fläche und dem Quadrat des Radius eines Kreises. 3.1415 und so weiter, aber wer hätte gedacht, dass man diese wichtige Konstante, die schon auf viele Milliarden Nachkommastellen berechnet wurde auch mit reinem Zufall herausfinden kann? So ist es tatsächlich! Man zeichnet einen Kreis mit Radius 1 cm auf ein Blatt Papier. Nun zeichnet man das umgebende Quadrat des Kreises um den Kreis. Jetzt zeichnen wir noch ein Quadrat mit der Seitenlänge 1 cm und der unteren linken Ecke am Kreismittelpunkt und der oberen rechten Ecke an der oberen rechten Ecke des großen Quadrats. So, jetzt sehen wir einen Viertelkreis mit einem Quadrat, das die Grenze anzeigt. Wenn man jetzt zufällige Punkte in dieses kleine Quadrat setzt, ist das Verhältnis von den Punkten im Kreisviertel und der Punkte außerhalb des Kreisviertels im kleinen Quadrat, man glaubt es kaum, PI. Nun muss man sehr viele Punkte setzen, um ein genaues Ergebnis zu bekommen. Hier kommt Freebasic ins Spiel. Hier der Quelltext für das eben beschriebene Experiment:

randomize timer

dim as double pi = 0
dim as ulongint i = 0
dim as double x = rnd
dim as double y = rnd
dim as ulongint punkte
dim as ulongint g
input "Wie viele Punkte?",g
punkte = g
do 
    x = rnd
    y = rnd
    if x*x + y*y <= 1 then
        i = i+1
    end if
    punkte = punkte - 1
loop while punkte > 0

pi = 4*cast(double,(i)/(g))
print pi

sleep

Diese Art ist nicht sehr effektiv, PI herauszufinden, da man sehr lange braucht für 6 richtige Stellen. Aber das Beispiel verdeutlicht, dass mit FreeBasic sehr leicht Zufallsexperimente durchgeführt werden können. Bei zehn Punkten erhält man noch wage Zahlen wie 2.8 oder 3.2, bei größeren Zahlen wird das Ergebnis brauchbarer wie mit 1000 Punkten 3.16 oder 3.08, aber wer genaue Ergebnisse will, muss mindestens bei einer Millionen anfangen. Bei 100 Millionen merkt man spürbar, wie lang das Rechnen dauert. Deshalb wird diese Methode in der Praxis nicht so oft angewandt, da man Sekunden braucht für 3 Nachkommastellen. Wichtig: Bei Computern mit einem Prozessorkern kann eine solche Schleife den Computer einfrieren bis sie vorbei ist. Daher sollten Sie das Programm nie benutzen mit mehr als einer Millionen Punkten. Je nachdem wie schnell ihr Computer ist, sollten Sie in so einem Fall lieber ganz auf einen Test verzichten.