Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level1:tables

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Nächste Überarbeitung
Vorherige Überarbeitung
scripting:tutorials:level1:tables [2023/05/28 15:41] – angelegt fritz_98scripting:tutorials:level1:tables [2024/05/13 13:26] (aktuell) fritz_98
Zeile 41: Zeile 41:
 </code> </code>
  
 +Tables, die wie Listen funktionieren, werden auch als //numerische Tables// bezeichnet.
 ----  ---- 
  
Zeile 55: Zeile 56:
 ---- ----
  
-**Hinweis**: Falls du schonmal mit anderen Programmiersprachen gearbeitet hast, bist du möglicherweise gewohnt, dass die Indizes derartiger Listen bzw. Arrays bei ''0'' zu zählen beginnen. Lua ist da anders: Hier beginnen Listen immer bei Index ''1''!+**Hinweis**: Falls du schonmal mit anderen Programmiersprachen gearbeitet hast, bist du möglicherweise gewohnt, dass die Indizes derartiger Listen bzw. Arrays bei ''0'' zu zählen beginnen. Lua ist da anders: Hier beginnen Listen immer bei Index ''1'' 
 + 
 +\\ 
 + 
 +==== Nutzung von Schleifen ====
  
 Vielleicht hast du schon bemerkt, dass es sich anbietet, Schleifen zu verwenden, wenn man mehrere Einträge eines Tables braucht. Mit einer **for**-Schleife kann die Zählvariable dazu benutzt werden, die Table-Einträge nacheinander zu **referenzieren**: Vielleicht hast du schon bemerkt, dass es sich anbietet, Schleifen zu verwenden, wenn man mehrere Einträge eines Tables braucht. Mit einer **for**-Schleife kann die Zählvariable dazu benutzt werden, die Table-Einträge nacheinander zu **referenzieren**:
Zeile 68: Zeile 73:
 Es gibt Umstände, unter denen du nicht weißt, wie groß ein Table ist. Es gibt Funktionen, die Listen variierender Größe als Rückgabewert haben. Da so ein Fall sehr oft eintritt, wollen wir eine sehr wichtige Funktion vorwegnehmen: \\ Es gibt Umstände, unter denen du nicht weißt, wie groß ein Table ist. Es gibt Funktionen, die Listen variierender Größe als Rückgabewert haben. Da so ein Fall sehr oft eintritt, wollen wir eine sehr wichtige Funktion vorwegnehmen: \\
 ''table.getn'' \\ ''table.getn'' \\
-Damit kann die Größe bzw. Länge einer Liste ermittelt werden. Dabei gibt es eine Einschränkung: **Diese Funktion funktioniert nur wie erwartet bei Listen**. Bei Tables, die wir weiter unten beschreiben, funktioniert diese Funktion nicht. Wir werden entsprechend darauf hinweisen.+Damit kann die Größe bzw. Länge einer Liste ermittelt werden. Dabei gibt es eine Einschränkung: **Diese Funktion funktioniert nur wie erwartet bei Listen**. Bei einigen Tables, die wir weiter unten beschreiben, funktioniert diese Funktion nicht. Wir werden entsprechend darauf hinweisen.
  
 Das gleiche Beispiel kann nun unter Verwendung von ''table.getn'' noch etwas umgebaut werden: Das gleiche Beispiel kann nun unter Verwendung von ''table.getn'' noch etwas umgebaut werden:
Zeile 106: Zeile 111:
 MyTable = {5, 8, 27, 11, 90, 3, 82} MyTable = {5, 8, 27, 11, 90, 3, 82}
 MyTableSum = SumOfList(MyTable) MyTableSum = SumOfList(MyTable)
 +</code> 
 +
 +\\
 +
 +==== Eine Liste verändern ====
 +
 +Konsequenterweise können wir über ''MyTable[2]'' das zweite Element unserer Liste nicht nur lesen, sondern auch überschreiben:
 +<code lua>
 +MyTable = {42, "Hallo Welt", true}
 +
 +-- Schreibe an die zweite Stelle der Liste einen anderen Wert
 +MyTable[2] = "Welt, seid mir gegrüßt"
 </code> </code>
  
