1. Runde: while ( 1 > 0 and 1 <= 4 ) or ( step <= 0 and var >= limit ) do EnlargeArmy(armyOne,troopDescription); var = 1 + 1 -- -> 2 end 2. Runde: while ( 1 > 0 and 2 <= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 2 + 1 -- -> 3 end 3. Runde: while ( 1 > 0 and 3 <= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 3 + 1 -- -> 4 end 4. Runde: while ( 1 > 0 and 4 <= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 4 + 1 -- -> 5 endAbbruch, da jetzt var = 5 und somit nicht mehr kleiner oder gleich 4 ist.
Inhaltsverzeichnis
Schleifen
Schaut gut aus. Vielleicht noch ein Beispiel, in dem ein String mit fortlaufender Zahl generiert wird.
Schleifen sind eine wunderbare Erfindung einem viel Tipparbeit zu ersparen. Es lohnt sich immer , wenn man mehrfach das Gleiche macht, eine Schleife dazu zu benutzen.
Die Arten:
Der Anfang | Das Ende | Kurzbeschreibung |
---|---|---|
for - Schleife | end
| Schleife mit einem Zähler von bis und einer Sprungvariablen (step genannt) |
while - Schleife | end
| Schleife mit einer Bedingung |
repeat - Schleife | until
| Schleife mit einer Bedingung, die aber auf jedenfall mindestes einmal durchlaufen wird |
for
for i = 1, 4, 0.5 do --Arbeitsanweisung end | Mit "i" von 1 bis 4, in Schritten von 0.5, mache: --Arbeitsanweisung Verändere i (hier + 0.5), gehe nach oben; oder wenn i == 4 dann Ende |
Das for-Statement hat zwei Formen: eine numerische und eine generische. Als Mapper benutzt man den numerischen.
Die numerische wiederholt immer wieder einen Codeblock, solange eine Kontrollvariable einer festgelegten arithmetischen Gleichung noch entspricht.
Viele von Euch haben sicherlich schon einmal den Teil
for i = 1, 4 do EnlargeArmy(armyOne,troopDescription); end
in einer Funktion CreateArmy() gelesen oder ihn kopiert, ohne so recht zu wissen, was er bedeutet. In der Karte ScriptExample wird darauf hingewiesen, dass in der Schleife das selbe passiert, als wenn man
EnlargeArmy(armyOne,troopDescription); EnlargeArmy(armyOne,troopDescription); EnlargeArmy(armyOne,troopDescription); EnlargeArmy(armyOne,troopDescription);
schreiben würde. Es wird also 4x ein Hauptmann mit Truppe zur Armee hinzu gefügt wird.
Die Definition einer For-Schleife ist
for Name = exp , exp [ , exp ] do block end
auf Deutsch: var für gewünschte Startzahl, limit für gewünschte Endzahl und step für gewünschte Schrittgröße
for Name = var , limit [, step] do EnlargeArmy(armyOne,troopDescription) end
im Beispiel von oben wird also bei 1 (var) begonnen, die Schleife läuft so oft, bis 4 (limit) erreicht ist und es wird immer um 1 (step) erhöht
( 1 ist für step Standard und steht deshalb in eckiger Klammer. Alles was in Erkärungen in eckigen Klammern steht muss nicht unbedingt geschrieben werden)
Für uns wichtiges Beispiel
Wir haben ein paar Diebe die sind durchnummeriert von Dieb1, Dieb2, …, bis Dieb 20.
Jetzt wollen wir irgendwann wissen ob alle noch am Leben sind.
Ohne Schleife müßten wir dann schreiben
if IsDead("Dieb1") then --Anweisung end if IsDead("Dieb2") then --Anweisung end . . . if IsDead("Dieb20") then --Anweisung end
oder
if IsDead("Dieb1") or IsDead("Dieb2") ... or IsDead("Dieb20") then --Anweisung end
Viel Schreib- und Kopierarbeit.
Mit einer Schleife geht das ganz einfach
for i = 1, 20 do if IsDead( "Dieb"..i ) then -- Hier wird "Dieb" mit i verbunden. Bei i = 5 >> "Dieb5" -- Anweisung end end
Man kann das auch mit den anderen machen. dann muß man sich den Zähler aber selbst basteln.
Also besser mit for.
for – Schleife (generische Form)
Mit der numerischen Form konnten wir alle tables in der Art: myTable[nummer] durchgehen.
Mit dieser Art von for – Schleife können wir aber solche tables nicht durchgehen: myTable.meinName
Genau das kann aber die generische Form der for – Schleife.
for variable, wert in myTable do Block end
Diese Schleife geht, ungeachtet ob es sich um ein numerisches table oder ein table mit Namen handelt, jedes Teil des tables durch.
Beispiel: Wir erzeugen ein table mit den Wochentagen
tage = {„Sonntag“, „Montag“, „Dienstag“,„Mittwoch“, „Donnerstag“, „Freitag“, „Samstag“} da muß ich noch ändern, Morgen
Jetzt liegt ein table in dieser Form vor:
tage[1] = "Sonntag" tage[2] = "Montag" tage[3] = "Dienstag" tage[4] = "Mittwoch" tage[5] = "Donnerstag" tage[6] = "Freitag" tage[7] = "Samstag"
Noch ein numerisches table
Wir machen eine generische Schleife. Dazu müssen wir nicht wissen, wie groß das table ist. Es wird ja jedes Element durchgegangen.
tagesZahlen = {} for variable, wert in tagesZahlen do tagesZahlen[wert] = variable end
Was geschieht:
-- wir machen ein leeres table (tagesZahlen) -- jetzt geht die Schleife jeden Teil des Tables durch -- in der Variablen variable steht jedes Mal womit wir diesen Teil ansprechen können. In unserem Fall ist das jetzt die Zahl [1…7] -- in der Variablen wert steht jedes mal der Inhalt den Tables mit der entsprechenden Nummer [Sonntag … Samstag] -- im Block erzeugen wir dann jeweils ein Teil des Tables tagesZahlen in der Form: tagesZahlen.Sonntag = 1 ….. o tagesZahlen.Samstag = 7
Durch die Schleife:
for i,v in tage do tagesZahlen[v] = i end
haben wir gesehen, dass es noch eine andere Form gibt ein table mit Namen zu erzeugen
• tagesZahlen.Sonntag = 1 – kennen wir • tagesZahlen[„Sonntag“] = 1 – haben wir jetzt
kennen gelernt
• tagesZahlen = {Sonntag = 1} – geht genau so
Sehr vielseitig. Nicht wahr? Immer so nutzen, wie wir es gerade brauchen können.
while
Die while-Schleife
macht etwas solange wie eine Bedingung erfüllt ist.
while a == 1 do --Arbeitsanweisung end | Solange **wie** a gleich 1 ist mache: --Arbeitsanweisung Gehe nach oben oder a ist gleich 1 dann Ende |
Kommt das Programm an der Schleife an, und a ist schon 1, dann wird nichts gemacht.
Die Bedingung die erfüllt sein muß, um zu beenden, kann alles Mögliche sein. Sie ist nicht auf Zahlen beschränkt.
Eine andere Bedingung wäre z.B. IsDead(„Dario“). Also solange wie Dario tot ist mache. U.S.W.
man könnte den Code der o.g. For-Schleife auch so schreiben:
-- Deklarieren der Variablen var = 1; limit = 4; step = 1; -- nun die eigentliche Arbeit der Schleife: -- SOLANGE ( step größer als 0 UND var kleiner / gleich limit [ zum Hochzählen] ) ist -- ODER ( step kleiner / gleich 0 UND var größer / gleich limit [ zum Herunterzählen ] ) DANN while ( step > 0 and var <= limit ) or ( step <= 0 and var >= limit ) do -- der Block EnlargeArmy(armyOne,troopDescription); -- addiere step zu var var = var + step; end
im Falle von
for i = 1,4,1 do EnlargeArmy(armyOne,troopDescription); end
würde das in Schritten so aussehen:
Code:( auf die Zahl → drücken, um anzusehen)
Die While-Bedingung ist wie alle Schleifen auch geeignet um etwas herunter zu zählen
bis zu einem bestimmten Limit, dann muss step aber negativ sein: (geht in der for-Schleife aber bequemer)
Beispiel: wir starten bei 10 (var) und zählen bis 4 (limit) in Schritten von -2 (step)
Code:( auf die Zahl → drücken, um anzusehen)
repeat
Die repeat-Schleife
macht etwas solang bis eine Bedingung erfüllt ist.
repeat --Arbeitsanweisung until a == 1 | Solange **bis** a gleich 1 ist mache: --Arbeitsanweisung Gehe nach oben oder a ist gleich 1 dann Ende |
Kommt das Programm an der Schleife an, und a ist schon 1, dann wird im Gegensatz zu While-Schleife einmal die Anweisung gemacht.
Die Bedingung die erfüllt sein muß, um zu beenden, kann alles Mögliche sein. Sie ist nicht auf Zahlen beschränkt. Eine andere Bedingung wäre z.B. IsDead(„Dario“). Also solange bis Dario Tot ist mache. U.S.W.
1. Runde: while ( step > 0 and var <= limit ) or ( -2 <= 0 and 10 >= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 10 + (-2); -- -> 8 end 2. Runde: while ( -2 <= 0 and 8 >= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 8 + (-2); -- -> 6 end 3. Runde: while ( -2 <= 0 and 6 >= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 6 + (-2); -- -> 4 end 4. Runde: while ( -2 <= 0 and 4 >= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 4 + (-2); -- -> 2 endAbbruch, da var mit 2 nun nicht mehr größer/gleich 4 ist Man könnte natürlich auch für step eine positive Zahl nehmen und den Block so schreiben:
while ( step > 0 and var <= limit ) or ( 2 >= 0 and 10 >= 4 ) do EnlargeArmy(armyOne,troopDescription); var = 10 - 2; -- -> 8 end