(Originaltext ist hier: https://gist.github.com/2391632)
Diese wenig kreative Geschichte soll als Beispiel dienen:
Das ist erst einmal eine ganze Menge.Wir stehen vor einer alten trutzigen Burg mit hohen Mauern und tiefem Graben und haben ein Seil und Brot dabei. Von dort können wir über eine Zugbrücke in den verfallenen Burghof gehen. Vögel flattern auf und wir treffen Hugo, der bewaffnet mit einem Schwert, nicht wagt, in die Kellergewölbe zu gehen. Wir können den Burgfried besteigen und finden dort Ratten, die ein Nest bewachen, in der eine Kiste mit Silbermünzen liegt. Mit dem Brot können wir die Ratten weglocken und die Münzen nehmen. (Alternativ können wir unser Seil nehmen, um das Dach des Turms zu erreichen, von wo aus wir direkt an die Münzen kommen, allerdings ist nun das Seil weg.) Andernfalls greifen die Ratten an, was beim dritten Biss zu unserem Tod führt. Es heißt also fliehen. Die Ratten werden nicht in den Burghof folgen. Die Münzen können wir Hugo geben und sein Schwert bekommen, mit dem wir in den Kellergewölbe steigen können und dort gegen einen Kobold kämpfen, der eine Falltür bewacht. Ohne Schwert wird er angreifen und uns töten, wenn wir nicht sofort weglaufen. Der Kobold hat einen Schlüssel dabei, den wir nur nehmen können, wenn er besiegt ist und damit die Tür aufschließen, die zu einem Tempelraum führt, den wir mit unserem Seil erreichen können (sonst müssen wir springen). Dort ist ein blutiger Altar, auf dem ein goldener sechszackiger Stern liegt. Nehmen wir den Stern (er ist wertvoll), haben wir in der PG13-Version gewonnen. Andernfalls reißt nun der Boden auf und eine dämonische Monstrosität erscheint, die nicht besiegt werden kann und uns tötet, wenn wir nicht fliehen. Das können wir nur, wenn wir das Seil noch haben. Der Dämon wird Hugo töten, der noch ruft, "lasst das Wesen nicht entkommen" und nun kann man die Zugbrücke hochkurbeln, wodurch das Wesen eingesperrt wird, allerdings mit uns zusammen...
Grundsätzlich gibt Schauplätze (gerne auch Räume genannt) wie den Burghof oder der Tempelraum, Gegenstände wie die Kiste mit Münzen oder das Schwert und Personen (oder Kreaturen) wie Hugo, der Kobold oder die Ratten.
Räume sind miteinander verbunden und wir, als Spielende, befinden uns immer in einem Raum. Gegenstände sind in einem Raum, in einem anderen Gegenstand (die Münzen in der Kiste) oder "in" einer Person. Personen sind (wie wir) immer in einem Raum. Wir können einen Raum wechseln, Gegenstände nehmen, weglegen oder benutzen und mit Personen interagieren, indem wir sie ansprechen, angreifen oder ihnen etwas geben.
Wir können das Spiel auf zwei Arten in Python implementieren: Entweder direkt oder als Rahmenwerk, mit derartige Spiele über eine spezielle (sogenannte Domänen-spezifische Sprache, englisch "DSL") beschrieben werden können und dann von unserem Python-Programm interpretiert werden. Um mehr über die "Domäne" zu lernen, wollen wir zunächst den einfacheren direkten Weg wählen.
Beginnen wir mit einer Klasse Room (ich werde das Programm englisch halten), mit deren Exemplaren wir die Schauplätze beschreiben können. Jeder Schauplatz hat einen Namen, eine Beschreibung und Verbindungen zu weiteren Räumen, die wir mit Himmelsrichtungen (oder "oben" / "unten") beschreiben wollen.
Code: Alles auswählen
class Room:
def __init__(self, name, description):
self.name = name
self.description = description
self.exits = {}
# define all rooms
vor_der_burg = Room("Vor der Burg",
"Vor dir ragt eine alte trutzige Burg auf, das Ziel deiner tagelangen "
"Reise durch die Wälder von Mordag. Im Norden führt eine herabgelassene "
"Zugbrücke zu einem düsteren Burghof. Es ist still hier. Sehr still.")
burghof = Room("Der Burghof",
"Die hohen Mauern lassen nur weg Licht der untergehenden Sonne hinein. "
"Der Hof ist unübersichtlich. Im Laufe der Jahrhunderte hat sich hier "
"viel Schutt und Müll angesammelt. Doch im Westen führt ein Tor in den "
"Burgfried. Alle anderen Zugänge scheinen verschüttet zu sein.")
burgfried = Room("Der Burgfried",
"Hier ist es richtig dunkel. Wie praktisch wäre jetzt ein Licht. Nach "
"einige Treppen kommt ein kleiner Raum, in dem es entsetzlich stinkt. "
"Wäre die restliche Treppe nicht eingestürzt, ginge es hier zum Dach.")
# all directions
directions = ("norden", "osten", "süden", "westen", "oben", "unten")
# connect rooms
vor_der_burg.exits["norden"] = burghof
burghof.exits["süden"] = vor_der_burg
burghof.exits["westen"] = burgfried
burgfried.exits["osten"] = burghof
Ich bin unschlüssig, ob ich das Spiel als Exemplar einer Klasse Game modellieren soll oder einfach eine globale Variable und Funktionen benutzen soll. Ich glaube, letzteres ist für den Anfang einfacher.
Code: Alles auswählen
# the current room
current_room = None
def enter_room(room):
global current_room
current_room = room
describe_room()
def describe_room():
emit()
emit(current_room.name); emit()
emit(current_room.description); emit()
Code: Alles auswählen
def emit(s="", width=80):
column = 0
for word in str(s).split():
column += len(word) + 1
if column > width:
column = len(word) + 1
print()
print(word, end=" ")
print()
Um das Spiel durchzuführen, setzen wir den Startschauplatz und verarbeiten dann in einer Schleife die Befehle, die wir mittels input (ich benutze Python 3.2, bei Python 2.7 wäre es raw_input) einlesen. Wird "ende" eingeben, beende ich das Spiel.
Code: Alles auswählen
def play():
enter_room(vor_der_burg)
while execute_command():
pass
def execute_command():
words = read_command()
if words:
if words[0] in ("gehe", "geh"):
if len(words) > 2 and words[1] == "nach":
execute_go(words[2])
elif len(words) > 1:
execute_go(words[1])
else:
emit("Wohin soll ich gehen?")
elif words[0] == "ende":
return False
else:
emit("Ich verstehe '%s' nicht." % "".join(words))
return True
def read_command():
return [word.lower() for word in input("? ").rstrip(".?!").split()]
In execute_go prüfe ich dann, ob es vom aktuellen Raum aus eine Verbindung in die angegebene Richtung gibt. Falls ja, werden wir diesen Raum betreten. Andernfalls wird ein Fehler angezeigt:
Code: Alles auswählen
def execute_go(direction):
room = current_room.exits.get(direction)
if room:
enter_room(room)
else:
emit("Du kannst nicht nach '%s' gehen." % direction)
Code: Alles auswählen
Vor der Burg
Vor dir ragt eine alte trutzige Burg auf, das Ziel deiner tagelangen Reise
durch die Wälder von Mordag. Im Norden führt eine herabgelassene Zugbrücke zu
einem düsteren Burghof. Es ist still hier. Sehr still.
? geh nach norden
Der Burghof
Die hohen Mauern lassen nur weg Licht der untergehenden Sonne hinein. Der Hof
ist unübersichtlich. Im Laufe der Jahrhunderte hat sich hier viel Schutt und
Müll angesammelt. Doch im Westen führt ein Tor in den Burgfried. Alle anderen
Zugänge scheinen verschüttet zu sein.
Code: Alles auswählen
def execute_command():
words = read_command()
if words:
if words[0] in ("gehe", "geh"):
...
elif words[0] in directions:
execute_go(words[0])
...
return True
Noch eine Kleinigkeit: Da ich schon alt und vergesslich bin, möchte ich mir die Beschreibung eines Raums auch per Befehl anzeigen lassen können:
Code: Alles auswählen
def execute_command():
...
elif words[0] in ("schaue", "schau", "beschreibung"):
describe_room()
Stefan