-FIXME Tables mit Indizes aufbauen + Hinweis darauf, dass das auch richtig passieren mussweil sonst table.getn nicht mehr geht+Auf diese Art und Weise kann ein Table auch nachträglich vergrößert werden, indem man einen Index benutzt, der die Listengröße um 1 erhöht: 
 + 
 +<code lua> 
 +MyTable = {42, "Hallo Welt", true} 
 + 
 +-- Schreibe an die vierte Stelle der Liste einen neuen Wert 
 +MyTable[4] = "Neuer Wert" 
 +</code> 
 + 
 +In einer Schleife können so beliebig große Listen erschaffen werden. In folgendem Beispiel erstellen wir ein Table, in dem die ersten paar Zahlen der [[ https://de.wikipedia.org/wiki/Fibonacci-Folge |Fibonacci-Folge]] liegen. Die gewünschte Länge unserer Liste geben wir als Parameter an: 
 +<code lua> 
 +function GetFibonacci(_Length) 
 +    -- Falls man nur an höchstens einer Fibonacci-Zahl interessiert ist, brauchen 
 +    -- wir nicht groß zu rechnen 
 +    if _Length == 0 then 
 +        return {} 
 +    elseif _Length == 1 then 
 +        return {0} 
 +    end 
 +     
 +    -- Initialisiere die Liste mit den ersten beiden Einträgen 
 +    local FibonacciList = {0, 1} 
 +    -- Die Schleife startet bei 3, denn die ersten beiden Einträge haben wir schon 
 +    for i = 3, _Length do 
 +        -- Wir greifen hier auf die Indizes i-2 und i-1 zu 
 +        -- Wenn man auf diese Weise mit Indizes rechnetmuss man immer sicherstellen, 
 +        -- dass man nicht "außerhalb" der Liste landet. 
 +        -- Dadurch, dass wir mit zwei Elementen in der Liste beginnen, klappt das 
 +        -- hier immer 
 +        FibonacciList[i] = FibonacciList[i-2] + FibonacciList[i-1] 
 +    end 
 +     
 +    return FibonacciList 
 +end 
 + 
 +MyFibonacci = GetFibonacci(10) 
 + 
 +-- Wir überlassen es dem Leserdie Liste MyFibonacci mit print komplett anzeigen zu lassen 
 +-- Eine Schleife und table.getn wird dabei helfen 
 +</code> 
 + 
 +**Achtung**: Wenn Listen auf diese Art befüllt werden, ist es wichtig, dass die Indizes des Tables **immer von 1 bis n** gehen. In anderen Worten: Die Reihe der Indizes **darf nicht unterbrochen** sein! Andernfalls wird ''table.getn'' nicht mehr richtig funktionieren. Leider unterscheidet sich die Lua-Version von Siedler hier wieder von der aktuellen, weshalb folgendes Beispiel ''Message'' statt ''print'' verwendet: 
 +<code lua> 
 +MyTable = {6, 18} 
 + 
 +-- Hier wird ein Wert an Stelle 4 geschrieben, obwohl Stelle 3 nicht existiert 
 +MyTable[4] = 24 
 + 
 +-- Als Table-Länge wird 2 angezeigt werden, weil danach ein "Loch" in der Liste ist 
 +Message(table.getn(MyTable)) 
 + 
 +-- Wenn wir dieses "Loch" nun "stopfen"... 
 +MyTable[3] = 1 
 + 
 +-- wird die Table-Länge 4 angezeigt werden 
 +Message(table.getn(MyTable)) 
 +</code>
  
 ---- ----
  
 ===== Tables als Wörterbücher ===== ===== Tables als Wörterbücher =====
 +
 +Die andere Art von Tables sind solche, die **Paare** von Variablen einander zuordnet. Wie in einem Wörterbuch kann man in so einem Table für einen gesuchten Wert (Fremdwort, **Schlüsselwert**/**Key**) einen entsprechenden gespeicherten Wert (Wort in der Muttersprache, **Value**) vorfinden. Auch solche Tables werden mit geschweiften Klammern ''{}'' konstruiert. Im Gegensatz zur numerischen Variante werden diese Tables //assoziative Tables// genannt.
 +
 +Dazwischen stehen dann die Werte-Paare. Der Schlüsselwert/**Key** liegt dabei in eckigen Klammern ''[]'' und wird durch ein =-Zeichen mit einem Wert/**Value** assoziiert. Ein sehr kleines Englisch-Deutsch-Wörterbuch sähe zum Beispiel so aus:
 +<code lua>
 +Dictionary = {
 +    ["Computer"] = "Rechner",
 +    ["Mouse"] = "Maus",
 +    ["Keyboard"] = "Tastatur",
 +    ["Screen"] = "Bildschirm"
 +}
 +</code>
 +
 +Will man nun wissen, welches deutsche Wort einem englischen entspricht, kann man sich den Wert wie bei den Listen oben mit eckigen Klammern holen:
 +
 +<code lua>
 +-- Was bedeutet Keyboard?
 +print("Keyboard bedeutet "..Dictionary["Keyboard"])
 +</code>
 +
 +Natürlich kann man nicht nur Strings einander zuordnen:
 +<code lua>
 +NumberNames = {
 +    [1] = "One",
 +    [2] = "Two",
 +    [3] = "Three",
 +    [4] = "Four"
 +}
 +</code>
 +
 +Der Name einer Zahl lässt sich dann mit ''NumberNames[i]'' ermitteln. Vielleicht fällt dir auf, dass diese Art der Referenzierung genau der von Listen entspricht. Und tatsächlich: Wenn die **Keys** des Tables ausschließlich Zahlen von ''1'' bis ''n'' sind, kann man dieses Table auch als Liste schreiben:
 +
 +<code lua>
 +NumberNames = {"One", "Two", "Three", "Four"}
 +</code>
 +
 +Es gibt für Tables eine weitere abkürzende Schreibweise, die sehr häufig benutzt wird. Wenn ein **Key** ein String ist, können die eckigen Klammern und Anführungszeichen weggelassen werden, sodass unser Wörterbuchbeispiel vereinfacht so aussieht:
 +<code lua>
 +-- Dieses kleine Wörterbuch ist genau das gleiche wie oben in einer anderen Schreibweise
 +Dictionary = {
 +    Computer = "Rechner",
 +    Mouse = "Maus",
 +    Keyboard = "Tastatur",
 +    Screen = "Bildschirm"
 +}
 +</code>
 +**Wichtig**: Das gilt nur für Strings und nur für Keys!
 +
 +Die gleiche Vereinfachung existiert auch, wenn man den Wert anhand des Keys wieder referenzieren möchte:
 +<code lua>
 +-- Was bedeutet Keyboard?
 +print("Keyboard bedeutet "..Dictionary.Keyboard)
 +</code>
 +Der String-Key wird also mit einem Punkt vom Table-Name getrennt.
 +
 +**Hinweis**: Bei Tables, die Key-Value-Paare benutzen, funktioniert ''table.getn'' nicht! Die Funktion wird für solche Tables immer ''0'' ausgeben.
 +
 +**Wichtig**: In Siedler 5 müssen alle **Keys** entweder Strings oder Zahlen sein! Andernfalls gehen die Tables beim Speichern und Laden verloren.
 +
 +\\
 +
 +==== Ein Table verändern ====
 +
 +Wir können unserem Wörterbuch wie gewohnt neue Werte hinzufügen. Für Strings bleiben beide Schreibweisen:
 +<code lua>
 +-- Wir definieren einige String-Paare im Dictionary
 +Dictionary = {
 +    Computer = "Rechner",
 +    Mouse = "Maus",
 +    Keyboard = "Tastatur",
 +    Screen = "Bildschirm"
 +}
 +
 +-- Jetzt fügen wir einige weitere hinzu:
 +Dictionary["Speaker"] = "Lautsprecher"
 +Dictionary["Headphones"] = "Kopfhörer"
 +
 +-- Dabei können wir die Schreibweise frei wählen
 +Dictionary.Joystick = "Steuerknüppel"
 +</code>
 +
 +\\
 +
 +==== Tables als Werte ====
 +
 +Wenn man in einem Table weitere "Untertables" einem Schlüsselwert zuordnet, hat das den Effekt, dass Tables "geschachtelt" werden. Diese Konstruktion wird uns später beispielsweise in [[ scripting:tutorials:level1:briefings |Briefings]] begegnen.
 +
 +Aus Rollenspielen kennst du vielleicht Charaktereditoren, mit denen man vornehmlich das Gesicht seines Spielcharakters anpassen kann. Die Eigenschaften des Spielcharakters können in einem geschachtelten Table gespeichert werden und so eine übersichtliche Struktur erhalten:
 +<code lua>
 +Character = {
 +    Hair = {
 +        Style = "Short Messy",
 +        Color = "Black",
 +        Effect = "Glossy"
 +    }, -- Key-Value-Paare werden weiterhin durch Kommas getrennt. Die werden oft vergessen
 +    Eyes = {
 +        Type = 9,
 +        Color = "Green",
 +        Size = 5,
 +        GapSize = 11
 +    },
 +    Nose = {
 +        Type = 3,
 +        Size = 7,
 +        Effect = "Dirt Patch"
 +    }
 +}
 +</code>
 +In diesem Beispiel haben wir oft "Type" oder "Color" als Key. Da diese aber immer einem anderen Teil des Gesichts zugewiesen sind, bleibt es eindeutig, worauf sie sich beziehen. Denn \\
 +''Character.Eyes.Type'' \\
 +ist eine andere Variable als \\
 +''Character.Nose.Type''
 +
 +Man kann dem geschachtelten Table wie gewohnt neue Werte hinzufügen:
 +<code lua>
 +Character.Nose.Height = 8
 +
 +Character.Mouth = {
 +    Type = 10,
 +    Width = 15,
 +    Color = "Deep Red",
 +    Height = 4
 +}
 +</code>
 +
 +----
 +
 +An dieser Stelle sind die Lua-Inhalte für diese Ebene abgeschlossen. Das nächste Kapitel gibt **wichtige** Konventionen an, //wie// man Lua lesbar aufschreibt.
 +
 +[[ scripting:tutorials:level1:loops | Voriges Kapitel: Schleifen ]]\\
 +[[ scripting:tutorials:level1:readable_code | Nächstes Kapitel: Gut lesbare Skripte ]]\\
 +[[ scripting:tutorials:level1:tables | Zurück nach oben ]]
scripting/tutorials/level1/tables.1685288511.txt.gz · Zuletzt geändert: 2023/05/28 15:41 von fritz_98