Home Map Index Search News Archives Links About LF
[Top bar]
[Bottom bar]
Philipp Gühring
von

Über den Autor:
Philipp hat gerade die Matura der HTL Wiener Neustadt bestanden, einer höheren technischen Schule für Informationssysteme. Dadurch hat er jetzt wieder Zeit, sich um seine Softwareentwicklungsgruppe Futureware 2001 zu kümmern. Er ist Linux Fan und aktives Mitglied der Linux User Group Austria

Inhalt:

Dialog - eine Programmiersprache für Dialoge

Josi, einer der Kunden

Zusammenfassung:

Dialog ist eine Programmiersprache, in der man Dialoge mit dem Benutzer entwickeln kann. Sie kam in der Handelssimulation Würstelstand zum Einsatz. Dieser Artikel beschreibt ihre Entwicklung.



 

Einleitung

Würstelstand ist eine österreichische Handelssimulation, bei der der Kundenkontakt schon fast zu einem Adventure wurde. Und eben für diesen Kundenkontakt entwickelte ich eine Dialogsprache, die folgende Anforderungen erfüllen soll: Als wir dann noch Telefongespräche realisierten, griff ich wieder auf die Dialogsprache zurück und erweiterte sie. Der Spieler steuert den Hauptcharakter Leni, dem der Würstelstand gehört, mittels Multiple-Choice, die Kunden werden vom Computer simuliert. Das Ziel des Spielers soll es sein, die Kunden zu beraten, ihnen etwas zu verkaufen, und mit ihnen zu plaudern. Die Kunden kommen automatisch, wenn sie Zeit und Hunger haben. Dann gibt es noch die Möglichkeit für den Spieler, selbst aktiv zu werden, und bei verschiedenen Telefonnummern anzurufen.
 

Dialogsprache

Die Dialoge werden in Ascii Textdateien abgelegt, und dann zeilenweise interpretiert. Damals wurden sie mit einem einfachen Editor erstellt. Der Dateiname ist Name.BAT (z.B.: HALE.BAT) Diese Datei wird zeilenweise interpretiert, wobei Sprünge möglich sind. Wenn der Spieler/Leni etwas sagen soll, dann geht das so:
Leni: Text
Leni: Guten Tag, der Herr! 
      Was darfs denn sein?
Leni: Da schau sich einer mal die
      heutige Jugend an!
Leni redet
Kundin redet Wenn der Kunde/Geprächspartner etwas sagen soll:
Kunde: Text
Kunde: Zwei mal Frankfurter mit Semmel
       und zwei Cola, aber dalli.
Telefon: Futureware 2001, Philipp Gühring.
         Was kann ich für sie tun?

Jeder ordentliche Dialog hört mit

Ende
auf.

Ein einfaches Beispiel:
Leni: Guten Tag, der Herr! Was darfs denn sein?
Kunde: Guten Tag! Einen Käsekrainer bitte!
Leni: Kommt gleich.
Leni: Hier, bitte sehr.
Kunde: Danke sehr. Auf wiedersehen!
Leni: Auf bald!
Ende

Sprungziele werden definiert, in dem eine Zeile mit einem Doppelpunkt anfängt, und dann der Name des Sprungziels folgt. Angesprungen werden die Sprungziele mit dem Befehl Sprung:

:Sprungmarke
//Und so springen wir dorthin:
Sprung Sprungmarke

Beispiel
...
Leni: 1
//Zuerst wird dies hier get
SPRUNG MENÜ_0
//Jetzt wurde gesprungen
...
//Diese Befehle werden übersprungen
Leni: 2
:MENÜ_0
//Und hier gehts wieder weiter
Leni: 3
Was macht der Interpreter bei diesem Beispiel? Zuerst findet er den Befehl Leni: und gibt den Text 1 aus. Dann ist in der nächsten Zeile ein Kommentar, der natürlich ignoriert wird. In der nächsten Zeile ist der Befehl Sprung. Der Interpreter sucht den ganzen Dialog nach dem Sprungziel MENÜ_0 ab, und findet es ein paar Zeilen darunter, und springt dort hin. Dann geht es gleich wieder bei einem Kommentar weiter (Und hier gehts wieder weiter). Und schlußendlich kommt noch der Befehl Leni:, worauf 3 ausgegeben wird. Der Befehl Leni: 2 wird in diesem Beispiel einfach übersprungen, und daher wird 2 nicht ausgegeben.

