Fehlerkorrektur von Oben: es ist nicht modolo 5, es ist modulo 6.
Druckbare Version
Fehlerkorrektur von Oben: es ist nicht modolo 5, es ist modulo 6.
"Zufälligere" Zahlen bekommt man, wenn man die Werte von einem offenen ADC-Eingang nimmt, das Rauschen ist doch qualitativ brauchbar.
Z.b. 8 Samples nehmen, jeweils das LSB und man hat ein sehr zufälliges Byte.
Man könnte auch einfach den Standard-Zahlen Generator mit dem ADC-Wert als Seed füttern, das liefert dann auch nicht mehr reproduzierbare Folgen, was hier ausreichen würde.
mfg
ok also ich poste einfach mal den c code, wichtig zu sagen ich habe den nicht geschrieben, sondern ein guter freund.
Idee war z.B. drei mal einen Taster zu drücken (für 3 würfel) und sich das ergebnis vom RP6 oder irgendwann von er Wand abzulesen.
Code:#include <stdio.h>
#include <stdlib.h> // include atoi funktion
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int rdev;
int one, five, six;
unsigned int seed;
unsigned int pool;
unsigned int dice;
unsigned int face;//würgelfläche
unsigned int hold;//threshhold hälfte des "pool" würfelzahl aufgerundet
if(argc == 2)//prgrammname übergeben und ein "echtes" Agrument /
pool = atoi(argv[1]);//charackter to integer/ anzahl des pools
else {
fprintf(stderr, "fuck you i'm a robot!\n");
return 1;
}
one = five = six = 0;
rdev = open("/dev/random", O_RDONLY);
if(rdev < 0) {
fprintf(stderr, "cannot open /dev/random\n");
return 1;
}
read(rdev, &seed, sizeof(seed));//übernimmt zufallszahl aus dev/random für die erste zahl
close(rdev);
for(dice=0; dice<pool; dice++) {
face = (int)( (float)(6) * (rand_r(&seed)) / (RAND_MAX + 1.0)) + 1;
printf("%i ", face);//zur kontrolle nochmal alle würfelergebnisse
switch(face) {
case 1:
one++;
break;
case 5:
five++;
break;
case 6:
six++;
break;
default:
break;
}
}
printf("[anzahl der 1er %i/anzahl der 6er %i]\n", one, six);
if(five+six == 1)
printf("you have one hit.\n");
else
printf("you have %i hits.\n", five+six);
hold = pool/2;
if(pool%2 == 1)
hold++;
if(one >= hold) {
if(five+six == 0)
printf("\n you have a critical glitch!!\n\n");
else
printf("you have a glitch!\n\n");
}
return 0;
}
Na so wird das wohl nichts, der RP6 hat doch kein Dateisystem. Und nur einen kleinen Mega32 ohne Bildschirm. Zeige deinem Freund mal die RP6-Doku. Warum machst du das eigentlich nicht selbst? Es ist doch dein RP6, oder?Zitat:
rdev = open("/dev/random", O_RDONLY);
if(rdev < 0) {
fprintf(stderr, "cannot open /dev/random\n");
return 1;
...
face = (int)( (float)(6) * (rand_r(&seed)) / (RAND_MAX + 1.0)) + 1;
printf("%i ", face);//zur kontrolle nochmal alle würfelergebnisse
}
Gruß
mic
oh ich glaube du hast mich falsch verstanden das ist der Orginalcode nachbauen für RP6 wollte ich das...
gruss
carlitoco
Aha, alles klar. Dann bau mal schön ;)
(
Wollte ich immer schon mal versuchen. Nicht spicken!)Code:// Einfaches Würfelprogramm für den RP6 mic 10.8.09
#include "RP6RobotBaseLib.h"
uint16_t zufall;
int main (void)
{
initRobotBase();
writeString_P("\nZum Würfeln linken Bumper drücken\n\n");
while (true)
{
while(zufall<7)
{
// ADC-Kanäle des RP6:
// ADC_ADC0, ADC_ADC1, ADC_LS_l, ADC_LS_R, ADC_BAT
// ADC_MCURRENT_L, ADC_MCURRENT_R (wohl nur bei laufenden Motoren sinnvoll)
// (ADC0 und ADC1 sind beim jungfräulichen RP6 nicht beschaltet)
zufall=readADC(ADC_ADC0);
zufall+=readADC(ADC_ADC1);
//...
}
while(zufall>6) zufall -=6;
while(!getBumperLeft());
mSleep(200);
writeInteger(zufall, 10);
writeChar('\n');
while(getBumperLeft());
mSleep(200);
}
return(0);
}
ha haha ich stecke noch in den kinderschuhen der RP6 programmierung ... also wird das mit dem großspurigen "selberbauen" noch dauern oder garnicht mehr gemacht. Da ich im bezug auf den RP6 "wichtigere" Projekte im Kopf habe.
:D
PS: ich dachte das wäre mal eben geschrieben...
@radbruch trotzdem danke für die mühe
gruss
Offene ADC kanäle sind keine besonders guten Zufallsgeneratoren. Gerade bei den ADC nach der sukezessiven Approximation kann es leicht passieren das die Wahrscheinlichkeit dafür, dass das LSB gesetzt ist deutlich von 50% abweicht.
Besser ist es in der Regel wenn man eine echte Zufallskomponente wie den ADC mit einer Pseudozufallszahl kombiniert. Die Pseudozufallszahl kann dann dafür sogen, das die Fehler der echten Zufallszahl bei den normalen Qualitätskriterien für Zufallszahlen nicht mehr auffallen. Selbst wenn z.B. der ADC an der Grenze ist (also z. B. immer 0 ausgibt) hat man immer noch die Pseudozufallszahlen.
Für meinen Taschenrechner habe ich mal ein Würfelprogramm geschrieben. Vorteil: man muss keine Taste drücken - das Programm läuft "endlos". Nachteil: Es wird immer die gleiche Ziffernfolge erzeugt (Ausnahme wäre: eine zweite Startzahl, evtl. Stunde und Minute nehmen). Ablauf etwa so:
Pi als Startwert (natürlich in floating point - macht ja der Taschenrechner sozusagen per default)
Addiere Merker auf Pi
Quadriere
Nimm nur den Nachkommaanteil
Nachkommaanteil Speichern im Merker und nochmal Pi drauf addieren - oder eine andere, krumme Zahl, jedenfalls nicht die eben berechnete Würfelzahl
Nachkommaanteil mit 7 multiplizieren
Nur Vorkommateil nehmen
Je nach Rundungsphilosophie entweder Null oder die Sieben entfernen
Zahl anschreiben
Freuen
Wie gesagt - es hängt alles an der Startbedingung. Die könnte man mit der Messung der Tastendrucklänge "zufällig" beeinflussen.
Viel Glück bei der Realisierung
Man muß dsa Rad nicht neu erfinden. Die Library zu GCC hat ein paar funktionen für Pseudozufallszahlen. So ähnlich die oberallgeier beschreiben hat, nur halt eine etwas andere Berechnungsmehtode und deutlich schneller, weil kein Floatingpoint, sondern Integer.