cat posts/python-lernen-04-sammlungen.md
Python lernen (Teil 4): Sammlungen
Listen, Tupel, Dictionaries und Sets – damit beschreiben wir die Dungeon-Welt als Daten und geben unserem Abenteurer ein richtiges Inventar.
In Teil 3 haben wir einen
Game-Loop gebaut, der auf die Befehle des Spielers reagiert. Die möglichen Wege
und Ereignisse steckten dabei direkt in einer langen if-elif-Kette.
Bei zwei oder drei Räumen funktioniert das noch. Besteht unser Dungeon später aber aus dreißig Räumen, würde der Game-Loop schnell unübersichtlich werden.
Heute lernen wir deshalb Sammlungen kennen. Damit können wir mehrere Werte gemeinsam speichern und die Welt unseres Dungeons als Daten beschreiben.
Python bringt dafür verschiedene Collection Types mit:
- Listen
- Tupel
- Dictionaries
- Sets
Sie erfüllen unterschiedliche Aufgaben. Am Ende dieses Teils verwenden wir sie, um Räume, Ausgänge, Gegenstände und den Player State übersichtlich abzubilden.
Listen: geordnet und veränderbar
Eine Liste speichert mehrere Werte in einer festen Reihenfolge. Listen werden mit eckigen Klammern geschrieben:
inventar = ["Fackel", "Brot", "Seil"]
Die einzelnen Werte heißen Elemente. Eine Liste darf beliebig viele Elemente enthalten und kann auch leer sein:
leeres_inventar = []
Auf Elemente zugreifen
Jedes Element besitzt eine Position, die als Index bezeichnet wird. Die
Zählung beginnt bei 0:
inventar = ["Fackel", "Brot", "Seil"]
print(inventar[0])
print(inventar[1])
print(inventar[2])
Die Ausgabe lautet:
Fackel
Brot
Seil
Die Indizes dieser Liste sehen damit so aus:
| Index | Element |
|---|---|
0 |
"Fackel" |
1 |
"Brot" |
2 |
"Seil" |
Dass die Zählung bei 0 beginnt, ist am Anfang ungewohnt, in der Programmierung
aber sehr verbreitet.
Mit einem negativen Index greifst Du vom Ende der Liste aus auf ein Element zu:
print(inventar[-1])
Die Ausgabe lautet:
Seil
-1 bezeichnet das letzte Element, -2 das vorletzte und so weiter.
Listen verändern
Listen sind mutable, also veränderbar. Mit append(...) fügst Du ein
einzelnes Element am Ende hinzu:
inventar = ["Fackel", "Brot"]
inventar.append("Schlüssel")
print(inventar)
Die Ausgabe lautet:
['Fackel', 'Brot', 'Schlüssel']
Mit remove(...) entfernst Du ein bestimmtes Element:
inventar.remove("Brot")
print(inventar)
Danach enthält die Liste nur noch:
['Fackel', 'Schlüssel']
Soll eine Liste um alle Elemente einer anderen Liste erweitert werden, verwendest
Du extend(...):
inventar = ["Fackel"]
fund = ["Schlüssel", "Heiltrank"]
inventar.extend(fund)
print(inventar)
Die Ausgabe lautet:
['Fackel', 'Schlüssel', 'Heiltrank']
Der Unterschied ist wichtig:
inventar.append(fund)
würde die gesamte Liste fund als ein einziges Element einfügen:
['Fackel', ['Schlüssel', 'Heiltrank']]
Anzahl der Elemente bestimmen
Mit len(...) ermittelst Du die Länge einer Liste:
inventar = ["Fackel", "Brot", "Seil"]
print(len(inventar))
Die Ausgabe lautet:
3
Eine leere Liste besitzt die Länge 0.
Prüfen, ob ein Element enthalten ist
Mit in kannst Du prüfen, ob sich ein Wert in einer Liste befindet:
inventar = ["Fackel", "Brot", "Seil"]
print("Brot" in inventar)
print("Schlüssel" in inventar)
Die Ausgabe lautet:
True
False
Das lässt sich direkt in einer Bedingung verwenden:
if "Schlüssel" in inventar:
print("Du kannst die Tür öffnen.")
Eine Liste durchlaufen
Mit einer for-Schleife kannst Du jedes Element nacheinander verarbeiten:
inventar = ["Fackel", "Brot", "Seil"]
for gegenstand in inventar:
print(f"- {gegenstand}")
Die Ausgabe lautet:
- Fackel
- Brot
- Seil
Du benötigst dafür keinen Index. Bei jedem Durchlauf enthält gegenstand
automatisch das nächste Element der Liste.
Tupel: geordnet und unveränderbar
Ein Tupel ähnelt einer Liste. Es ist ebenfalls geordnet und kann mehrere Werte enthalten. Ein Tupel kann nach seiner Erstellung jedoch nicht mehr verändert werden.
Tupel werden üblicherweise mit runden Klammern geschrieben:
position = (3, 7)
Auf die Elemente greifst Du wie bei einer Liste über ihren Index zu:
print(position[0])
print(position[1])
Die Ausgabe lautet:
3
7
Eine Position aus einer X- und einer Y-Koordinate ist ein typischer Anwendungsfall für ein Tupel: Beide Werte gehören zusammen und die Position soll als gemeinsame Einheit behandelt werden.
Du kannst die Werte auch direkt in zwei Variablen übernehmen:
position = (3, 7)
x, y = position
print(f"X: {x}, Y: {y}")
Das wird Unpacking genannt.
Tupel lassen sich nicht verändern
Der folgende Versuch führt zu einem TypeError:
position = (3, 7)
position[0] = 9
Python erlaubt es nicht, einem Element des Tupels nachträglich einen neuen Wert zuzuweisen.
Ein Tupel eignet sich deshalb für Werte, die zusammengehören und nicht versehentlich verändert werden sollen.
Ein Tupel mit nur einem Element
Bei einem Tupel mit einem einzigen Element ist das Komma entscheidend:
ein_element = ("Schlüssel",)
Ohne das Komma entsteht lediglich ein String in Klammern:
kein_tupel = ("Schlüssel")
print(type(kein_tupel))
Die Ausgabe lautet:
<class 'str'>
Technisch erzeugt also das Komma das Tupel, nicht allein die runden Klammern.
Dictionaries: Werte über Schlüssel erreichen
Ein Dictionary, kurz dict, ordnet Schlüsseln bestimmte Werte zu.
Während Du bei einer Liste über einen numerischen Index auf ein Element zugreifst, verwendest Du bei einem Dictionary einen selbst gewählten Schlüssel.
Ein einfacher Raum könnte so beschrieben werden:
raum = {
"name": "Halle",
"beschreibung": "Eine dunkle Halle mit moderigem Geruch.",
"besucht": False,
}
Ein Dictionary wird mit geschweiften Klammern geschrieben. Jeder Eintrag besteht aus einem Schlüssel und einem Wert:
"beschreibung": "Eine dunkle Halle mit moderigem Geruch."
Der Doppelpunkt trennt den Schlüssel vom zugehörigen Wert.
Auf einen Wert zugreifen
Den Wert eines bestimmten Schlüssels erhältst Du mit eckigen Klammern:
print(raum["name"])
print(raum["beschreibung"])
Die Ausgabe lautet:
Halle
Eine dunkle Halle mit moderigem Geruch.
Werte verändern und ergänzen
Dictionaries sind wie Listen mutable. Du kannst vorhandene Werte verändern:
raum["besucht"] = True
Mit derselben Schreibweise kannst Du einen neuen Eintrag ergänzen:
raum["licht"] = "dunkel"
Existiert der Schlüssel bereits, wird sein Wert ersetzt. Existiert er noch nicht, wird er neu angelegt.
Prüfen, ob ein Schlüssel existiert
Der Operator in prüft bei einem Dictionary standardmäßig dessen Schlüssel:
print("beschreibung" in raum)
print("monster" in raum)
Die Ausgabe lautet:
True
False
Fehlende Schlüssel und .get(...)
Greifst Du auf einen nicht vorhandenen Schlüssel zu, entsteht ein KeyError:
print(raum["monster"])
Mit .get(...) erhältst Du bei einem fehlenden Schlüssel stattdessen None:
monster = raum.get("monster")
print(monster)
Du kannst außerdem einen Default-Wert angeben:
monster = raum.get("monster", "Kein Monster")
print(monster)
Die Ausgabe lautet:
Kein Monster
Dictionaries durchlaufen
Eine for-Schleife über ein Dictionary liefert standardmäßig seine Schlüssel:
for schluessel in raum:
print(schluessel)
Mit .values() erhältst Du die Werte:
for wert in raum.values():
print(wert)
Mit .items() erhältst Du Schlüssel und Wert gemeinsam:
for schluessel, wert in raum.items():
print(f"{schluessel}: {wert}")
Das Unpacking funktioniert hier genauso wie bei einem Tupel.
Verschachtelte Collections
Die Werte eines Dictionaries dürfen selbst wieder Listen, Tupel, Sets oder weitere Dictionaries sein:
raum = {
"name": "Halle",
"ausgaenge": {
"norden": "bibliothek",
"osten": "krypta",
},
"gegenstaende": ["Fackel", "Brot"],
}
raum["ausgaenge"] liefert hier ein weiteres Dictionary:
print(raum["ausgaenge"])
Um das Ziel des nördlichen Ausgangs zu erhalten, werden zwei Zugriffe miteinander kombiniert:
print(raum["ausgaenge"]["norden"])
Die Ausgabe lautet:
bibliothek
Genau diese Verschachtelung nutzen wir gleich, um die gesamte Dungeon-Welt zu beschreiben.
Sets: ungeordnet und ohne Duplikate
Ein Set ist eine Sammlung, in der jeder Wert höchstens einmal vorkommt.
besuchte_raeume = {"halle", "bibliothek", "halle"}
print(besuchte_raeume)
Obwohl "halle" zweimal angegeben wurde, ist der Wert im Set nur einmal
enthalten:
{'halle', 'bibliothek'}
Die Reihenfolge der Ausgabe kann variieren. Sets sind nicht dafür gedacht, Elemente über eine feste Position oder einen Index abzurufen.
Werte hinzufügen
Mit .add(...) fügst Du einem Set einen Wert hinzu:
besuchte_raeume.add("krypta")
Wird derselbe Wert erneut hinzugefügt, verändert sich das Set nicht:
besuchte_raeume.add("krypta")
"krypta" bleibt trotzdem nur einmal enthalten.
Mitgliedschaft prüfen
Auch bei Sets verwendest Du in:
if "krypta" in besuchte_raeume:
print("Du warst bereits in der Krypta.")
Solche Prüfungen sind bei Sets besonders effizient. Sie eignen sich deshalb gut für Dinge wie:
- bereits besuchte Räume
- freigeschaltete Fähigkeiten
- bekannte Zaubersprüche
- einmalige IDs
Ein leeres Set anlegen
Ein leeres Set wird mit set() erzeugt:
besuchte_raeume = set()
Leere geschweifte Klammern erzeugen dagegen ein Dictionary:
leere_sammlung = {}
print(type(leere_sammlung))
Die Ausgabe lautet:
<class 'dict'>
Welche Collection passt wozu?
| Collection | Geordnet | Veränderbar | Duplikate | Zugriff |
|---|---|---|---|---|
| Liste | ja | ja | ja | über Index |
| Tupel | ja | nein | ja | über Index |
| Dictionary | ja | ja | Schlüssel eindeutig | über Schlüssel |
| Set | keine garantierte Reihenfolge | ja | nein | über Mitgliedschaft |
Für unseren Dungeon verwenden wir:
- ein Dictionary für den Player State
- eine Liste für das Inventar
- ein Dictionary für die Räume
- ein Dictionary für die Ausgänge jedes Raums
- eine Liste für die Gegenstände in einem Raum
- ein Set für bereits besuchte Räume
Die Dungeon-Welt als Daten
Bisher steckte die Welt direkt in der Programmlogik:
if befehl == "norden":
print("Du stehst vor einer verschlossenen Tür.")
elif befehl == "osten":
print("Im Osten wartet ein Goblin.")
Jeder neue Raum erforderte dadurch weitere Bedingungen.
Stattdessen beschreiben wir die Welt nun in einem großen Dictionary:
raeume = {
"halle": {
"name": "Halle",
"beschreibung": "Du stehst in einer dunklen Halle mit moderigem Geruch.",
"ausgaenge": {
"norden": "bibliothek",
"osten": "krypta",
},
"gegenstaende": ["Fackel"],
},
"bibliothek": {
"name": "Bibliothek",
"beschreibung": "Staubige Regale voller zerfledderter Bücher umgeben Dich.",
"ausgaenge": {
"sueden": "halle",
},
"gegenstaende": ["Schlüssel"],
},
"krypta": {
"name": "Krypta",
"beschreibung": "Feuchtigkeit glänzt auf den Wänden der alten Krypta.",
"ausgaenge": {
"westen": "halle",
},
"gegenstaende": [],
},
}
Die Schlüssel "halle", "bibliothek" und "krypta" sind interne IDs der
Räume. Jeder Raum ist wiederum ein Dictionary mit vier Einträgen:
namebeschreibungausgaengegegenstaende
Die Ausgänge bilden Richtungen auf die ID des jeweiligen Zielraums ab:
"ausgaenge": {
"norden": "bibliothek",
"osten": "krypta",
}
Dadurch müssen wir nicht mehr für jede Richtung einen eigenen elif-Block
schreiben.
Den Player State gruppieren
Auch der Player State besteht inzwischen aus mehreren zusammengehörigen Werten:
name = "Karl"
hp = 100
max_hp = 100
gold = 50
inventar = []
Diese Werte können wir ebenfalls in einem Dictionary gruppieren:
spieler = {
"name": "Karl",
"hp": 100,
"max_hp": 100,
"gold": 50,
"inventar": [],
}
Der Zugriff erfolgt nun über die jeweiligen Schlüssel:
print(spieler["name"])
print(spieler["hp"])
print(spieler["inventar"])
So ist sofort erkennbar, dass diese Werte zum Player State gehören.
Der Dungeon, Schritt 4
Öffne dungeon.py und ersetze den bisherigen Inhalt durch folgenden Code:
# Dungeon – Teil 4: Collections und Welt als Daten
raeume = {
"halle": {
"name": "Halle",
"beschreibung": "Du stehst in einer dunklen Halle mit moderigem Geruch.",
"ausgaenge": {
"norden": "bibliothek",
"osten": "krypta",
},
"gegenstaende": ["Fackel"],
},
"bibliothek": {
"name": "Bibliothek",
"beschreibung": "Staubige Regale voller zerfledderter Bücher umgeben Dich.",
"ausgaenge": {
"sueden": "halle",
},
"gegenstaende": ["Schlüssel"],
},
"krypta": {
"name": "Krypta",
"beschreibung": "Feuchtigkeit glänzt auf den Wänden der alten Krypta.",
"ausgaenge": {
"westen": "halle",
},
"gegenstaende": [],
},
}
print("Du stehst vor dem rostigen Tor eines vergessenen Verlieses.")
print("Ein kalter Luftzug weht Dir entgegen.")
spieler = {
"name": input("Wie heißt Du, Abenteurer? ").strip(),
"hp": 100,
"max_hp": 100,
"gold": int(input("Wie viele Goldmünzen bringst Du mit? ")),
"inventar": [],
}
ort = "halle"
besuchte_raeume = set()
raum_anzeigen = True
print()
print(f"Willkommen, {spieler['name']}!")
print("Befehle: umsehen, nimm, inventar, status, ende")
while True:
raum = raeume[ort]
if raum_anzeigen:
besuchte_raeume.add(ort)
print()
print(raum["beschreibung"])
print("Ausgänge:", ", ".join(raum["ausgaenge"]))
raum_anzeigen = False
befehl = input("\n> ").strip().lower()
if befehl == "ende":
print("Du verlässt das Verlies. Bis zum nächsten Mal.")
break
elif befehl == "umsehen":
if raum["gegenstaende"]:
print("Hier liegt:", ", ".join(raum["gegenstaende"]))
else:
print("Hier liegt nichts Brauchbares.")
elif befehl == "nimm":
if raum["gegenstaende"]:
gefundene_gegenstaende = ", ".join(raum["gegenstaende"])
spieler["inventar"].extend(raum["gegenstaende"])
raum["gegenstaende"].clear()
print(f"Du nimmst: {gefundene_gegenstaende}")
else:
print("Hier gibt es nichts zu nehmen.")
elif befehl == "inventar":
if spieler["inventar"]:
print("Inventar:", ", ".join(spieler["inventar"]))
else:
print("Dein Inventar ist leer.")
elif befehl == "status":
print(
f"{spieler['name']} | "
f"HP: {spieler['hp']}/{spieler['max_hp']} | "
f"Gold: {spieler['gold']}"
)
print(f"Besuchte Räume: {len(besuchte_raeume)}")
print(f"Gegenstände: {len(spieler['inventar'])}")
elif befehl in raum["ausgaenge"]:
ort = raum["ausgaenge"][befehl]
raum_anzeigen = True
else:
print("Das geht hier nicht.")
print("Mögliche Ausgänge:", ", ".join(raum["ausgaenge"]))
print("Weitere Befehle: umsehen, nimm, inventar, status, ende")
Führe das Programm aus:
python dungeon.py
Ein möglicher Durchlauf sieht so aus:
Du stehst vor dem rostigen Tor eines vergessenen Verlieses.
Ein kalter Luftzug weht Dir entgegen.
Wie heißt Du, Abenteurer? Karl
Wie viele Goldmünzen bringst Du mit? 50
Willkommen, Karl!
Befehle: umsehen, nimm, inventar, status, ende
Du stehst in einer dunklen Halle mit moderigem Geruch.
Ausgänge: norden, osten
> umsehen
Hier liegt: Fackel
> nimm
Du nimmst: Fackel
> norden
Staubige Regale voller zerfledderter Bücher umgeben Dich.
Ausgänge: sueden
> nimm
Du nimmst: Schlüssel
> inventar
Inventar: Fackel, Schlüssel
> status
Karl | HP: 100/100 | Gold: 50
Besuchte Räume: 2
Gegenstände: 2
> ende
Du verlässt das Verlies. Bis zum nächsten Mal.
Was im neuen Game-Loop passiert
Der Player State wird nun in einem Dictionary gespeichert:
spieler = {
"name": input("Wie heißt Du, Abenteurer? ").strip(),
"hp": 100,
"max_hp": 100,
"gold": int(input("Wie viele Goldmünzen bringst Du mit? ")),
"inventar": [],
}
Das Inventar ist eine Liste innerhalb dieses Dictionaries:
spieler["inventar"]
Der aktuelle Raum wird weiterhin über die Variable ort gespeichert:
ort = "halle"
Mit diesem Wert holen wir das Dictionary des aktuellen Raums aus der Welt:
raum = raeume[ort]
Enthält ort den String "halle", entspricht das diesem Zugriff:
raum = raeume["halle"]
Die Variable raum verweist anschließend auf das Dictionary der Halle.
Bereits besuchte Räume speichern
Das Set besuchte_raeume beginnt leer:
besuchte_raeume = set()
Sobald ein Raum angezeigt wird, fügen wir seine ID hinzu:
besuchte_raeume.add(ort)
Besucht der Spieler denselben Raum später erneut, bleibt er trotzdem nur einmal
im Set. Mit len(...) erhalten wir deshalb die Anzahl der unterschiedlichen
Räume, die der Spieler bereits betreten hat.
Räume nur nach einem Wechsel anzeigen
Die bool-Variable raum_anzeigen bestimmt, ob die Beschreibung des aktuellen
Raums ausgegeben werden soll:
raum_anzeigen = True
Nach der Ausgabe setzen wir sie auf False:
raum_anzeigen = False
Dadurch wird der Raum nicht nach jedem Befehl erneut beschrieben.
Wechselt der Spieler in einen anderen Raum, setzen wir sie wieder auf True:
ort = raum["ausgaenge"][befehl]
raum_anzeigen = True
Beim nächsten Durchlauf des Game-Loops erscheint dann die Beschreibung des neuen Raums.
Gültige Richtungen erkennen
Dieser Vergleich prüft, ob der Input einem Schlüssel im Dictionary der Ausgänge entspricht:
elif befehl in raum["ausgaenge"]:
Befindet sich der Spieler in der Halle, enthält das Dictionary diese Schlüssel:
{
"norden": "bibliothek",
"osten": "krypta",
}
Die Befehle "norden" und "osten" sind dort deshalb gültig.
Das Ziel der gewählten Richtung erhalten wir mit:
ort = raum["ausgaenge"][befehl]
Gibt der Spieler "norden" ein, entspricht das:
ort = raum["ausgaenge"]["norden"]
Der neue Wert von ort lautet anschließend "bibliothek".
Die Bewegung durch den Dungeon benötigt damit keine eigene Bedingung mehr für jede Richtung. Sie besteht nur noch aus einem Dictionary-Zugriff.
Gegenstände aufnehmen
Die Gegenstände des aktuellen Raums liegen in einer Liste:
raum["gegenstaende"]
Mit extend(...) übernehmen wir alle Elemente dieser Liste in das Inventar:
spieler["inventar"].extend(raum["gegenstaende"])
Danach leeren wir die Liste des Raums:
raum["gegenstaende"].clear()
Die Gegenstände befinden sich nun im Inventar und können nicht erneut aufgenommen werden.
Listen als String ausgeben
Die Methode join(...) verbindet mehrere Strings zu einem gemeinsamen String:
", ".join(spieler["inventar"])
Aus
["Fackel", "Schlüssel"]
wird dadurch:
Fackel, Schlüssel
Der String vor .join(...) bestimmt, was zwischen die einzelnen Elemente
gesetzt wird. In diesem Fall ist es ein Komma mit anschließendem Leerzeichen.
join(...) funktioniert nur, wenn alle Elemente Strings sind. Eine Liste mit
Zahlen müsste vorher entsprechend umgewandelt werden.
Daten und Logik trennen
Der wichtigste Fortschritt dieses Teils ist nicht eine einzelne Methode, sondern die neue Struktur des Programms.
Die Räume werden als Daten beschrieben:
raeume = {
...
}
Der Game-Loop enthält dagegen die Logik, die mit diesen Daten arbeitet:
while True:
...
Möchtest Du einen weiteren Raum hinzufügen, musst Du nicht mehr den kompletten
Game-Loop verändern. Du ergänzt lediglich das Dictionary raeume und verbindest
den neuen Raum über die Ausgänge mit der vorhandenen Welt.
Diese Trennung macht das Programm übersichtlicher und erleichtert spätere Erweiterungen.
Stolperfallen
-
Bei
0zu zählen vergessen: Eine Liste mit drei Elementen besitzt die Indizes0,1und2. Ein Zugriff aufinventar[3]führt zu einemIndexError. -
Einen fehlenden Dictionary-Schlüssel verwenden: Ein Zugriff wie
raum["monster"]führt zu einemKeyError, wenn der Schlüssel nicht existiert. Mitraum.get("monster")erhältst Du stattdessenNone. -
Liste und Dictionary verwechseln: Auf Listen greifst Du mit numerischen Indizes zu, auf Dictionaries mit ihren Schlüsseln.
python
inventar[0]
raum["beschreibung"]
-
append(...)undextend(...)verwechseln:append(...)fügt einen Wert hinzu.extend(...)übernimmt die einzelnen Elemente einer anderen Collection. -
Ein leeres Set mit
{}anlegen:{}erzeugt ein leeres Dictionary. Für ein leeres Set benötigst Duset(). -
Von einer festen Set-Reihenfolge ausgehen: Sets besitzen keine für Deine Programmlogik verlässliche Reihenfolge. Verwende eine Liste, wenn die Position der Elemente wichtig ist.
-
Zahlen direkt mit
join(...)verbinden:join(...)erwartet Strings.", ".join([1, 2, 3])führt deshalb zu einemTypeError. -
Umlaute in Befehlen übersehen: Im Code verwenden wir für die südliche Richtung bewusst
"sueden", damit sie ohne Umlaut eingegeben werden kann.
Übungen
1. Eine Schatzkammer ergänzen
Füge dem Verlies einen vierten Raum namens "schatzkammer" hinzu. Er soll von
der Bibliothek aus nach Norden erreichbar sein und einen "Goldhaufen"
enthalten.
Lösung
Ergänze das Dictionary `raeume` um folgenden Eintrag:"schatzkammer": {
"name": "Schatzkammer",
"beschreibung": "Gold und Edelsteine glitzern im Licht Deiner Fackel.",
"ausgaenge": {
"sueden": "bibliothek",
},
"gegenstaende": ["Goldhaufen"],
},
"ausgaenge": {
"sueden": "halle",
"norden": "schatzkammer",
},
2. Einen Startgegenstand hinzufügen
Gib dem Spieler zu Beginn ein Stück Brot. Das Inventar soll also nicht mehr leer starten.
Lösung
Ändere den Eintrag `inventar` im Player State:spieler = {
"name": input("Wie heißt Du, Abenteurer? ").strip(),
"hp": 100,
"max_hp": 100,
"gold": int(input("Wie viele Goldmünzen bringst Du mit? ")),
"inventar": ["Brot"],
}
3. Alle Ausgänge eines Raums ausgeben
Schreibe eine for-Schleife, die alle Richtungen und Zielräume der Halle
ausgibt.
Die Ausgabe soll ungefähr so aussehen:
norden -> bibliothek
osten -> krypta
Lösung
halle = raeume["halle"]
for richtung, ziel in halle["ausgaenge"].items():
print(f"{richtung} -> {ziel}")
Im nächsten Teil
Die Welt ist jetzt sauber als Daten beschrieben. Der Game-Loop ist durch die vielen Befehle allerdings weiterhin recht lang.
In Teil 5 lernst Du deshalb Funktionen kennen. Damit zerlegen wir die Logik in benannte, wiederverwendbare Blöcke und machen den Game-Loop wieder übersichtlich.
0 Kommentare
Noch keine Kommentare. Sei der/die Erste!
Anmelden um einen Kommentar zu hinterlassen.