Wie wir nun gesehen haben, kann eine Zeile:

Kommentare beginnen mit ;(Strichpunkt),//(Zwei Schrägstriche), (Leerzeichen),*(Stern). Sie dienen zur Hilfe und Dokumentation, und werden vom Interpreter ignoriert. z.b:
// Dies ist ein Kommentar
**************************************
* Auch so kann man Kommentare machen *
**************************************
Kommentare dürfen nicht in der selben Zeile wie ein Befehl stehen:
Leni: Ich kenn mich nicht mehr aus.  // Kein Kommentar
 

Das Multiple Choice System

Multiple-Choice Auswahl Die Dialogsprache geht vom folgenden System aus: Das System stellt eine Liste zur Verfügung, in die im Laufe der Zeit die Einträge eingetragen werden, die der Benutzer als Antwortmöglichkeiten haben soll. Wenn die Zeit gekommen ist, wird das Menü auf den Bildschirm gebracht, der Benutzer kann auswählen, und dann wird zu einem Programmteil gesprungen, der die Auswahl weiterbehandelt. Zuerst werden also immer mit dem Befehl NEU oder ALT Auswahlmöglichkeiten in eine Liste hinzugefügt. Beiden Befehlen muß angegeben werden, zu welchem Sprungziel gesprungen werden soll, wenn der Eintrag ausgewählt werden sollte, und dann natürlich der ganze Auswahltext. Dieser kann ruhig länger sein, er wird vom System automatisch in mehrere Zeilen umgebrochen. Dann wird mit dem Befehl MENÜ die Liste angezeigt, und der Spieler kann sich einen Eintrag aus der Liste aussuchen.

Nun gibt es drei Arten von Abfragen.  

Themen

Die erste Art ist zum Beispiel für Gesprächsthemen geeignet:
Neu kaufen,A Schoaffe, wie imma, oder net ?
Neu arbeit,Was macht die Arbeit ?
Neu sprachkurs,Mochst nu oiwei den Sprachkurs beim WIFI?
Neu familie,Wie gehts deina Familie ?
Neu wetter,Wie taugt da eigentli des Wetta ?
Menü
Bei dieser Art hat der Spieler die Möglichkeit, der Reihe nach alle Möglichkeiten durchzuspielen. Die Einträge, die nicht ausgewählt wurden, verbleiben also in der Liste, und können beim nächsten MENÜ auch wieder ausgewählt werden. Wählen wir zum Beispiel Arbeit aus:
:arbeit
Leni: Was macht die Arbeit?
Kunde: Wie immer viel zu tun.
Menü
Wie gesagt, wird hier nur die ausgewählte Zeile gelöscht und bearbeitet. Bei der nächsten Auswahl bleiben folgende Möglichkeiten: Nun, es gibt auch eine andere Art von Abfragen:  

Auswahl

Kunde: Wieviel Stück brauchst du?
Alt einige, 10 Stück
Alt mehrere, 20 Stück
Alt viele, 100 Stück
Menü

:einige
//Hier gehts weiter, wenn 10 Stück ausgewählt wurden

:mehrere
...

:viele
...
Da es keinen Sinn macht, die nicht ausgewählten Einträge noch länger in der Liste zu lassen, sollten alle Listeneinträge nach der Auswahl des Benutzers automatisch gelöscht werden. Nehmen wir an, der Benutzer hat 20 Stück ausgewählt, dann springen wir zum Sprungziel mehrere:
:mehrere
Kunde: Bist du sicher?
Leni: Ja, ich nehme 20 Stück.
Kunde: Bis wann brauchst du sie?
Alt 1, Morgen
Alt 2, Übermorgen
Alt 3, Irgendwann
Menü
Und schlußendlich kann man die beiden Arten noch vermischen:  

Kontext/Themenwechsel

