Inhaltsverzeichnis

Schleifen

Ritter Lanzelot


FIXME 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)

FIXME\\ for ''variable'', wert in myTable do \\ Der Bezeichner ''variable'' ist unglücklich gewählt. Eine Variable ist auch ''wert'' oder myTable. Möchte man aus dem Englischen übertragen so wird "Key-Value-Pair" zu "Schlüssel-Werte-Paar". Zu ''Schlüssel'' kann man auch Index sagen. Außerdem sollte aus Kompatibilitätsgründen pairs() auf das Table angewendet werden. Das hat dir Chromix aber schon gesagt.\\FIXME

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“} FIXME 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)

1)

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)

2)

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)
Zurück auf die Zahl ← drücken
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
end
Abbruch, da jetzt var = 5 und somit nicht mehr kleiner oder gleich 4 ist.
2)
Zurück auf die Zahl← drücken
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
end
Abbruch, 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