next up previous contents index
Next: Das Betreten des Rasens Up: Schritt für Schritt ins Previous: Und was hängt an

Subsections


,,... allerlei Bäume, lustig anzusehen ...''

Räume und Bäume aller Klassen.

Die Mitte des Gartens haben wir; jetzt muss aber noch etwas Landschaft außen herum. Weil der Garten überall irgendwie ähnlich aussieht, definieren wir gemeinsame Eigenschaften aller Gartenteile in einer Klasse:

Class Garten 

 with short_name "Im Garten Eden",  
      description "Du bist im Garten Eden. Ringsum sind Beete,  
                   Obstbäume, Gebüsche; alles ist gepflegt und  
                   feierlich. ",  
      in_to "Du bist bereits im Garten Eden.",  
      u_to Mitte,  
      cant_go "Du gehst einige Schritte im Garten umher.",  
 has  light;

Mit dem Schlüsselwort Class wird kein Objekt definiert, sondern eine Art Vorlage für mehrere ähnliche Objekte. Darauf aufbauend können mit wenig Zeilen die tatsächlichen Objekte geschrieben werden, hier z.B der östliche Gartenteil:

Object EdenE 
 class Garten 
 with  s_to EdenSE, 
       n_to EdenNE,  
       sw_to EdenS, 
       nw_to EdenN,  
       w_to Mitte;
Mit der Zeile class Garten ,,holen'' wir alle in der Klasse definierten Eigenschaften (Attribute und properties) in unser neues Objekt, ohne sie ein zweites Mal schreiben zu müssen.19

