PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zufallsgenerator



modtronic
23.09.2014, 21:54
Guten Abend

Ein Freund und Ich wollen ein Brettspiel elektronisch nachbauen.
Es handelt sich um die Spanische Versions von Mensch Ärgere Dich nicht.

Ich habe eine kurze frage wie ich in C einen Zufallsgenerator programmieren kann.
Und zwar gedacht für den Würfel.

Als Würfel ist ein Kreis aus 6 Leds gedacht und nach Ende des Würfelzykluses soll das Ergebniss noch auf einer 7-Segmentanzeige erscheinen. Starten soll man das ganze über einen Taster.

Mir geht es jetzt hier allerdings um den Programmzyklus für die Zufallschleife des eigentlichen Würfels so das immer wieder andere Zahlen ausgegen werden.

Gruss
Patrick

Che Guevara
23.09.2014, 22:18
Hi,

also da gibts mehrere Möglichkeiten.
Zum einen könntest du dir bewusst an einem ADC-Pin Störungen einfangen, um diese als "Zufall" zu verwenden.
Oder du misst die Zeit des Tastendrucks und nimmst diesen Wert als Zufall.
Natürlich gibts wohl noch einige andere Möglichkeiten, diese beiden sind mir eben gerade eingefallen.

Gruß
Chris

schorsch_76
24.09.2014, 06:46
Pseudo RNG [1] .... Als seed anfangs die Zeit zwischen einem tastendrock oder ähnliches nehmen. [2] scheint auf µC's umsetzbar zu sein.

[1] http://de.wikipedia.org/wiki/Kategorie:Pseudozufallszahlengenerator
[2] http://de.wikipedia.org/wiki/KISS_(Zufallszahlengenerator)

modtronic
24.09.2014, 17:39
mit diesen aussagen kann ich irgendwie nix anfangen

schorsch_76
24.09.2014, 17:56
#include <stdint.h>

// interner Zustand
static uint32_t x = 123456789; // <- beliebige seed != 0
static uint32_t y = 362436000;
static uint32_t z = 521288629;
static uint32_t c = 7654321;

uint32_t KISS() {
uint64_t t;

// Linearer Kongruenzgenerator
x = 69069 * x + 12345;

// Xorshift
y ^= y << 13;
y ^= y >> 17;
y ^= y << 5;

// Multiply-with-carry
t = 698769069ULL * z + c;
c = t >> 32;
z = (uint32_t) t;

return x + y + z;
}


Das ist dein Zufallszahlengeneratur.

static uint32_t x = 123456789; // <- beliebige seed != 0

Das ist dein seed. Der "Samen" des Zufalls. Ist dieser Wert immer gleich, kommt immer dieselbe Reihe an Zahlen raus. Ergo, addiere einfach eine Zeit aus einem Timer beim Start des Spieles drauf... aber nur einmalig.

Besserwessi
24.09.2014, 21:15
Der Pseudozufallsgenerator von schorsch_76 wäre eine Möglichkeit.

Eine andere Möglichkeit wäre so etwas wie ein echter "Zufall", etwa über die Zeitmessung, etwa für die Zeit wann die Taste zum würfeln gedrückt wird. Je nach µC geht das sehr einfach: wenn der µC einen Timer mit Capture funktion hat, kann man den Timer direkt und schnell bis 5 Zählen lassen, und die Capture funktion scharf stellen. Bei jeder Flanke bekommt man dann einen Quasi zufälligen Wert von 0-5 im Capture Register - nach jeder Taste hat man da also einen neuen Wert.

Durch das Zählen nur bis 5 spart man sich die ggf. etwas trickreiche Umrechung in den Bereich 1-6.

Klebwax
24.09.2014, 22:55
Es ist ja nicht das erste Mal, das ein random number generator in C gebraucht wird: da hilft dann, wie in C üblich, die man-page (http://linux.die.net/man/3/rand). Um die ganze Sache nicht zu langweilig zu machen, sollte man den seed mit etwas Zufall versehen: die Zeit bis zum ersten Tastendruck, einen offenen ADC Eingang oder so.

MfG Klebwax

021aet04
28.09.2014, 12:40
Wenn man es aufwändiger will kann man auch einen Chaosgenerator nutzen. Den Ausgang des Chaosgenerators verbindet man mit dem Analogeingang des Controllers.

MfG Hannes