Hallo, mit inzwischen über 30 Jahren "Nerd-sein" hängt man sich ja auch ein paar bekloppte Sachen an die Wand. Wer den 70iger Jahre Film "Computer Code P1" gesehen hat weiss warum. Conways Game of Life läuft bei mir auf einer 24x32 Matrix mit 768 LEDs. Ebay Kracher mit 7219, wobei der noch ein Reset Problem hatte. Einfach an Spannung ist nicht, dann leuchten alle LEDS und nehmen keine Befehle an. Die Slew Rate muss größer sein, was ich durch dicke Elkos realisiert habe. Aktuell halte ich das System am Leben indem ich zufällige unsichtbare Zelle einstreue, jeweils 2 pro Generation. Dann hört das Ganze nie auf. Das führt leider auch zu unschönen Blitzern einzelner Zellen. "Zufall" wird durch die 32 Bit RTC erzeugt und gelegentliches srand(GetRTC) Ich würde noch gern erfassen wann ich eine statische Welt habe die sich nicht mehr ändert. Hat da jemand eine Idee? Statische Welten blinken aber durchaus und haben 2 oder mehr Zyklen. Nur #ndern sie sich nicht mehr. Christian
Die einzige Loesung, die mir dazu einfaellt: speicher so viele Generationen, wie in den RAM passen, in einem Ringpuffer, und vergleiche jede neue Generation mit den alten. Hast du einen Treffer, dann ist es zyklisch. Man koennte vielleicht noch einen Hash-Algorithmus einbauen und nur die Hashes speichern und vergleichen, dann passen mehr Generationen in den RAM. Um aber z.B. einen einzelnen Glider zu erkennen (sofern du an den Seiten wrap-around machst) braucht man schon einiges an RAM.
Wenn ich GoL implementiert habe, dann habe ich vor der Berechnung des nächsten Zyklus den Status von einigen Zellen per Zufall getoggelt. Wenn dann nach der Berechnung die aktiven Zellen dargestellt werden, blitzt da nichts mehr auf.
1 | void Step() { |
2 | Randomize(); |
3 | Calculate(); |
4 | DrawCells(); |
5 | }
|
Für das Detektieren eines "statischen" Zustandes: Du könntest die Anzahl der lebenden Zellen zählen. Diese Anzahl sollte sich dann nicht mehr ändern. merciless
:
Bearbeitet durch User
Dirk K. schrieb: > Für das Detektieren eines "statischen" Zustandes: > Du könntest die Anzahl der lebenden Zellen zählen. Das mache ich schon, die ändert sich aber bei manchen Pulsaren. Ich erfasse auch die Anzahl veränderter Zellen. Aber so richtig glücklich bin ich damit nicht. Das Ding ist nur Demo klar, aber auch die soll endlos laufen. Bisher erzeuge ich mit GodMode(x) umso mehr Zellen, je weniger es werden. Das erzeugt aber eben leider diese Blitzer eines einzelnen Punktes. Arne schrieb: > Die einzige Loesung, die mir dazu einfaellt: speicher so viele > Generationen, wie in den RAM passen, in einem Ringpuffer, und vergleiche > jede neue Generation mit den alten. Die Idee ist auch nicht verkehrt. Habe 20kb RAM, wenn ich mit dem Bitbanding arbeite (bisher gings auch ohne....) frisst jede Matrix grad mal 12x8 = 96 Bytes. Falls überhaupt nötig, da auch 768 Bytes noch fast 15 Mal rein passen.
Du koenntest einfach den Mittelwert der Stromaufnahme des Displays messen. Bleibt der ueber einen gewissen Zeitraum konstant, dann ist das Display entweder leer, oder sind nur noch "Blinker" da.
Anstatt nur einzelne Pixel zu setzen, könntest du auch ab und zu Glider von außen reinfliegen lassen oder in einem größeren leeren Block ein chaotisches Pattern (z.B. r-Pentomino) entstehen lassen.
foobar schrieb: > Anstatt nur einzelne Pixel zu setzen, könntest du auch ab und zu Glider > von außen reinfliegen lassen oder in einem größeren leeren Block ein > chaotisches Pattern (z.B. r-Pentomino) entstehen lassen. Zusammen mit der Erkennung der statischen Welt oben werde ich das mal ins Auge fassen. Ich schiebe ja nur 96 Bytes Bitstream in die Anzeige und da lassen sich 5 Streams locker speichern, die sich nicht wiederholen dürfen. Ich hoffe mal, dass eine einfache XOR 32 Bit Quersumme sicher genug ist, werden sich schon nicht zwei so ändern, dass die gleich bleibt. Das mit den Glidern ist schon schwieriger, die müssen ja in allen 4 Varianten vorliegen damit sie auch alle Richtungen fliegen und an dem Feldrand überspringen zur anderen Seite. Außerdem muss es auch dafür Regeln geben, denn die sollen ja durch Kollisionen mit den Stillleben neue Strukturen erzeugen.
Christian J. schrieb: > Ich hoffe mal, dass eine einfache XOR 32 Bit Quersumme sicher genug ist Der STM32F1xx kann doch CRC in Hardware. Ist doch perfekt für den Zweck.
Harry L. schrieb: > Der STM32F1xx kann doch CRC in Hardware. > Ist doch perfekt für den Zweck. Wir backen erstmal kleine Brötchen, bevor die Hardwaregeschütze aufgefahren werden :-) Erst funktionieren, dann optimieren.
1 | /* -----------------------------------------------------------------------------
|
2 | Prüft ob, der aktuelle Datenstream schonmal eingespielt wurde in den letzten
|
3 | 5 Perioden.
|
4 | -------------------------------------------------------------------------------- */
|
5 | uint8_t history[5][DATA_SETS]; |
6 | uint8_t hPtr = 0; |
7 | |
8 | static
|
9 | int CheckForPeriod(uint8_t* source, size_t len) |
10 | {
|
11 | /* Puffer für 5 Perioden */
|
12 | |
13 | /* Neuen Datenstrom in freien Bereich einspielen */
|
14 | for (int i = 0; i < DATA_SETS; i++) |
15 | history[hPtr][i] = *(source++); |
16 | |
17 | /* Neuen Datenstrom gegen alle anderen vergleichen */
|
18 | int cmpPtr = (hPtr + 1) % 5; |
19 | int check = 1, cnt = 0; |
20 | do { |
21 | check = memcmp((uint8_t*)&history[hPtr][0],(uint8_t*)&history[cmpPtr][0], len); |
22 | cmpPtr = (cmpPtr + 1) % 5; |
23 | cnt++; |
24 | } while ((check !=0 ) && (cnt < 4)); |
25 | |
26 | /* Zeiger auf nächste freie Reihe des Ringpuffers */
|
27 | hPtr = (hPtr + 1) % 5; |
28 | |
29 | if (!check) |
30 | return 1; |
31 | |
32 | return 0; |
33 | }
|
So gehts schneller... leider werden bestimmte Raumschiffe aber nicht erkannt, da sie die Erkennung auf Stillleben nicht erfüllen. Dann segelt so eines ununterbrochen durch den Bildschirm.
1 | static
|
2 | int CheckForPeriod(uint8_t* source, size_t len) |
3 | {
|
4 | /* Puffer für 5 Perioden */
|
5 | static uint8_t hPtr = 0; |
6 | static uint32_t HistoryCRC[5] = {1,2,3,4,5}; |
7 | |
8 | /* CRC32 Summe bilden für aktuellen Datenstrom */
|
9 | CRC_ResetDR(); |
10 | uint32_t crc = CRC_CalcBlockCRC((uint32_t*) source, len/4); |
11 | HistoryCRC[hPtr] = crc; |
12 | |
13 | /* Neuen Datenstrom gegen alle anderen vergleichen */
|
14 | int cmpPtr = (hPtr + 1) % 5; |
15 | |
16 | int cnt = 0; |
17 | while ((HistoryCRC[cmpPtr] != crc ) && (cnt < 4)) { |
18 | cmpPtr = (cmpPtr + 1) % 5; |
19 | cnt++; |
20 | };
|
21 | |
22 | /* Ringpuffer rotieren */
|
23 | hPtr = (hPtr + 1) % 5; |
24 | |
25 | /* Cnt < 4, dann war Treffer */
|
26 | return ((cnt < 4) ? true:false); |
27 | }
|
Hans schrieb: > Was ist denn das genau? Naja, wenn ich da so abends aus dem Bett drauf schaue macht es mich auf jeden Fall schnell müde, das Gewusel :-) Ein Spielzeug für Nerds, war 1985 u.a. eine Übungsaufgabe im PASCAL Informatik Kurs auf dem Apple IIe.
Rufe mal handofgod() auf, bevor die neue Generation berechnet wird. Dann sollte da auch nichts mehr aufblitzen. merciless
Das ist doch der Fall. Displaymatrix bringt die Anzeige zum Leuchten. Dann ist die naexhste Generation schon berechnet worden. Ein bisschen Blitzen bleibt immer.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.