Eine weitere Nuance der menschlichen Dialoge haben wir auch noch erkannt und umgesetzt: Wenn man mit dem Gesprächspartner über ein Thema diskutiert hat, und noch eine Anmerkung übrig hat, kann man entweder diese Anmerkung ausspielen, oder das Thema wechseln. Wenn das Thema gewechselt wird, dann verfällt der Kontext der Anmerkung, und sie wird sinnlos. Man hat also die Möglichkeit, das Thema beizubehalten, oder zu einem anderen Thema zu springen. Diese Möglichkeit wurde so umgesetzt, daß man die Anmerkung wie ein normales Thema in die Themenliste einfügt, und angibt, daß die Anmerkung kontextbezogen ist, und daher auch gelöscht wird, wenn sie nicht ausgewählt wird.
Kunde: Jaja, das waren Zeiten.
Alt Erinnerung,Da fällt mir ein, du ...
MENÜ
 

Umsetzung

Jetzt kommt sicher die Frage auf, wie man die doch verschiedenen Konzepte realisieren kann. Wie Sie vielleicht schon bemerkt haben, liegt der Unterschied in der Verwendung von NEU oder ALT. Wenn man einen Eintrag mit NEU einfügt, dann bleibt er in der Liste erhalten, nur wenn er nicht ausgewählt wird. Wenn ein Eintrag mit ALT eingefügt wird, dann wird er nach dem Menü automatisch gelöscht, unabhängig davon, ob er ausgewählt wurde oder nicht. (Er ist dann verALTert).  

Mehrere Listen

Was macht man nun, wenn man in der Liste die Gesprächsthemen verwaltet, und in einem Thema eine Auswahl braucht, aber die Gesprächsthemen nicht mit anzeigen will? Zu diesem Zweck habe ich nicht nur eine Liste, sondern gleich 3 Listen angelegt:

Liste 0 wird für das erste Abfragekonzept empfohlen. Liste 1 habe ich für die allgemeinen Gesprächsthemen vorgeschlagen. Also Familie, Beruf, Freizeit, was man Essen will, ... Wenn man nun zum Beispiel über den Beruf redet, und dort wieder verschiedene Themen auftauchen, die man behandeln könnte, dann nimmt man die Liste 2. Ein Beispiel findet sich im Dialog von Hale. Sollte jemand noch weitere Listen brauchen, muß nur eine Konstante im Quellcode des Interpreters geändert werden.  

Wie verwendet man nun die verschiedenen Listen?

Am Anfang ist die Liste 1 die aktuelle Liste. Mit dem Befehl
LISTE 0
wechselt man in die Liste 0. Mit dem Befehl
LISTE 1
kommt man dann wieder zurück in die Themen-Liste. Die Einträge der Listen bleiben natürlich erhalten. Die Befehle wie NEU, ALT, MENÜ, LÖSCHEN beziehen sich immer auf die gerade aktuelle Liste.

 

Alte Version von Dialog

In der früheren Version von Dialog, die beim Würstelstand verwendet wurde, ging das ganze noch etwas anders: Statt dem Befehl ALT wurde dem Befehl NEU nach dem Beistrich ein Paragraphenzeichen angegeben:
Neu Erinnerung,§Da fällt mir ein, du ...
Und die Liste 0 wurde automatisch nach dem Menü gelöscht, war also nur für direkte Abfragen geeignet, nicht für Gesprächsthemen.

Ich empfehle nun, die HALE.BAT und die PETER.BAT als Beispiel anzusehen, dort werden die Listen ausgiebig verwendet.

Mit

LÖSCHEN Sprungziel
wird jeder Eintrag aus der aktuellen Liste gelöscht, der auf Sprungziel zeigt. z.B.:
LÖSCHEN familie
Um alle Einträge der aktuellen Liste zu löschen, gibt man den Stern an:
LÖSCHEN *
(Wer will, kann ja Regular-Expression Support einführen ;-)

Mit Menü werden alle Menüeinträge der aktuellen Menüliste angezeigt und der Benutzer kann aus diesen auswählen. Dann wird der ausgewählte Eintrag und alle mit ALT eingefügten Einträge gelöscht. Schließlich wird noch zum bei NEU angegebenen Sprungziel gesprungen. Sollte nur eine Auswahlmöglichkeit in der Liste sein, dann wird die Auswahl natürlich nicht angeboten, sondern direkt nur ausgegeben. Sollte die Liste leer sein, oder das Sprungziel nicht gefunden werden, dann wird in der nächsten Zeile nach MENÜ weitergemacht.  

Schnittstellen

