Kaum ein Textadventure kommt ohne einen Rucksack aus. Viele Rätsel erfordern, dass man vorher an einem anderen Ort Gegenstände eingesammelt hat. Diese müssen „irgendwie“ transportiert werden, z.B. in einem Rucksack oder verallgemeinert in einem „Inventar“. Programmiertechnisch bedeutet das, dass man sich Information über den Stand des Abenteuers merken muss. Wurde der rostigeSchlüssel schon eingesammelt? Python bietet dafür als Datentyp die Liste an.
Eine Liste ist – wie der Name schon sagt – eine Aufzählung von Daten. Man kann also in einer Liste Strings, Zahlen, Wahrheitswerte (und sogar andere Listen) zusammenfassen. Es gibt einfach Anweisungen, mit denen man Daten einer Liste hinzufügen, entfernen oder sie darin suchen kann. Anders als in einem Rucksack, in dem die Dinge oft durcheinander geraten, bleiben Daten in einer Liste immer in der Reihenfolge, in der man sie hinzugefügt hat.
Schauen wir uns ein einfaches Beispiel an.
inventar = ["Fackel", "Seil", "Proviant", "Wasserflasche"] def waldlichtung(): gute_antwort = False while not gute_antwort: print("Waldlichtung") print("Du befindest dich auf einer kleinen Lichtung im Wald. Hohe Bäume umringen den Platz, ihr Blätterdach lässt nur vereinzelte Sonnenstrahlen hindurch. Ein schmaler Pfad führt nach Norden und ein anderer nach Osten. Der Boden ist weich, mit Moos bedeckt, und du meinst, in der Ferne das Plätschern von Wasser zu hören.") wahl = input("Wohin soll es gehen? (n=Norden, o=Osten) ") if wahl == "n": gute_antwort = True flussufer() elif wahl == "o": gute_antwort = True verlasseneHuette() else: dunklerWald() def flussufer(): gute_antwort = False while not gute_antwort: print("Flussufer") print("Der Pfad mündet an ein glitzerndes Flussufer. Das Wasser ist klar und fließt ruhig dahin, doch weiter auf der anderen Seite siehst du dichten Wald. Ein alter Holzsteg ragt ein Stück in den Fluss – instabil, aber vielleicht noch nutzbar. Du kannst zurück nach Süden zur Waldlichtung gehen oder versuchen, den Holzsteg zu betreten.") wahl = input("Wohin soll es gehen? (s=Süden, h=Holzsteg) ") if wahl == "s": gute_antwort = True waldlichtung() elif wahl == "h": gute_antwort = True holzsteg() else: dunklerWald() def holzsteg(): gute_antwort = False while not gute_antwort: print("Holzsteg") if "Rostiger Schlüssel" in inventar: print("Der Steg ächzt und wankt unter deinem Gewicht, aber er hält. Unter dir fließt das Wasser klar und ruhig dahin. Du kannst zurück zum Flussufer gehen.") wahl = input("Was willst du tun? (f=zum Flussufer gehen) ") if wahl == "f": gute_antwort = True flussufer() else: print("Der Steg ächzt und wankt unter deinem Gewicht, aber er hält. Unter dir fließt das Wasser klar und ruhig dahin. Du beobachtest einige Fische und plötzlich siehst du einen rostigen Schlüssel auf Grund des Flusses liegen. Du kannst zurück zum Flussufer gehen oder versuchen, den Schlüssel zu nehmen.") wahl = input("Was willst du tun? (f=zum Flussufer gehen, s=Schlüssel nehmen) ") if wahl == "f": gute_antwort = True flussufer() elif wahl == "s": gute_antwort = True inventar.append("Rostiger Schlüssel") holzsteg() def verlasseneHuette(): gute_antwort = False while not gute_antwort: print("Verlassene Hütte") print("Ein schmaler Weg führt dich zu einer kleinen, verwitterten Hütte. Die Fenster sind blind vor Staub, die Tür geschlossen. Drinnen scheint es dunkel, aber du meinst, einen schwachen Geruch von Rauch wahrzunehmen – vielleicht war hier kürzlich jemand. Du kannst zurück nach Westen, zur Waldlichtung, oder versuchen, die Tür zu öffnen.") wahl = input("Was willst du tun? (w=nach Westen gehen, t=die Tür öffnen) ") if wahl == "w": gute_antwort = True waldlichtung() elif wahl == "t": if "Rostiger Schlüssel" in inventar: print("Die Tür ist verschlossen, aber der rostige Schlüssel passt und du kannst die Tür aufschließen. Die Hütte ist leer und kalt und du verlässt sie sofort wieder.") else: print("Die Tür ist verschlossen und du kannst sie nicht öffnen.") else: dunklerWald() def dunklerWald(): print("Dunkler Wald") print("Du verlässt den schmalen Pfad und schlägst dich durchs Unterholz. Schon nach wenigen Schritten verdunkelt sich das Licht, und die Luft wird kälter. Der Wald wirkt hier älter, dichter – fast lebendig. Zwischen den knorrigen Wurzeln scheint Nebel aufzusteigen, der lautlos über den Boden kriecht. Schnell kehrst du um, bevor du den Weg zurück nicht mehr findest.") waldlichtung()
Wie immer: Führe das Programm mit Thonny aus und untersuche, wie es funktioniert. Achte besonders auf die Zeile 1 sowie die Funktion holzsteg(). Benutze den Debugger und lasse dir die Variablen anzeigen.
In Zeile 1 wird die Listen-Variable inventar initialisiert. Listen schreibt man in eckigen Klammern und die Listenelemente werden durch Kommas voneinander getrennt. Anfänglich enthält unsere Liste schon vier Elemente, nämlich die Strings: „Fackel“, „Seil“, „Proviant“ und „Wasserflasche“. Beachte, dass man Variablen, die man verwenden möchte, immer zunächst initialisieren muss. Das heißt, man muss Variablen zunächst einen Wert zuweisen. Andernfalls bekommt man eine Fehlermeldung, wenn man auf die Variable zugreift.
Probiere es selbst aus: Lösche die Zeile 1, dann gibt es eine Fehlermeldung, sobald die Programmausführung in Zeile 37 (bzw. 35 oder 36) angekommen ist. Wie lautet die Fehlermeldung?
Möchte man eine leere Liste haben, soll also der Rucksack anfänglich leer sein, dann schreibt man einfach nur „leere“ Klammern:
inventar = []
In der Funktion holzsteg() kannst du sehen, wie man Listen benutzt. In Zeile 37 wird mit dem Operator in geprüft, ob der String „Rostiger Schlüssel“ in der Variablen inventar enthalten ist. Je nachdem, wie die Prüfung ausfällt, wird der if- oder der else-Block der Fallunterscheidung ausgeführt.
Um einen neuen Gegenstand dem Inventar hinzuzufügen, verwendet man den Ausdruck inventar.append(…) (Zeile 51). Das ist nun wieder etwas Neues: Die Variable inventar verweist auf ein sog. Objekt. Objekte kombinieren Daten (hier: eine Liste von Dingen) mit den Operationen (hier: das Hinzufügen eines neuen Dings). Durch die Punktnotation drückt man aus, dass die Methode append() für das Objekt inventar aufgerufen wird. (Methoden sind Funktionen, die zu Objekten gehören.)
Für Listen-Objekte gibt noch eine Reihe weiterer Methoden, um Daten einzufügen, zu entfernen oder die Position herauszufinden, an der ein bestimmtes Datum in der Liste steht. Eine Übersicht findet man hier:
Listen sind in Python ein sehr flexibles Werkzeug, mit dem man für viele Probleme Lösungen programmieren kann. In der nächsten Lektion werden wir uns anschauen, wie man das Inventar noch etwas flexibler macht und dabei weitere Möglichkeiten des Listen-Datentyps erkunden.
Nun baue aber zunächst ein Inventar in dein eigenes Textadventure ein.
Nächste Lektion: Was habe ich eigentlich dabei?