PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hat einer von euch nen Würfelprgramm geschrieben?



carlitoco
07.08.2009, 01:25
Ich würd da gern mal eines ausprobieren bzw. bauen.

ideen ? danke erstmal gruss carlitoco

Thomas$
07.08.2009, 06:06
ich kenn den rp6 zwar nicht. aber das müsstest du selber hinbekommen können wenn du mal nach "rnd" basic oder "rand" c da dürftest du fündig werden.

carlitoco
07.08.2009, 15:08
in C habe ich eines aber das sind ja die standart c libs die ich im RP6 code nicht habe.

radbruch
07.08.2009, 20:59
in C habe ich einesDann sollten wir das einfach an den RP6 anpassen. Die Hürde dürfte die Zufallszahl sein.

s.o.
07.08.2009, 21:18
Wie wärs so: Timer rennen lassen (möglichst schnell), bei Tastendruck timerwert bilden, modulo von 5 bilden und eins addieren...

Besserwessi
07.08.2009, 21:47
Mit dem einfache modulo sollte man vorsichtig sein, wenn man gute Zufallszahlen haben will. Wenn man als Ausgangswert z.B. 8 Bits hat, also Werte von 0 bis 255, bekommt man für 0 und 255 modulo 5 eine 0. Damit hat man genau einmal eine 0 zu viel. Die 0 kommt damit häufiger vor als alle anderen Zahlen. Wenn man es in diesem Beispiel besser machen will, sollte man in einigen Fällen die Zahl verwerfen und sich eine neue Zufallszahl besorgen. In diesem Beispiel also z.B. den Fall 255 verwerfen. Wenn man dabei auf einen Tastendruck angewiesen ist, hat man natürlich ein Problem.

radbruch
07.08.2009, 22:09
Irgendwie kam mir das Thema bekannt vor:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=45788

carlitoco
07.08.2009, 23:34
Also ich dachte an einen 6 er Würfel wo er mir beispielsweise am LCD das Ergebnis ausgiebt.

carlitoco
08.08.2009, 00:24
habe mir mal ein paar C würfel programme angeschaut und festgestellt das die alle mit der tollen Funktion "rand()" arbeiten :(
ich muss mir ja den Zufallsgenerator selber basteln. . . oder ?

gruss

recycle
08.08.2009, 04:31
ich muss mir ja den Zufallsgenerator selber basteln. . . oder

Lies doch einfach mal die Antworten die du weiter oben schon bekommen hast.
Da wurde dir doch bereits der Vorschlag gemacht dir deine Zufallszahlen mit einem Timer zu erzeugen.

s.o.
08.08.2009, 05:29
Fehlerkorrektur von Oben: es ist nicht modolo 5, es ist modulo 6.

Netzman
08.08.2009, 08:10
"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

carlitoco
10.08.2009, 19:05
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.



#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;
}

radbruch
10.08.2009, 19:18
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

}
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?

Gruß

mic

carlitoco
10.08.2009, 19:45
oh ich glaube du hast mich falsch verstanden das ist der Orginalcode nachbauen für RP6 wollte ich das...

gruss
carlitoco

radbruch
10.08.2009, 20:48
Aha, alles klar. Dann bau mal schön ;)

(
Wollte ich immer schon mal versuchen. Nicht spicken!
// 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);
})

carlitoco
15.08.2009, 15:19
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

Besserwessi
15.08.2009, 19:50
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.

oberallgeier
15.08.2009, 21:09
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

Besserwessi
15.08.2009, 22:24
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.

carlitoco
18.08.2009, 19:17
Danke für den nicht Spicken hinweiss !
Sorry das ich nicht an mich halten konnte...


// Einfaches Würfelprogramm für den RP6 mic 10.8.09

#include "RP6RobotBaseLib.h"

uint16_t zufall;

int main (void)
{
initRobotBase();

writeString_P("\nZum Wuerfeln linken Bumper druecken\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());
if (zufall>=5)
setLEDs(0b111111);
else if
(zufall>=2)
{
setLEDs(0b000000);
}
else if
(zufall>=1)
{
setLEDs(0b000001);
}

/*
switch (zufall)
{
case 1: {(zufall=1);
setLEDs(0b000001);}
case 2: {(zufall=2);
setLEDs(0b000011);}
case 3: {(zufall=3);
setLEDs(0b000111);}
case 4: {(zufall=4);
setLEDs(0b001111);}
case 5: {(zufall=5);
setLEDs(0b011111);}
case 6: {(zufall=6);
setLEDs(0b111111);}
}*/
mSleep(200);
writeInteger(zufall, 10);
writeString_P("\n___\n\n");
writeChar('\n');
while(getBumperLeft());
mSleep(200);
}
return(0);
}

die LEDs übernehmen die ausgabe der erfolge / misserfolge
gruss