Wie kann der Dialog nun auf die Umgebung reagieren, die Umgebung beeinflussen, und mit anderen Dialogen Daten austauschen?  

Register

Beim Würstelstand hat jeder Dialog auf 256 Register Zugriff. Jedes dieser Register fasst Zahlen im Bereich von -2Mrd. bis +2Mrd. Diese sind in 3 Bereiche unterteilt:

Systemregister

Die ersten 100 Register(von 0 bis 99) sind vom System reserviert: Sie werden vom System vor dem Start des Dialogs mit den Werten gefüllt. Alle mit //S markierten Register werden nach dem Ende des Dialogs vom System ausgewertet und verarbeitet. Hier nun die Liste der zur Zeit vom Würstelstand verwendeten Systemregister:
1 Event;   //Ereignis Nummer (siehe texte.h)
2 geliefert; //S //0-10 wieviel zehntel geliefert werden)
3 wtag;   //Wochentag
4 tag;   //Monatstag
5 monat;   //Monat
6 jahr;   //Jahr
7 Datum;   //fortlaufender Tag (1.1.1997 = 0)
8 wetter;   //Das Tageswetter
9 konto; //S //Wieviel Geld am Konto ist
10 kapital; //S //Kapital
11 ausgaben; //S //Wieviel Ausgaben heute gemacht wurden
12 einnahmen; //S //Wieviel Einnahmen heute gemacht wurden
13 sterne; //S //Wieviel Sterne der Würstelstand hat(0-5)
14 wverkauf;   //Wieviel diese Woche verkauft wurde
15 weinnahmen;   //Wieviel diese Woche eingenommen wurde
16 wausgaben;   //Wieviel diese Woche ausgegeben wurde
17 0; //S //Neue Ein/Ausgaben (durch Dialog ausgelöst)
18 Nachrichtenserie;   //Welche Nachrichtenserie (0=Elch,1=...)
19 Nachricht;   //Welche Nachricht in der Serie (0=1.Tag,1=2.
20 LottoNr[0];   //Wieviele LottoNr angekreuzt sind(0-6)
21 LottoErgebnis[0];   //Wieviele LottoNr richtig waren
22 LottoGewinn[LottoErgebnis[0]];   //Wieviel gewonnen wurde
23 S.Image; //S //Lenis Image
24 S.Override; //S //Override-Ereignis
25 S.wverkauf[1];   //Wieviel letzte Woche verkauft wurde
26 S.weinnahmen[1];   //Wieviel letzte Woche eingenommen wurde
27 S.wausgaben[1];   //Wieviel letzte Woche ausgegeben wurde
28 S.wverkauf[2];   //Wieviel vorletzte Woche verkauft wurde
29 S.weinnahmen[2];   //Wieviel vorletzte Woche eingenommen wurde
30 S.wausgaben[2];   //Wieviel vorletzte Woche ausgegeben wurde
31 S.NOverride; //S //Override für morgen
32 S.wetter_bericht;   //Welcher Wetterbericht verwendet wurde
33 Gesamtwert();   //Gesamtwert des Würstelstandes
34 Wetterbericht[S.wetter_bericht].Ereignis;   //Welches Wetterereignis
35 Tageszeit;   //Tageszeit in Minuten
70..79 Lagermenge   //Lagermenge der bestellten Produkte
80..89 Verkaufspreis   //Verkaufspreis der bestellten Produkte
90..99 Kaufmenge //S //Menge die gekauft wird

Dialogregister

Die nächsten 100 Register (von 100 bis 199) sind für jeden Dialog. Sie werden am Anfang des Spieles auf 0 gesetzt, bleiben dem Dialog über das ganze Spiel erhalten (werden also auch in den Spielständen gespeichert, ...), und können nur vom dazugehörigen Dialog gelesen und geschrieben werden. Am Anfang des Dialoges sollte in Kommentaren dokumentiert werden, welche Register wofür verwendet werden.
batch.cpp

