________________________________________________________________________
[<<] [Inhalt] [>>] II. Definitionen

5. Programmieren der Ausführungsblöcke

5.1.   Arten von Aktionen
5.2.   Grundprozeduren und -funktionen
5.3.   Bedingungen

5.1. Arten von Aktionen

Aktionen sind Folgen von Anweisungen, die Objekte, Räume oder den Spieler verändern. Aktionen können definiert werden als

  • Bestandteile von Befehlen,
  • Ergänzungen von bereits in TAG vorhandenen Befehlen,
  • Ausführungsblöcke von Räumen und Objekten,
  • Wege und
  • frei definierte Aktionen

Die Aktionen werden sequentiell abgearbeitet. Dabei steht in jeder Zeile eine Anweisung. Nachfolgend werden die Standardprozeduren erläutert. Für die Variablen in den Beschreibungen gilt:

Obj     Objekt
Dies kann ein benutzerdefiniertes Objekt oder eine Objektvariable sein.

Raum gültiger Raumname.

Ort Ortsbezeichnung
Dies kann ein Raumname, ein Verhältniswort mit einem nachfolgenden Objekt oder eines der Schlüssselworte hier, BeiMir oder angezogen sein.

Attr Attribut
Je nachdem, worauf sich das Attribut bezieht, kann es ein Objekt- oder ein Raumattribut sein.

Zust Zustandsbezeichner

Flg Beliebige Flagge
Dies kann eine benutzerdefinierte Flagge, eine Systemflagge wie Inv oder NullAkt, oder eine der Objektvariablen wie Gew, Vol oder Spez sein, die dem Objekt mit einem Punkt versehen angehängt werden: aObj.Gew, Lampe.Zust usw.

Block Textblock-ID (Zahl von 0 bis 255)

Text ist ein Text, der in einfache Anführungszeichen eingeschlossen ist, und der über mehrere Zeilen gehen kann. Die Regeln, die ein solcher Text erfüllen muß, sind in Kapitel 7 erklärt.

Alle anderen Bezeichner sind ganze Zahlen.

5.2. Grundprozeduren und -funktionen

Zur Erleichterung des Programmierens sind schon einige Grundprozeduren vorhanden, die hier kurz erklärt werden:

5.2.1. Textprozeduren

Das wichtigste Element in einem Text-Adventure sind wohl die Texte, die auf dem Bildschirm ausgegeben werden sollen. Daher sollen die Befehle zur Textausgabe hier an erster Stelle stehen.

Text 'Text'
Gibt den Text zwischen den Apostrophen aus. Dieser Text kann über mehrere Zeilen gehen und Textbefehle enthalten. Dabei werden die Zeilen mitgezählt, damit das Fortsetzungszeichen erscheint, wenn der Bildschirm voll ist. Zum Format von Texten und den darin enthaltenen Textbefehlen siehe Kapitel 7.

Text Block Nr
Gibt den Text Nr aus dem Textblock Block aus. Funktioniert wie die direkte Textangabe mit 'Text', nur, daß der Text auf einem Textblock steht. Nr kann eine Flagge oder eine ganze Zahl sein, weshalb es manchmal besser ist, den Text aus einem Textblock zu lesen.

Absatz
Beendet einen Textabsatz und beginnt einen neuen. Je nach den im Umgebungs-Block angegebenen Parametern wird dabei eine Leerzeile eingefügt und der neue Absatz eingerückt.

Zufallstext Block von bis
Bestimmt zufällig einen Text von von bis bis aus dem Textblock Block und gibt ihn aus. Hier können keine expliziten Texte angegeben werden, sondern nur Verweise auf einen Textblock.

Puffer 'Text'
Schreibt den angegebenen Text nur in den Meldungspuffer, der bei jeder normalen Text-Anweisung gelöscht wird. Der Text im Buffer wird nur dann geschrieben, wenn es in der Nachausführungen der Objekte und des Raums keine Textanweisung gegeben hat oder mit dem Befehl Puffer ohne Text-Angabe.

Box 'Text' Box Block Nr
Mit diesem Befehl kann ein Zitat, das entweder als String in Hoch- kommas oder durch einen Textblock Block mit der Stelle Nr angegeben wird, in einem Kasten in der Mitte des Bildschirms eingeblendet werden. Das ist Graham Nelsons Inform abgeguckt. Die Box in TAG verschwindet jedoch nach Tastendruck. Obwohl der Text wie ein normaler Ausgabetext in einem Block definiert wird, gibt es doch ein paar Besonderheiten:

  • Der Umbruch ist genau wie in der ADV-Datei, jede Zeile dort entspricht einer Zeile in der Box.
  • Die Zeilen werden nach 60 Zeichen abgeschnitten, es sind nur acht Zeilen erlaubt.
  • Es können keine Steuerzeichen in eckigen Klammern oder mit Schrägstrichen angegeben werden. Die einzigen Steuerzeichen, die mit der Box benutzt werden sollen, stehen in der ersten Spalte, und können ein '' für linksbündig, ein '' für rechtsbündig und ein '.' für zentrierten Text sein. Ist das erste Zeichen einer Zeile keins dieser Zeichen, so wird linksbündig geschrieben.

