Es gibt keine Zufälle
Text wurde mit Genehmigung des Authors übernommen. Quelle: MitOhneHaare.de - Artikel "Es gibt keine Zufälle".
Zufallszahlen sind eine feine Sache und auch sehr einfach zu generieren. Die Random-Klasse des XNA-Framework liefert uns hier eine sehr gute Möglichkeit. Jedoch auch hier gibt es den ein oder anderen kleinen Fallstrick, der uns - wenn wir uns nicht mit der Materie befassen - das Leben schwer machen kann.
In diesem kleinen Artikel möchte ich ein paar Anmerkungen dazu machen und so eine Art Mini-Tutorial bereitstellen.
Das wichtigste erstmal vorweg:
Zufallszahlen sind nicht zufällig.
Zufallszahlen wirken lediglich zufällig, werden aber in Wirklichkeit von einem Algorithmus erzeugt. Dieser Algorithmus beginnt seine Arbeit bei einem Startwert, dem sogenannten Seed. Und damit kommen wir auch schon zur ersten Regel:
Gleicher Seed bedeutet gleiche Zahlenreihe.
Dies ist eine wichtige Erkenntnis, die durchaus nützlich sein kann. Wenn wir z.B. ein zufälliges Level generieren, dann können wir mittels des Seeds - ein Parameter des Konstruktors von Random - immer das gleiche Level erzeugen, wenn wir den gleichen Seed verwenden. In diesem Fall müssten wir nicht das gesamte Level speichern, sondern lediglich den Seed.
Der Standardwert für den Seed wird in der Regel aus der Systemzeit abgeleitet. Da diese selten exakt gleich ist zwischen zwei Programmausführungen, haben wir immer einen neuen Seed und damit eine neue "zufällige" Zahlenreihe.
Mit diesem Wissen ausgerüstet kommen wir nun aber auch direkt zum ersten Fallstrick und einer sehr einfachen Lösungsmöglichkeit. Sollten wir auf die Idee kommen, mehrere Zufallsgeneratoren kurz hintereinander zu erzeugen, so kann das Problem auftreten, daß dies so schnell geschieht, daß alle den gleichen Seed erhalten. In diesem Fall liefern alle natürlich auch die gleiche Zahlenreihe und damit die gleichen Zufallszahlen, die dann garnicht mehr zufällig aussehen. Es ist also wichtig, daß wir möglichst wenige Instanzen, am besten nur eine einzige, erzeugen, damit dieses Problem nicht auftritt.
Der letzte, wichtige Punkt ist, daß Zufallszahlen nicht normalverteilt sind. Sie sind auch nicht so verteilt, daß ein Mensch diese Zahlen als besonders zufällig wahrnimmt (also z.B. weißes Rauschen). Die Zufallszahlen sind schlicht und einfach zufällig (naja, nicht wirklich, siehe oben). Es kann also durchaus passieren, daß 10x die gleiche Zahl kommt bei zehn Aufrufen. Das ist halt so und manchmal nicht wirklich zielführend. Wenn der Computergegner bei einem Kartenspiel 10x hintereinander die Joker bekommt, dann entsteht schnell der Eindruck, das geschummelt wird. Wir müssen uns darum also selbst kümmern, wie auch immer das im konkreten Fall aussehen mag.
Zum Abschluss noch der obligatorische Link auf die MSDN mit der Doku für die Random-Klasse.