// Kunde:Peter Hinzing 
// 
// Verwendung der Register: 
//[100] Wie oft er da war 
//[101] Taschengeld 
//[102] Verschiedene Ereignisse 
//[103] Zufallszahl Bestellung 
//[104] Zufallszahl Antwort auf Bestellung 
//[105] Unterschiedliche Dialoge Arbeit rede erst am 5. Tag 
//[106] Geschäft 
//[107] Das Spiel beginnt.Nach Auswahl Spiele 
//[108] Glückspiel.Einsatz.Art 
//[109] Glückspiel.Einsatz 
//[110] Glückspiel.Auswahl.Kunde 
//[111] Glückspiel.Auswahl.Leni 
//[112] Aktivierung Hobby 
//[113] Aktivierung Wohnen 
//[114] Dialoge über Würstelstand 
//[115] Gesamtbestand Cola 
//[116] zu Teuer?*************************
//* noch nicht erledigt 
Im Register [100] merkt sich Peter, wie oft er schon da war. Beim ersten Mal stellt er sich dann vor, beim 10. Mal bietet er das "du" an. In [101] verwaltet er sein tägliches Taschengeld, ...

Shared Memory

Die letzten 56 Register (könnten auch mehr sein, die genaue Zahl ist ja nicht so wichtig) sind Shared Memory zwischen den Dialogen. Das heißt, daß alle Dialoge auf diese Register zugreifen können, und alle Dialoge hier dieselben Register sehen. Es muß also eine zentrale Stelle geben, bei der festgelegt wird, welches Register mit welchen Daten belegt wird. Folgende 3 Register wurden beim Würstelstand verwendet:
[200]: Leni soll mit Hale zum Asylantragsbüro gehen 
[201]: Leni hat den Hunde-Steckbrief gelesen 
[202]: Leni hat mit Peter Stein-Schere-Papier gespielt! (Böse) 
 

Events

Für den Würstelstand haben wir ein Event-System entwickelt, das dem Slot System von KDE ähnlich sein dürfte. (Ich kenne letzteres zuwenig) Jeder Event hat eine eindeutige Nummer, die in einer zentralen Datei festgelegt wird. Events können folgende Dinge auslösen: Wie wird das gemacht? In den jeweiligen Datendateien (Produkte, Kunden, Telefonnummern, Nachrichtenserien) als Start/End Wert die Eventnummer eintragen.

Wie können Events ausgelöst werden?

Aktion Ausdruck
// Aktivieren des Cheats:
Aktion 3
// Aktivieren des Ereignisses, das im Register 100 berechnet wurde:
Aktion [100]
Was kann man nun mit diesen Events so alles machen? Hier ist ein Teil der Events vom Würstelstand:
0 Fehler/Nie Event 0 wird abgefangen und nicht behandelt
1 Initialisierung Wird am Anfang aufgerufen und aktiviert viele Produkte, Kunden, ...
2 Ende Sollte am Ende aufgerufen werden
3 FW-Cheat aktivieren Wer hat das denn programmiert?
4 FW-Cheat deaktivieren
5 Leni.Wettbewerb.Zeitung aktivieren Sobald Lenis Image gut genug ist, wird hiermit die Zeitungsmeldung des bevorstehenden Wettbewerbs aktiviert
6 Leni.Wettbewerb.Zeitung->TelefonNr Der Zeitungsartikel aktiviert die Telefonnummer, bei der man dann anrufen kann
7 Leni.Wettbewerb.TelNr deaktivieren Nachdem angerufen wurde und alles geklärt ist, wird die Telefonnummer wieder deaktiviert
8 Hale deaktivieren Hale deaktiviert sich selbst, weil er beleidigt wurde
9 Hale empfiehlt Josi Hale aktiviert Josi sobald darüber geredet wurde (Smalltalk ist wichtig!)
10 Josi deaktivieren Josi deaktiviert sich selbst
11 Peter deaktivieren Peter deaktiviert sich selbst
12 Sepp Nachricht ohne Leni aktivieren Sepp hat Leni Schwarzbrennen angeboten, Leni hat abgelehnt, die ganze Sache ist aufgeflogen und veröffentlicht worden
13 Sepp Nachricht mit Leni aktivieren Leni hat beim Schwarzbrennen zugestimmt, und kriegt Probleme
14 Spiel verloren Der Brieftäger löst das Ende des Spiels aus
15 Spiel gewonnen Gottfried sieht das Kapital von Leni, und Leni gewinnt
16 Hale->Zeitungsbericht Asyl aktivieren Leni hat mit Hale über seine Familie gesprochen, und dadurch die Zeitungsmeldung über das neue Asylrecht ausgelöst.
17 Hale->Zeitungsbericht->Telefonnr aktivieren In der Zeitung steht die Telefonnummer, bei der jetzt angerufen werden kann.
18 Hale->Zeitungsbericht->Telefonnr deaktivieren Das Gespräch deaktiviert die Telefonnummer wieder.
19 Hale->Familie aktivieren Hales Familie bekommt Asyl
20 Spion aktivieren Leni sollte einen Detektiv empfohlen bekommen, aber dieser wurde nie realisiert.
33 Neues Sortiment 1 (Neuer Lieferant) Dieses Ereignis erweitert die Produktpalette
100 Wettbewerb gewonnen Leni hat den Wettbewerb gewonnen, die Kunden reden darüber, ...
101 Wettbewerb verloren
102 Lottogewinn Leni hat im Lotto gewonnen
Wie man sieht, sind die Events ein sehr leistungsfähiges Mittel, die Logik des Spiels umzusetzen.  