Zum Beispiel:

        Box '.Gruselett

        Der Flügelflagel gaustert
        durchs Wiruwaruwolz,
        die rote Fingur plaustert
        und grausig gutzt der Golz.

        >Chr. Morgenstern'
        

Die Farbe der Textbox ist die Rahmenfarbe.

5.2.2. Variablenzuweisungen

Zur Zuweisung von Variablen stehen folgende allgemeinen Prozeduren zur Verfügung, die anstelle der in den meisten Programmiersprachen üblichen Zuweisungen der Form x = y verwendet werden können:

Sei Flg1 Flg2
Weist der Flagge oder der Variable Flg1 den Wert von Flg2 zu. Flg2 kann natürlich auch ein Zahlenwert sein.

Inkr Flg1 Flg2
Erhöht den Wert der Flagge Flg1 um den Wert von Flg2. Wenn Flg2 weggelassen wird, wird Flg1 um 1 erhöht.

Dekr Flg1 Flg2
Erniedrigt den Wert der Flagge Flg1 um den Wert von Flg2. Wenn Flg2 weggelassen wird, wird Flg1 um 1 erniedrigt.

Mult Flg1 Flg2
Multipliziert den Wert der Flagge Flg1 mit dem Wert von Flg2. Achtung! Da TAG nur mit Bytes arbeitet, sollte sichergestellt sein, daß das Produkt nicht größer als 255 ist. (Es sei denn, es werden Integer-Variablen benutzt.)

Div Flg1 Flg2
Dividiert den Wert der Flagge Flg1 durch den Wert von Flg2. Es ist eine ganzzahlige Division, bei der der Rest weggelassen wird, z.B. 7 div 3 = 2.

Mod Flg1 Flg2
Weist der Flagge Flg1 den Rest der Division von Flg1 durch Flg2 zu. Zum Beispiel ist 7 mod 3 = 1.

Anmerkung:
TAG erlaubt nicht, wie die meisten Programmiersprachen, Ausdrücke wie x = y*8 + z. Stattdessen müssen diese Anweisungen nacheiander durch die obenstehenden ausgedrückt werden. Das entspricht in etwa der Vorgehensweise, die man beim Eintippen des Ausdrucks in einen Taschenrechner anwenden würde. Der Ausdruck oben wäre also in TAG:

        Sei x y
        Mult x 8
        Inkr x z
        

Das ist zwar etwas gewöhnungsbedürftig, funktioniert aber.

Setze Flg
Weist der Flagge Flg den Wert 1 (und damit 'wahr') zu.

Lösche Flg
Weist der Flagge Flg den Wert 0 zu (d.h. 'falsch') zu.

Zufall Var von bis
Belegt die Flagge Var mit einer Zufallszahl von von bis bis. Anstelle der Flagge können auch Objekte, Räume usw. angegeben werden.

Zufall Var (x1 x2 ... xn)
Weist der Variablen Flg zufällig einen der Werte aus der Klammer zu. Hier können auch Objekte, Räume, Richtungen usw. angegeben werden. Die Werte in der Klammer müssen aber immer vom selben Typ sein wie die Variable.

BitUnd Flg1 Flg2
Verknüpft die beiden Flaggen Flg1 und Flg2 bitweise mit 'und' und weist den Wert der Verknüpfung der Variablen Flg1 zu. Bei der Und-Verknüpfung werden nur diejenigen Bits gesetzt, die in beiden Flaggen gesetzt sind. Zum Beispiel: 6 und 10 = 2 oder in binärer Schreibweise: #0110 und #1010 = #0010. (0 markiert nicht-gesetzte, 1 gesetzte Bits. Das # bezeichnet eine binäre Zahl.)

BitOder Flg1 Flg2
Verknüpft die beiden Flaggen Flg1 und Flg2 bitweise mit 'oder' und weist den Wert der Verknüpfung der Variablen Flg1 zu. Bei der Oder-Verknüpfung werden nur die Bits gesetzt, die in mindestens einer der Flaggen gesetzt sind: 6 oder 10 = 14 bzw. #0110 oder #1010 = #1110.

