Pages: [1]   Go Down
Author Topic: Zufallszahl, aber jede nur ein mal  (Read 1161 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 4
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hallo,

ich habe ein Led strip und möchte nach und nach alle LEDs per zufall angehen lassen.
Bei jedem loop soll eine weitere LED angehen.
Das heißt im random muss überprüft werden, ob die LED schon an ist.
Hier kann man also alle eingeschalteten LEDs in ein Array schmeißen und immer schön schleifen durchlaufen...
Ist mir etwas zu aufwändig.

Hier nun meine Idee (die so richtig nicht funktiniert)

Ich möchte gerne ein Array mit allen LED IDs füllen

Code:
int totalLength = stripLengthv + stripLengthvr + stripLengthhr + stripLengthh + stripLengthhl + stripLengthvl;
int numberArray[totalLength]; //funktioniert leider nicht... "array bound is not an integer constant"


Code:
for(int i=0; i<totalLength; i++)
{
  numberArray[i] = i;
}

im loop möchte ich dann ein element per zufall auswählen und dieses aus dem array löschen.

Code:
int aktPixel = random(totalLength);
paintPixel(numberArray[aktPixel ]);
numberArray.splice(aktPixel, 0);

leider sind diese sachen die ich hier geschrieben hab actionscript3 code und ich weiß sie so recht nicht auf arduino zu transferieren.

also meine zulösenden probleme sind:

1. die totalLength ist in einer variable gespeichert und ich möchte ein Array mit dieser Länge erzeugen
Komischerweise wird ein integer Variable nicht als Längendefinition für ein Array akzeptiert. Was kann ich tun?

2. wie kann ich elemente aus einem Array komplett löschen?
Also so, dass sich gleichzeitig alle nachfolgenden elemente nach vorne schieben und sich die gesamlänge verkürzt?


hoffe mir kann jemand helfen.

viele grüße
« Last Edit: October 02, 2012, 04:00:53 am by iamable » Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 111
Posts: 5236
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

1. Dynamische Arrays (also Arrays deren Länge erst zur Laufzeit bekannt ist) lassen sich mit malloc() und free() realisieren:

Code:
int *numberArray = malloc(count * sizeof(int));
// use it
free(numberArray);

2. Dies liesse sich durch ein fest alloziertes Array darstellen, dessen Grösse Du in einer separaten Variablen speicherst. Dann kannst Du alle Elemente oberhalb des zu löschenden um eines runterkopieren und am Schluss die Grössenvariable um eins verkleinern.
Allerdings würde ich in Deinem Fall nicht dazu raten. Ich würde Dein Array zufällig sortieren (also besser: durchmischen), was eine Permutation erzeugt. Dann kannst Du einfach sequentiell durch das Array gehen und eine LED-Nummer nach der anderen angehen lassen.
Logged

Weinsberg, Germany
Offline Offline
God Member
*****
Karma: 3
Posts: 773
A Coder's Tale
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Das wird so nicht funktionieren, da der Arduino ein Array wie in C benutzt.

Du könntest Dir eine verkettete Liste über ein entsprechendes struct aufbauen, aber das wäre ein bisschen auswändig.

Wie wäre es denn wenn Du Dir ein totalLength-langes Array aufbaust, es mit Zahlen von 0 bis totalLength-1 füllst, und dann die Zahlen in der Reihenfolge verwürfelst? Anschließend müsstest Du nur noch in einer Schleife ein Mal über das Array laufen und die entsprechenden LEDs anwerfen.

Verwürfeln könntest Du z.B. über einen Sortieralgorithmus (z.B. einen Bubble-Sort oder so), der aber statt die Inhalte zu vergleichen Zufallswerte vergleicht. Wenn Du den oft genug drüber laufen lässt sollte das Ergebnis eigentlich auch nahezu zufällig sein...


Update: pylon war schneller. smiley
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1419
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das Verfahren ist reichlich umständlich,weil jedesmal Daten kopiert werden.

Wenn da die Anzahl der LEDs ja konstant ist, kann man ein Array fester Größe wählen. Aber anstatt es nun mit den LED-Nummern in aufsteigender Reihenfolge zu bestücken, bringt man den Inhalt des vollen Arrays durcheinander, z.B. indem man zweizufällig ausgewählte Elemente vertauscht. Je häufiger man das macht, desto "zufälliger" wird die Reihenfolge.
Am Ende kann man dann das Array normal durchlaufen und die LEDs in der Reihenfolge einschalten wie sie drin stehen.

Beispiel:
Code:
#define NUMLED 10

//Liste der LED-Pins (Beispiel)
int leds[NUMLED] = { 1,2,3,4,5,6,7,8,9,10};

void loop() {
    //20ig Mal Elemente tauschen
    for(int i=0;i<20;i++)
        swap();

    //LEDs einzeln einschalten
    for(int i=0;i<NUMLED;i++) {
        digitalWrite(leds[i],HIGH);
        delay(500);
    }
}

void swap() {
    byte a = random(0,NUMLED);
    byte b = random(0,NUMLED);
    int temp = leds[a];
    leds[a] = leds[b];
    leds[b] = temp;
}
« Last Edit: October 02, 2012, 06:21:19 am by mkl0815 » Logged

Weinsberg, Germany
Offline Offline
God Member
*****
Karma: 3
Posts: 773
A Coder's Tale
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Stimmt, das bringt noch schneller gute Ergebnisse.  smiley
Logged

Offline Offline
Jr. Member
**
Karma: 4
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hat super funktioniert....vielen dank
Logged

Pages: [1]   Go Up
Jump to: