Helmuth:
if (index<0) {index=index+25;}
if (index>24) {index=index-25;}
Ja, genau so.
Immer wenn Du "rechts neben das Ende" oder "links neben den Anfang" des Arrays greifen würdest, greifst Du stattdessen auf die entsprechende Stelle am anderen Ende des Arrays so, so dass sich beim Zugriff quasi ein geschlossener Ring ergibt.
Ich habe gerade auch mal einen sehr einfachen zellulären Automaten aufgesetzt, der berechnet zwar keine "plasmaähnlichen Effekte", sondern nur simple ein/aus Zustände, aber im Endeffekt dürfte es ziemlich dasselbe sein.
Ich habe zwei Zustandspuffer definiert, die immer im Wechsel mal als Quelle und mal als Ziel für die Berechnung des nächsten Schritts dienen.
Und eine Zugriffsfunktion, die bei Anforderung von Werten mit einem Index unter 0 oder oberhalb der Arraygrenze dann entsprechend Werte "vom anderen Ende des Arrays" zurückliefert.
// Zellulärer Automat by 'jurs' for German Arduino Forum
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
#define BUFLEN 61
byte celldata[2][BUFLEN]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
byte cellAccess(int index, int bufindex)
{
if (bufindex<0) bufindex+=BUFLEN;
if (bufindex>BUFLEN-1) bufindex-=BUFLEN;
return(celldata[index][bufindex]);
}
void Neuberechnen(byte source, byte dest)
// recalc data of cellular automat
{
for (int i=0;i<BUFLEN;i++)
{
if (cellAccess(source,i-1)==1 && cellAccess(source,i)==1 && cellAccess(source,i+1)==1) celldata[dest][i]=0;
else
if (cellAccess(source,i-1)==1 && cellAccess(source,i)==1 && cellAccess(source,i+1)==0) celldata[dest][i]=0;
else
if (cellAccess(source,i-1)==1 && cellAccess(source,i)==0 && cellAccess(source,i+1)==1) celldata[dest][i]=0;
else
if (cellAccess(source,i-1)==1 && cellAccess(source,i)==0 && cellAccess(source,i+1)==0) celldata[dest][i]=1;
else
if (cellAccess(source,i-1)==0 && cellAccess(source,i)==1 && cellAccess(source,i+1)==1) celldata[dest][i]=1;
else
if (cellAccess(source,i-1)==0 && cellAccess(source,i)==1 && cellAccess(source,i+1)==0) celldata[dest][i]=1;
else
if (cellAccess(source,i-1)==0 && cellAccess(source,i)==0 && cellAccess(source,i+1)==1) celldata[dest][i]=1;
else
if (cellAccess(source,i-1)==0 && cellAccess(source,i)==0 && cellAccess(source,i+1)==0) celldata[dest][i]=0;
else {Serial.print("Error ");Serial.println(i);} // this should never happen
}
}
void Zeigen(byte index)
// show data of cellular automat
{
char output[BUFLEN+1];
memset(output,0,sizeof(output));
for (int i=0;i<BUFLEN;i++)
if (celldata[index][i]==1) output[i]='X'; else output[i]=' ';
Serial.println(output);
}
void loop() {
// put your main code here, to run repeatedly:
static boolean even;
if (even)
{
Neuberechnen(0,1);
Zeigen(1);
}
else
{
Neuberechnen(1,0);
Zeigen(0);
}
even=!even;
}
Sehr schön sieht man an der Berechnung: Ein einzelner gesetzter Startwert führt sehr schnell zu einem Gewimmel von Werten im Automaten.
Du berechnest wahrscheinlich irgendwie RGB-Werte in Deinem Automaten statt nur einfacher ein/aus Werte?
Was man bei solchen Automaten herausbekommt, ob die aktiven Zellen langfristig "Aussterben" oder einem anderen Endzustand zustreben, bei dem es keine oder nur noch minimale Variation im Ablauf gibt, das hängt natürlich vom Algorithmus und den Parametern ab.