(Anmerkung: Die Notation #xxxx wird als binäre Zahl verstanden, wenn dem # nur Einsen und Nullen folgen. Binäre Zahlen können höchstens achtstellig sein, das Doppelkreuz wird dabei nicht mitgezählt. Man kann auch Zahlen in Hex-Notation angeben, wenn man ihnen ein $ voranstellt: $ff = 255, $c0 = 192. Hex-Zahlen können auch größer als 255 sein.)

5.2.3. Prozeduren für Räume und zur Fortbewegung

Für die Behandlung der Räume gibe es ebenfalls eine Anzahl in TAG vordefinierter Funktionen:

GeheZu Ort
Bewegt den Spieler an den genannten Ort. Ort kann ein Raumname sein oder ein Verhältniswort mit einem Objekt, z.B. 'in Sessel'.

SeiRaum RVar Raum Ritg
Belegt RVar mit dem Ausgang des Raums Raum in Richtung Ritg. Ist Null, wenn es in diese Richtung keinen Ausgang gibt.

SeiRitg RiVar Raum1 Raum2
Sucht eine Richtung, in die man von Raum1 nach Raum2 gehen kann. Gibt es mehrere Möglichkeiten, so wird die zuerst gefundene benutzt.

AttrDazu Raum Attr
Belegt den Raum Raum mit einem Raumattribut Attr.

AttrWeg Raum Attr
Entfernt ein Raumattribut Attr von einem Raum Raum.

5.2.4. Objekte

Um die Objekte hin- und herjonglieren zu können, gibt es folgende Anweisungen:

ObjNach Obj Ort
Bewegt ein Objekt an einen bestimmten Ort. Ort kann ein Raumname sein oder ein Verhältniswort mit einem Objekt, z.B. unter Bett.

Tausche Obj1 Obj2
Vertauscht die Orte der beiden Objekte Obj1 und Obj2. Das ist nützlich, wenn ein Objekt sich verändert und gegen ein anderes ausgetauscht wird, das sich nirgendwo (d.h. in keinem Raum) befindet, z.B. Tausche Vase Scherben.

ObjZust Obj Zust
Ändert den Zustand des Objekts Obj in Zust.

AttrDazu Obj Attr
Belegt das Objekt Obj mit einem Objektattribut Attr oder den Raum Raum mit einem Raumattribut Attr.

AttrWeg Obj Attr
Entfernt ein Objektattribut Attr von einem Objekt Obj oder ein Raumattribut Attr von einem Raum Raum.

MutterObj Obj1 Obj2
Ein Mutterobjekt ist ein Objekt, in dem ein anderes (Tochter-)Objekt enthalten ist. Es kann aber auch auf, unter, bei, an oder hinter dem Mutterobjekt sein. Diese Anweisung weist der Objektvariablen Obj1 das Mutterobjekt von Obj2 zu. Ist Obj2 kein Tochterobjekt oder ist Obj2 beim Spieler, soist Obj1 Null.

StammObj Obj1 Obj2
Weist Obj1 das Stammobjekt von Obj2 zu. Das Stammobjekt eines Objekts ist das Objekt, das dieses Objekt auf einer beliebigen Ebene enthält, das aber selbst kein Tochterobjekt ist. Ist Obj2 kein Tochterobjekt, so ist das Stammobjekt Obj1 gleich Obj2. Das Stammobjekt kann also nicht Null sein, wie beim Mutterobjekt.

Da dies sich das etwas kompliziert anhört, hier ein Beispiel: Auf einem Tisch steht eine Schale, darin befindet sich Obst. Das Mutterobjekt des Obstes ist die Schale, das der Schale der Tisch und der Tisch hat kein Mutterobjekt, da er dirket im Raum steht. Das Stammobjekt aller drei Objekte ist der Tisch. MutterObj bezieht sich also auf die jeweils nächste Ebene, Stammobj immer auf die unterste Ebene, d.h. auf alle Objekte, die direkt in einem Raum sind.

StammRaum Raum Obj
Weist der Raumvariablen Raum den Raum zu, in dem sich das Objekt auf einer beliebigen Ebene befindet, d.h. Raum ist der Ort des Stammobjekts von Obj. Das Stammobjekt eines Objekts ist immer direkt in einem Raum enthalten. Ist Obj bei mir, so ist der Stammraum Null.

ObjListe OVar (Bed)
Schreibt eine Objektliste aller Objekte, auf die die Bedingung zutrifft, auf die Hilfsvariable Aussage. Dies funktioniert natürlich mit einer Schleife, die OVar als Zählvariable benutzt (Wie Bedingungen genau aussehen, steht im nächsten Kapitel.) Die Anzahl der aufgezählten Objekte liegt auf der Flagge #AnzListe.

InhListe OVar Flg
Schreibt den Inhalt des Objekts OVar heraus. Je nach Flg wird eine Meldung herausgegeben, wenn OVar leer ist, und es werden darunterliegende mitbetrachtet (Rekursion). Um Sachen darin zu zeigen, muß das Objekt ein Behälter sein, um Sachen darauf zu zeigen, eine Ablage.

ObjInh Flg Obj
Belegt die Flg mit der Anzahl der Dinge, die sich in, auf, bei usw. dem Objekt befinden.

ObjGew Flg Obj
Berechnet das Gewicht von Obj und seiner Unterobjekte und schreibt es auf die Flagge Flg.

ZeigeInh Ort
Listet den Inhalt des Orts Ort auf. Ort ist ein Raumname oder ein Verhältniswort mit einem nachfolgenden Objekt.

ObjGenus Obj Sex Spez
Ändert das grammatikalische Geschlecht und/oder das Namensformat eines Objekts. Das ist nur dann nützlich, wenn der Name einen Aktionsaufruf enthält und somit veränderlich ist. Sex und Spez werden wie in der Objektdefinition angegeben.

5.2.5. Allgemeine Spielprozeduren

Diese Prozeduren sind für das allgemeine Spielgeschehen:

Stop
Beendet die Aktion sofort und setzt die Flagge NullAkt. Stop springt aus allen Schleifen und Bedingungen direkt ans Ende der Aktion.

Gestorben
Wird aufgerufen, wenn der Spieler stirbt. Es erscheint ein Text, stan- dardmäßig: 'Ich bin jetzt leider tot.' Dann werden die Punkte gezeigt und gefragt, ob neu gestartet werden, ein Spielstand geladen werden oder das Programm verlassen werden soll.

Gewonnen
Ein Text wird angezeigt, standardmäßig: 'Ich habe gewonnen!' Dann wird der Punktestand gezeigt, und das Programm verlassen. Ich nehme an, daß jemand, der soeben gewonnen hat, nicht einen alten Spielstand laden oder sogar von vorne anfangen möchte.

Punkte Pkt Wert
Ändert den Punktestand Pkt auf den Wert Wert.

ObjPunkte Obj Wert
Ändert den Punktestand des Objekts Obj auf den Wert Wert.

RaumPunkte Raum Wert
Ändert den Punktestand des Raums Raums auf den Wert Wert. Eine genaue Beschreibung des Punktesystems gibt es in Kapitel 8.

Ausf Akt
Ruft eine Aktion auf und führt sie aus. Akt kann eine benutzerdefinierte Aktion sein, ein Weg oder ein Befehl, benutzerdefiniert oder von TAG. Ist Akt ein Befehl, dann wird natürlich zuerst VorAusf, dann der Hauptausführungsteil und schließlich NachAusf abgearbeitet, wie gehabt. Es können keine Variablen übergeben werden.

Ausf Bef {aObj} {aObj2} {aObj3} {aRitg}
Führt einen Befehl aus und übergibt die Objekte und die Richtung. Die Objekte müssen dabei in derselben Reihenfolge stehen wie in der Syntax des Befehls definiert. Objekte, die nicht übergeben werden, bleiben wie sie sind. Objekte, die übergeben werden, obwohl sie in der Befehlssyntax definiert sind, bleiben unberücksichtigt. Bei der Ausführung werden alle Vor- und Nachausführungen der Objekte und des Raums berücksichtigt. Diese Anweisung ist sehr wichtig, wenn in einem Befehl andere implizit ausgeführt werden sollen oder wenn ein Befehl mit einer VorAusf 'umgelenkt' wird:

        Ausf untersuchen aObj
        Ausf gehen N
        Ausf hineinlegen aObj Truhe
        

SetzeZeit std min
Setzt die Uhrzeit std und min, die in den Sytemflaggen Stunden und Minuten abgelegt werden.

WarteZeit std min
Läßt std Stunden und min Minuten der Spielzeit verstreichen. Die Uhrzeit wird im 24-Stunden-Format ausgegeben. Wartet man um 23:55 h zwölf Minuten, so ist es danach 0:07 h. Logisch.

JaNein Flg
Fragt nach der Eingabe von 'J' oder 'N', schreibt je nach Angabe JA oder NEIN mit einem anschließenden Absatz und belegt Flg mit 0, wenn die Antwort 'N' war, mit 1 wenn sie 'J' war.

Auswahl Flg 'Tasten'
Fragt nach der Eingabe einer der Tasten, die im String Tasten enthalten sind. Flg wird dann mit der Position der Taste im String belegt. Wird die Abfrage mit Escape abgebrochen, so ist Flg Null. Ist String z.B. 'max', so ist Flg 2, wenn 'a' (oder 'A') gedrückt wurde.

5.2.6. Prozeduren zur Belegung von Feldern

Zur leichteren Handhabung der Felder gibt es folgende Prozeduren:

Daten Feld Pos (x1 {x2 x3 x4 ...})
Belegt das Feld Feld ab der Position Pos mit den Werten x.

Lese Flg Feld (Pos1 {Pos2 Pos3})
Liest den Wert des Feldes Feld an der Position Pos, je nach Dimen- sion des Feldes.

Belege Feld (Pos1 {Pos2 Pos3}) Wert
Belegt die Position Pos des Feldes Feld, je nach Dimension des Feldes mit dem Wert Wert.

FeldPos Feld Flg (Pos1 {Pos2 Pos3})
Berechnet die eindimensionale Position des Feldes nach der Dimension und der (mehrdimensionalen) Positionsangabe.

5.3. Bedingungen

Bedingungen sind Abfragen, ob ein Ereignis wahr oder falsch ist. In TAG werden Bedingungen immer in runde Klammern gesetzt. Dabei dürfen keine Klammern ineinandergeschachtelt werden. Ein Schrägstrich vor der Klammer verneint die Bedingung.

Bedingungen können miteinander verknüpft werden. Gültige Verknüpfungen sind und und oder:

Bed und Bed ist wahr, wenn beide Bedingungen wahr sind. Bed oder Bed ist wahr, wenn mindestens eine der Bedingungen wahr ist.

Achtung! TAG behandelt nicht, wie allgemein üblich, die Und-Verknüpfung vorrangig vor der Oder-Verknüpfung, sondern arbeitet die Verknüpfungen der Reihe nach ab. TAG versteht keine verschachtelten Klammern, deshalb müssen Bedingungen, die zuerst ausgewertet werden sollen, mit einer SeiBed-Anweisung einer Hilfsflagge zugewiesen werden:

SeiBed Flg Bed
Weist der Flagge Flg den Wahrheitswert der Bedingung Bed zu, d.h. Flg ist 0, wenn Bed falsch ist und 1, wenn Bed wahr ist. Bed ist eine Kette von Einzelbedingungen, die mit und oder oder verknüpft werden können. Die Bedingungen werden nun beschrieben.

Da keine verschachtelten Bedingungen verstanden werden, ist es wichtig, zu wissen, wie man verknüpfte Bedingungen ausdrücken kann. So ist z.B.:

        /(a und b)  = /a oder /b
        /(a oder b) = /a und /b

Auf diese Weise kommt man noch einmal um den lästigen Umweg der Hilfsvariablen herum. Die Verneinung einer verneinten Bedingung ist natürlich wieder die Bedingung selber. Doppelte Verneinungen heben sich also auf und werden auch nicht von TAG verstanden.

Man kann die Auswertung von links auch auch ausnutzen, um Prioritäten zu setzen:

        a oder (b und c)        ->   b und c oder a
        a oder /(b und c)       ->   /b oder /c oder a

(Dies funktioniert natürlich nur, solange nur eine Verknüpfung vorrangig behandelt werden soll.)

TAG kennt verschiedene Bedingungen:

(Flg Operator Flg)
Vergleicht zwei Flaggen oder Werte miteinander. Flg kann eine Flagge, eine Variable oder einen Zahlenwert bezeichnen. Der Operator kann = (gleich), > (größer als) und < (kleiner als) sein. Weitere Operatoren erhält man durch Negation der Bedingung. Beispiele:

(Obj Ort)
Prüft, ob sich das Objekt Obj am Ort Ort befindet. Ort kann IN gefolgt von einem Raum sein, oder ein Verhältniswort, gefolgt von einem Objekt, oder eines der Schlüsselwörter hier, beimir und angezogen, z.B.:

Anmerkung: in und bei prüfen nicht, ob man das Objekt sehen kann. So ist die letzte Bedingung auch wahr, wenn der Magier den Stab hat, ihn aber vor den Augen des Spielers versteckt.

(Obj Zust)
Prüft, ob das Objekt im Zustand Zust ist:

(Obj Attr)
Prüft, ob das Objekt ein bestimmtes Attribut besitzt:

(Raum RaumAttr)
Prüft, ob der Raum ein bestimmtes Attribut besitzt:

(aRaum besucht) war ich hier schon einmal?

((Proz Flg)
Ist mit einer Wahrscheinlichkeit von Flg Prozent wahr. Flg kann eine Flagge oder ein fester Zahlenwert sein.

(Flg)
Eine alleinstehende Flagge wird als Boolsche Flagge interpretiert und ist falsch, wenn sie Null ist und und anderen Fällen wahr. Diese Schreibweise ist eine Abkürzung für /<(I>Flg = 0). Diese Bedingung wird häufig im Zusammenhang mit Setze, Lösche und SeiBed verwendet.

(Obj nebenan)
Prüft, ob ein Objekt sich im Nachbarraum befindet. (Nachbarräume sind Räume, die mit aRaum durch normale Ausgänge, auch durch Türen versperrt, abgetrennt sind. Wege zählen nicht.)

(Obj hat Var)
Prüft, ob die Variable Var bei einem Objekt definiert ist.

(Obj Deko) Prüft, ob das Objekt als Dekoration definiert wurde.

(Obj OKl)
(Raum RKl)
Prüft, ob ein Raum oder ein Objekt eine Klasse besitzt.

(Obj1 am_Ort_von Obj2)
Prüft, ob sich zwei Objekte am selben Ort befinden. Das bedeutet, sie müssen dasselbe Mutterobjekt besitzten und dasselbe Verhältnis zu ihm. So sind ein Taschentuch im Nachttisch und eine Lampe darauf nicht am selben Ort, genausowenig wie ein Apfel in einer Schale und ein Messer auf dem Tisch, auch wenn die Schale auf dem Tisch steht.

(Obj1 im_Raum_mit Obj2)
Prüft, ob sich zwei Gegenstände im selben Raum befinden. Sie müssen denselben Stammraum besitzen, mehr nicht. Alle oben genannten Gegenstände sind im selben Raum.

((Meta Bef)
Prüft, ob ein Befehl ein Meta-Befehl ist.

(Licht_in Raum)
ist wahr, wenn man im Raum sehen kann. Es gibt Licht im Raum, wenn er das Attribut 'dunkel' nicht besitzt oder man mindestens ein Objekt, das eine Lichtquellen ist und das nicht ausgeschaltet ist, sehen kann.

Als Abkürzung kann man mehrere Bedingungen des gleichen Typs in einer zusammenfassen, indem man das letzte Wort wiederholt. Zum Beispiel werden folgende Bedingungen

        (aObj = Schere Messer Gabel)
        /(aRaum = Ruine Park)
        (xObj in Eimer Tasche)
        /(xObj geschlossen abgeschlossen)

von TAG in die folgenden Ketten umgewandelt:

        (aObj = Schere) oder (aObj = Messer) oder (aObj = Gabel)
        /(aRaum = Ruine) und /(aRaum = Park)
        (xObj in Eimer) oder (xObj in Tasche)
        /(xObj geschlossen) und /(xObj abgeschlossen)

Normale Bedingungen werden mit oder verknüpft, verneinte mit und. Diese Abkürzung funktioniert nur bei den Vergleichen mit Operator, bei Ortsangaben, bei Zuständen und bei Attributen. Außerdem muß die Bedingung immer von der selben Art sein. (aObj abgeschlossen in Tasche) funktioniert also nicht. Die folgenden Konstrukte sind jedoch erlaubt:

        (aObj = akteur Hans)
        (Nummer < X  Y 25)

Bedingungen spielen in bestimmten Anweisungen eine Rolle. Dieses sind die Wenn-dann-Anweisungen, die Bed(ingungs)-Anweisungen und ihre Abkürzungen sowie verschiedene Arten von Schleifen.

Eine Wenn-dann-Anweisung ermöglicht es, einen oder mehrere Befehle nur dann auszuführen, wenn eine Bedingung erfüllt ist. Die Syntax ist:

        Wenn (Bed) dann
          [...]
        Ende

Dabei ist Bed eine Bedingung aus beliebig vielen Einzelbedingungen und das Auslassungszeichen [...] steht für beliebige Anweisungen. Jede dieser Anweisungen steht dabei in einer eigenen Zeile. Alle Anweisungen bis zum Schlüsselwort Ende werden nur ausgeführt, wenn Bed wahr ist. Zum Beispiel

        Wenn (aRaum draußen) und (Sturm = 15) dann
          Text  'Der Himmel zieht sich langsam zu und ein
                unangenehmer Wind bläst scharf über das Land.'
        Ende

Wenn-dann-Anweisungen können auch ineinander geschachtelt werden. (Maximal können 12 Wenn-dann-Bedingungen ineinander liegen.)

        Wenn (Fisch hier) dann
          Text  'Es riecht hier ziemlich streng.'
          Wenn (Katze hier) dann
            Text  'Die Katze stürzt sich auf den Fisch und vertilgt
                  ihn hastig (und nicht gerade manierlich...)'
            ObjNach Fisch Nirwana
          Ende
        Ende

Sehr häufig möchte man zusätzlich Anweisungen geben, wenn die Bedingung nicht erfüllt ist. Dazu kann man die Wenn-dann-Anweisung mit sonst erweitern:

        Wenn (Bed) dann
          [...]
        sonst
          [...]
        Ende

Wenn Bed wahr ist, werden alle Ausführungen bis zum Kennwort sonst durch geführt, die Ausführungen zwischen sonst und Ende werden übersprungen. Ist die Bedingung Bed falsch, so wird der erste Teil bis sonst übersprungen und nur der zweite Teil von sonst bis Ende durchgeführt. Danach geht es weiter. Zum Beispiel:

        Text 'Der Bauer sagt:'
        Wenn (Regen) dann
          Text  '"Verdammtes Scheißwetter heute!"'
        sonst
          Text  '"Ein schöner Tag, nicht wahr?"'
        Ende

Wenn der Bereich der Wenn-dann-Anweisung nur eine Anweisung enthält und es keinen sonst-Bereich gibt, kann man die Anweisung durch Weglassen des Wortes dann abkürzen. So sind die folgenden drei Anweisungen äquivalent:

        Wenn (x > 15) dann
          Sei x 0
        Ende

        Wenn (x > 15)
          Sei x 0

        Wenn (x > 15) Sei x 0

Ob die Anweisung direkt hinter der Bedingung oder in der nächsten Zeile steht, ist dabei egal. Die Anweisung kann auch eine weitere Bedingung oder eine Schleife sein. Diese Notation kann praktisch sein, aber man muß aufpassen, daß man dann und das abschließende Ende wegläßt. Im Zweifelsfall empfiehlt es sich immer, die komplette Schleife anzugeben, um Mißverständnisse auszuschließen.

Sehr häufig werden aber Bedingungen abgefragt, um zu prüfen, ob ein Befehl des Spielers durchführbar ist oder nicht. Ist die Bedingung nicht erfüllt, passiert aber nichts. Dazu dient die Bed-Anweisung. Sie springt sofort zum Ende des Ausführungsblocks und gibt nur einen Text aus. Die Syntax ist:

Bed (Bed) 'Text' oder
Bed (Bed) Block Nr

Dabei ist Bed die zu erfüllende Bedingung. Ist sie wahr, geht es weiter im Programm. Ist sie falsch, so wird Text Nr aus Block oder der nachfolgend in Anführungszeichen angegebene Text ausgegeben und der Ausführungsblock sofort gestoppt. Dies soll in einem Beispiel verdeutlicht werden: Wir möchten den Befehl graben neu einführen. Als Werkzeug (aObj2) akzeptieren wir nur den Spaten.

        Bef     graben
        [...]
        Ausf
          [...]
          Bed (aObj2 = Spaten)
                'Wie soll ich denn mit [dem aObj2] graben? Das mußt
                Du mir aber erst erklären.'
          [...]
        AusfEnde

Anmerkung: Da die Bedingungen unter Umständen sehr lang sein können, finde ich es schöner, den Text in die nächste Zeile zu schreiben. Aus diesem Grund kann bei der Bed-Anweisung der Textstring auch in der nächsten Zeile stehen, während er bei anderen Anweisungen wie Text oder String immer auf derselben Zeile wie der Befehl stehen muß. Das hat außer der Optik des Datensatzes keinen besonderen Grund. Aber das Auge programmiert schließlich mit.

Zwei Bedingungen sind besonders wichtig, nämlich, ob das Objekt hier ist und ob der Spieler das Objekt bei sich hat. Dafür gibt es besondere Bedingungen:

ObjHier Obj
Prüft, ob Obj im selben Raum wie der Spieler ist. Ist das der Fall, so geht es weiter, wenn nicht, so wird ein Text ausgebeben. Je nachdem, ob das Objekt nicht hier ist, zu weit entfernt oder außer Reichweite ist oder ob es in einem Glasbehälter verschlossen ist und deshalb nichts mit ihm gemacht werden kann.

ObjBeiMir Obj
Prüft, ob das Objekt beim Spieler ist. Wenn nicht, wird die Aktion abgebrochen und 'Ich habe Obj nicht bei mir.' ausgegeben.

Sollen Anweisungen häufiger wiederholt werden, so kann man in TAG einfache Schleifen programmieren, die solange ausgeführt werden, wie eine bestimmte Bedingung wahr ist.

        Solange (Bed)
          [...]
        Ende

Dabei muß natürlich vom Programmierer sichergestellt werden, daß die Bedingung durch die Anweisungen in der Schleife falsch werden kann, so daß die Schleife zu einem Ende kommt. Ist das nicht der Fall, so hängt sich das Programm auf, da immer und immer wieder die Schleife abarbeitet. So ist zum Beispiel folgendes

        Solange (1 < 5)
          [...]
        Ende

eine Endlos-Schleife, da 1 immer kleiner als 5 ist, was immer auch in der Schleife passiert. Ist die Bedingung beim ersten überprüfen falsch, so wird alles, was zwischen Solange und Ende steht, nicht ausgeführt.

TAG kennt auch Schleifen, die eine Variable von einem festen Wert zu einem nächsten zählen. Dies entspricht den Do- oder For-Schleifen, die es in den meisten Programmiersprachen gibt:

        Schleife Var {von bis} {(Bed)}
          [...]
        Ende

Es muß die Variable angegeben werden, die variiert werden soll. Dies kann eine Flagge, oder eine beliebige Variable sein. Dann werden die Grenzen des Interwalls angegeben, das Var durchlaufen soll. Bei Flaggen müssen sie angegeben werden, bei Objekten, Räumen und Befehlen werden implizit alle Objekte, Räume und Befehle durchlaufen, wenn sie nicht angegeben werden. Weitehin kann eine Bedingung angegeben werden, so daß Werte übersprungen werden, die diese Bedingung nicht erfüllen. Das ist bei Objekten praktisch:

        Schleife xObj (xObj in Handtasche)
          [...]
        Ende

Ähnlich wie die Solange-Schleife arbeitet eine Wiederhole-Schleife. Hier wird die Bedingung nur am Ende der Schleife anbgefragt.

        Wiederhole
          [...]
        bis (Bed)

Hier werden die Anweisungen zwischen Wiederhole und bis solange ausgeführt, bis eine Bedingung wahr ist. Da die Überprüfung hier am Ende der Schleife erfolgt, werden die Ausführungen [...] auf jeden Fall mindestens einmal ausgeführt.

Eine weitere Bedingungsabfrage ist der Jenach-Befehl, der eine Vereinfachung des Wenn-dann-Befehls für einfache Bedingungen des Typs (X = Y) ist. Jenach ist sehr nützlich, wenn eine Variable auf verschiedene Werte hin überprüft werden soll. Die Syntax ist:

        Jenach Var
          (Ber1) [...]
          (Ber2) [...]
          (Ber3) [...]
          ...
        Ende

Dabei steht Var für eine definierte Flagge, für eine Objektvariable, eine Raumvariable oder einen Befehl. Die Ber sind verschiedene Bereiche. Je nach Var können sie Zahlen von 0 bis 255, Objekte, Räume oder Befehle enthalten. Gültige Bereiche sind:

(x) einzelnes Element
(x1 x2) Liste von Elementen
(x1..x2) alle Elemente von x1 bis x2 einschließlich
([...]) jede Kombination dieser drei
(sonst) Das Schlüsselwort sonst in Klammern

Nach den Bereichsdefinitionen in Klammern folgen dann in gewohnter Form TAG-Anweisungen. Die erste Anweisung kann in derselben Zeile wie die Definition des Bereichs stehen. Ist der momentene Wert von Var in einem Bereich enthalten, so werden die Ausführugen, die nach dem Bereich stehen, ausgeführt, bis ein neuer Bereich definiert wird.

Wichtig! Ist Var in einem Bereich und wurden die dazugehörigen Anweisungen abgearbeitet, so wird automatisch zur Ende-Marke gesprungen. Es können also überschneidende Bereiche angegeben werden, aber es wird nur der erste Bereich, in dem sich die Variable befindet behandelt. Nach der gleichen Logik wird sonst einfach als der komplette Bereich der möglichen Werte betrachtet. Es können weitere Bereiche nach sonst definiert werden, aber sie sind wirkungslos.

Also, ein kleines Beispiel:

        Jenach Monat
          (2)           Sei Tage 28
          (4 6 9 11)    Sei Tage 30
          (sonst)       Sei Tage 31
                        Wenn (Monat = 12) dann
                          Text  'Es weihnachtet sehr!'
                        Ende   | (Wenn)
        Ende   | (Jenach)
        Text   'Der [Ord Monat] hat [Num Tage] Tage.'

In diesem Beispiel wird nicht beachtet, daß die Monate nur von 1 bis 12 gehen. So hätten hier auch der 0. oder 13. einunddreißig Tage.

Martin Oehm, 04.02.2000 Vorheriges KapitelInhaltsverzeichnisNächstes Kapitel