Berechnungen

Der Dialog lebt nicht vom Text allein, auch Zahlen müssen rein. Mit Rechne kann man Werte berechnen und zur späteren Verwendung in den Registern ablegen. z.B.:
Rechne [100]:= 20 + [30] * 10
Der Inhalt des Registers 30 wird mit 10 multipiliziert, zu 20 addiert und das Ergebnis in das Register 100 geschrieben.

Es sind folgende Rechenoperationen möglich:

Operation Notation Beispiel Ergebnis
Klammern (a) (10+20)*30 900
Register [a] [20] Der Inhalt des Registers 20
Multiplizieren a*b 3*4 12
Dividieren a/b 10/5 2
Rest a%b 10%3 1
Addieren a+b 1+1 2
Subtrahieren a-b 1-1 0
Zuweisung [a]:b [10]:20 Schreibt in Stelle 10 den Wert 20
Vergleiche: a?b Ja(1) oder Nein(0)
Ist gleich a=b 10=20 Nein(0)
Kleiner a<b 10<20 Ja(1)
Größer a>b [10]>[20] ob der Inhalt des Registers 10 größer als der Inhalt des Registers 20 ist
AND a&b 1=1 & 2=2 Wenn 1 gleich 1 ist UND 2 gleich 2 ist
OR a|b 1=1 | 2=2 Wenn 1 gleich 1 ist ODER 2 gleich 2 ist
Zufallszahl a Z b 1 Z 6 Liefert eine Zufallszahl im Bereich von 1 bis 6

Vergleiche liefern Zahlenwerte: 1 für Richtig/Wahr und 0 für Falsch Diese können auch in die Register geschrieben werden. Leerzeichen ( 10 + 20 ) sind erlaubt, aber nicht nötig (10+10).

Die größte Herausforderung war das Entwickeln des mathematischen Evaluierers, der jetzt fähig ist, Ausdrücke wie den folgenden richtig zu verarbeiten:

Annahmen: [100]=5, [24]=14, 1Z6=2

[[100]+1]:((1Z6)*([24]>3)+10/2-10%5)
[5    +1]:((2  )*(14  >3)+10/2-10%5)
[6      ]:(2    *(1        )+5   -0   )
[6      ]:(2    *1          +5        )
[6      ]:(7                          )
[6      ]:7
Ergebnis: [6]:7 Also in das Register 6 wird der Wert 7 geschrieben.

 

Auf Register reagieren

Mit
Wenn Bedingung
Dann
können Abfragen gemacht werden. z.B.:
Wenn [100+1]>10
Kunde: Die Zahl im Register 101 ist größer als 10 !
Wenn 1>1
Kunde: FEHLER!
Wenn die Bedingung erfüllt ist, dann geht es in der nächsten Zeile weiter, sonst in der übernächsten. Implementiert wurde es dadurch, daß die nächste Zeile übersprungen wird, wenn die Bedingung nicht erfüllt ist. Dies kann für Sprungbefehle genutzt werden:
Wenn [102]<10
Sprung KLEINER
Wenn [102]=10
Sprung GLEICH
Wenn [102]>10
Sprung GRÖSSER
...
:KLEINER
...
:GLEICH
...
:GRÖSSER
 

Bilder anzeigen