Die properties auf _to legen fest, was passiert, wenn man aus einem Raum in eine bestimmte Richtung (eine der acht Kompasshaupt- und Nebenrichtungen n, w, s, e (steht für Osten!)20, nw, sw, ne, se, in, out, u (hinauf) und d (hinunter) geht: Steht darin der Name eines anderen Raumobjekts, dann geht es dorthin; steht ein String darin, wird der String ausgegeben und der Spieler bleibt, wo er war. Die property cant_go hat dieselbe Funktion für jede Richtung, die das Objekt nicht ausdrücklich definiert.

Damit die Bewegung in beide Richtungen funktioniert, muss sie in den Objekten auf ,,beiden Seiten'' festgelegt sein. Das heißt hier, dass auch die Definition von Mitte erweitert werden muss, damit man von dort wirklich in alle Richtungen gehen kann:

w_to EdenW,  
sw_to EdenSW,  
s_to EdenS,  
se_to EdenSE,  
e_to EdenE,  
ne_to EdenNE,  
n_to EdenN,  
nw_to EdenNW,
Eine in der Klasse vordefinierte property kann in der Objektdefinition problemlos überschrieben werden. Bestimmte properties (z.B. before und after) sind aber additiv, d.h. dass zuerst die in der Objektdefinition angegebenen Regeln abgearbeitet werden, wenn keine davon ein true zurückgegeben hat, werden noch die Regeln der Klassendefinition durchgeprüft.

Bei Attributen gibt es eine Besonderheit: male und female überschreiben einander und neuter; neuter überschreibt die beiden anderen aber nicht (man muss also ~male neuter schreiben, um im Objekt ein von der Klasse geerbtes male auszuschlagen).

Weil es so schön ist, folgen noch drei Klassen:

Class Baum  
with  name 'baum' 'baeume' 'obstbaum' 'obstbaeume',  
      dekl 1,  
      description "Die Bäume sind lustig anzusehen.  
                   Sie tragen Früchte.",  
      before [;  
               lift, push, pull, empty, burn, cut, squeeze:  
                "Du sollst den Garten hüten und nicht in ihm  
                 randalieren.";  
               search: <<examine self>>;  
               climb: "Du hörst die Stimme eines Engels:  
                       ~Denk' an den Anteil der Arbeit an der  
                       Menschwerdung des Affen!~ und überlegst  
                       dir, dass es jetzt noch etwas zu früh ist,  
                       zurück auf die Bäume zu klettern.";  
              ],  
has  scenery male;
Neu ist hier der Befehl <<examine self>>; es handelt sich wieder um eine Kurzschreibweise; nämlich für die Befehlsfolge <examine self>; return true; . Mit <examine self> (in einfachen spitzen Klammern) wird eine Aktion ausgelöst und derselbe Ablauf bewirkt, als hätte der Spieler selbst ,,Untersuche den Baum'' eingegeben.

Der vorhin definierte Apfelbaum sollte auch mit der Zeile class Baum das allgemeine Verhalten eines Baums vererbt bekommen. (Die description überschreibt er allerdings.)

Class Obst  
with  name 'Frucht' 'Fruechte' 'Obst',  
      short_name "Frucht",  
      dekl 7,  
      before [;  
               examine:  
                 print_ret  
                   (GDer) self, " sieht lecker aus.  
                    Du bekommst Appetit.";  
               eat, remove, transfer, take, taste:  
                 print_ret 
                  "Du pflückst ", (einen) self, ". ",  
                   (GEr) self, " ist so appetitlich, dass du  
                   nicht widerstehen kannst und ", (ihn) self ,  
                   " auf der Stelle verspeist. ", (GEr) self,  
                   " ist gut zu essen und schmeckt köstlich.";  
             ],  
 has  female;
und

Class Blume

 with short_name "Blume",

      dekl 9,

      name 'bluete' 'blume' 'blueten',

      before [;

        smell: print_ret (GDer) self, " duftet angenehm.";

        touch: "Du fühlst eine zarte Pflanze.";

      ],

      initial [; print_ret (GEin) self, " blüht auf der Wiese.";],

 has  female;

Ausgeben von Texten

Der Befehl print_ret ist ebenso wie das schon bekannte "..." eine weitere Kurzschreibweise für - wer weiß es noch? - print "..." ; new_line; return true;

Wir verwenden hier print_ret statt "...", weil nicht nur einfach ein String, sondern ein ganzer Satz, bestehend aus mehreren Strings und Ausgaberegeln ausgegeben werden soll (die einzelnen Elemente können in beliebiger Anzahl und Reihenfolge hinter print_ret folgen, sie werden durch Kommata getrennt, am Schluss folgt wie immer ein Strichpunkt). Da bei der zweiten Ausgabeanweisung als erstes Element ein in Anführungszeichen geschriebener String kommt, könnte dieser auch in seiner Funktion als Kurzschreibweise für print_ret benutzt und also das zweite print_ret einfach weggelassen werden.

Ausgaberegeln
sind in Klammern geschriebene Funktionsnamen, gefolgt von einem Objekt. (Für eine Übersicht der Ausgaberegeln siehe 3.2.5.) Sie bewirken, dass das Objekt mit dem passenden Artikel bzw. passenden Pronomen ausgegeben wird: (GDer) self gibt den bestimmten Artikel und den Objektnamen im Nominativ aus, es wird für den Apfel zu ,,Der Apfel'', für die Birne zu ,,Die Birne'' und für das Johannisbrot zu ,,Das Johannisbrot'' (das G am Anfang steht für Großschreibung).

Von der Klasse zum Objekt

Mit diesen Klassen läßt sich der Garten so flott ausstatten, als wären es in Zaubertrank gefallene Eicheln, bzw. Carobs:

Object  Johannisbrot EdenE  
 class  Obst  
 with   short_name "Johannisbrot",  
        dekl 1,  
        initial "Hier stehen die Johannisbrotbäume.",  
        name 'johannisb' 'brot' ,  
 has    ~female neuter;
bzw.

Object  Primel EdenW

 class  Blume

 with   short_name "Primel",

        name 'primel' 'schluessel' 'bluete' 'blueten' 'winzig' 'gelb' 'klein',

        description "Eine kleine Primel, auch Schlüsselblume genannt. Sie hat

                     viele winzige gelbe Blüten.";

Beachte: Hier haben wir keinen Pfeil -> verwendet, um den Ort des Objekts im Spiel festzulegen. Statt dessen ist der parent des Objekts - EdenE - explizit im Kopf der Definition angegeben. Diese Schreibweise ist weniger fehleranfällig und deshalb vorzuziehen.



Footnotes

...19
Dieser Vorgang wird üblicherweise ,,Erben'' genannt (das Objekt erbt alle Eigenschaften der Klasse), was aber eigentlich nicht passt, da die Klasse damit nicht etwa tot ist, sondern beliebig oft verwendet werden kann.
...20
Der Name EdenE ist willkürlich; ich habe den um die Mitte liegenden Gartenteilen solche Namen gegeben, um den Überblick zu behalten.

next up previous contents index
Next: Das Betreten des Rasens Up: Schritt für Schritt ins Previous: Und was hängt an
Frank Borger
2003-05-02