Und hier noch etwas ganz Aktuelles aus der Dialogschmiede:
BILD Ausdruck
Wenn zum Beispiel in der HALE.BAT
Bild 5
steht, dann wird HALE5.DAT (ein spezielles Bildformat) angezeigt, auf einen Mausklick gewartet, und dann geht der Dialog weiter.  

Befehlsübersicht

Um einen besseren Überblick zu erhalten, habe ich hier noch eine Befehlsübersicht erstellt:
// Kommentar: BEFEHLSÜBERSICHT

Kunde: Text Der Kunde sagt etwas
Tel: Text Gesprächspartner sagt etwas
Leni: Text Leni sagt etwas
:Sprungmarke Sprungmarke wird angesprungen
Liste Nummer Wählt aktuelle Liste
Löschen * löscht alle Einträge der aktuellen Liste
Löschen Sprungmarke löscht Eintrag, der auf Sprungmarke zeigt, aus Liste
Aktion Nummer Führt besondere Aktionen aus
Ende Beendet den Dialog
Bild Nummer Zeigt das Bild mit dem Dateinamen NameNummer.dat
Sprung Sprungmarke Springt zur Sprungmarke
Neu Sprungmarke,Text Neues Thema in die aktuelle Liste einfügen
Alt Sprungmarke,Text Neue Option in die aktuelle Liste einfügen
Menü Menü anzeigen, auswählen lassen,...
Wenn Bedingung Abfrage (siehe nächste Zeilen)
//Dann Wenn ja, dann geht es in der nächsten Zeile weiter
//Sonst Wenn nein, dann wird die nächste Zeile übersprungen
Rechne Ausdruck Rechnet in die Register
Bild Ausdruck Zeigt Bilder an, und wartet auf Mausklick/Taste
 

Nachteile des Multiple-Choice Systems

 

Dialog Maker

Markus Muntaneau hat ein Delphi Programm namens Dialog-Maker entwickelt, mit dem die Dialoge leichter zu entwickeln sein sollten. Leider wurde Dialog-Maker nicht fertiggestellt (hat noch einige Bugs), und ist daher nur eingeschränkt verwendbar. Aber ein Blick darauf wird sich für Entwickler sicherlich auszahlen.

 

Programmier Tricks

Da das ganze Würstelstand-Projekt nur ca. 10.000 Zeilen C(++)-Code umfaßt hat, und die Kompilierzeiten noch erträglich waren, verzichtete ich auf eine saubere Modularisierung (ok, Faulheit war auch dabei). Stattdessen habe ich das Test-Include System entwickelt: Der Modulcode kommt in eine .c Datei, die für sich lauffähig ist, und zu den Modulroutinen gleich ein Testprogramm mitliefert, das per #ifdef deaktiviert wird, wenn es vom Hauptmodul inkludiert wird. So spart man Header Files. ;-)

batch.cpp
#ifndef _DIALOG_H 
#define _DIALOG_H 
 
#ifndef MAIN_MODULE
  #define DIALOG_TEXT 
  #define DEBUG 
  //Hier werden die benötigten Header Files inkludiert
  #include <stdio.h>
  //... 
#endif 
 
//Hier sind die ganzen Dialogroutinen 
//..
S2 Dialog(char *Filename, TYP Array[])
{
  //...
}

#ifndef MAIN_MODULE
 //Hier nun die nötigen Sachen für das Testprogramm 
TYP Feld[256]; 
int main(short argc,char *argv[]) 
{ 
  //Testprogramm
  Dialog(Filename,Feld);
} 
#endif
wurst.cpp
#define MAIN_MODULE
#include "batch.cpp"
TYP Felder[10][256];
int main(short argc,char *argv[]) 
{ 
  Dialog(Filename,Felder[i]);
}

 

Abschließende Bemerkungen

Übrigens, die Linux Version vom Würstelstand sollte ab September 1999 bei Futureware (http://poboxes.com/futureware) erhältlich sein. Wenn genügend Nachfrage besteht (E-Mails an den Autor), dann werden weitere Artikel über praktische Anwendungsbeispiele von Dialog folgen.
Dem LinuxFocus-Team schreiben
© Philipp Gühring
LinuxFocus 1999

1999-08-01, generated by lfparser version 0.7