IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Problem bei Antwort auf "Was meinst du, den....."
AntwortenNeues ThemaNeue Umfrage
» Mehrere Seiten: 12

Problem bei Antwort auf "Was meinst du, den....."

Geschrieben um 14:03 am 10.01.2005 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Hallo,

ich habe ein Problem wenn ein Objekt nicht eindeutig gefiltert werden konnte und die Frage "Was meinst du, ...." erscheint. Allerdings nur dann, wenn es sich um eine parsename-Angelenheit handelt.

Hier mal der Code (gekürzt):



  with   post "11",

        parse_name [q;

           q = wn;

           if (nextword() == 'eingang' && nextword() ~= '11') return 1;

           wn = q;

                      if (nextword() == '11') return 1;

           wn = q;

           if (nextword() == 'eingang' && nextword() == '11') return 2;

           wn = q;

        

           return -1;

           ],

        description "Eingang 11 ist rund.",

 ...

Object Eingang22 "Eingang" Testlabor

  with   post "22",

     parse_name [q;

        q = wn;

        if (nextword() == 'eingang' && nextword() ~= '22') return 1;

        wn = q;

        if (nextword() == '22') return 1;

        wn = q;

        

        if (nextword() == 'eingang' && nextword() == '22') return 2;

        wn = q;

     

        return -1;

        ],

     description "Eingang 22 ist dreieckig.",

... ```

Und das passiert:

>x eingang

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 11

Eingang 11 ist rund.

>x eingang

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 22

Du kannst nichts dergleichen sehen.

Das Problem scheint zu sein, dass er nur für das erste Objekt eine genaue Spezifikation zuläßt und das zweite schon gar nicht mehr erreicht bzw. die Variable wn auf das falsch Wort verweist?

Und es kommt noch mehr:

>x eingang

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: eingang 11

Ich habe dich nur soweit verstanden: betrachte den Eingang 11.

Das macht nun gar kein Sinn mehr für mich.

Kann es sein, dass es Probleme mit dem return-Wert aus der parsename Routine bei dieser Frage gibt?

Gruß

Kris
Geschrieben um 23:06 am 10.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Ich hab mal versucht, in der Library herauszufinden, was genau mit den return-Werten passiert. Leider blicke ich nicht mal ansatzweise, was da tatsächlich intern abläuft.

Was mir aber aufgefallen ist: Die Befehle, die du oben angegeben hast, funktionieren sämtlichst einwandfrei, wenn du jeden return-Wert in deinem Beispielcode um 1 erhöhst.

Warum das so ist? Keine Ahnung. Da der return-Wert ja eigentlich die Anzahl der erkannten Worte zurückgeben soll, könnte ich mir vorstellen, dass meine vorgeschlagene Änderung bei komplizierteren Eingaben ungeahnte Nebenwirkungen haben kann. Das sollte also auf alle Fälle intensiv getestet werden. :)

Geschrieben um 23:25 am 10.01.2005 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

ChrisW:

Das sollte also auf alle Fälle intensiv getestet werden. :)

Genau :-)

Danke erstmal für deine Versuche. Ich habe auch nicht wirklich durchgeblickt. Zuviele unkommentierte Variablen usw...

Ich werde als Workaround einfach ein Objekt (in diesem Fall wäre es "Eingang") implementieren, dass eben nur auf 'eingang' hört (bei den anderen Objekten nur Eingang nicht akzeptieren) und mit before darauf hinweisen, sich speziell auf den einen oder anderen zu beziehen. Nicht das feinste, aber von den Möglichkeiten die am wenigsten verwirrende für den Spieler.

Gruß

Kris

Geschrieben um 00:28 am 11.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Naja, du erkennst in deiner parse_name die Möglichkeiten "Eingang x" und "x". Wenn der Spieler ein Objekt auf eine Frage hin präzisiert, wird diese Eingabe vor dem mehrdeutigen Objekt eingefügt und der ganze Sums wird nochmal geparst. Das funktioniert ganz gut, da die Wörter, die zur Disambiguisierung beitragen, eh meist Adjektive oder Attribute sind, die im Englischen (und 2017 wohl auch im Deutschen) als einzelnes Wort vorangestellt sind sind (und uns lustige Objekte wie "small/rusty/flat brass/aluminium/copper/pewter keys bescheren) und da Inform eigentlich nicht zwischen Adjektiven unterscheidet und auch "key brass brass brass small" als "small brass key" versteht und sich sogar damit brüstet.

Daher also die profane Lösung:


Object Eingang11 "Eingang" Testlabor

  with post "11",

       dekl 1,

       name 'eingang' '11',

       description "Eingang 11 ist rund.",

       has door static male;

Object Eingang22 "Eingang" Testlabor

  with post "22",

       dekl 1,

       name 'eingang' '22',

       description "Eingang 22 ist dreieckig.",

       has door static male;

Das funktioniert ganz gut. Bei einstelligen Zahlen bitte die Notation '1//', '2//' usw. verwenden. Selbst, wenn ich einen Eingang 2 habe und dann im selben Raum 'nimm 2 Streichhölzer' sage, funktioniert alles wie es soll.

Folgende Variante erzwingt die Angabe der Zimmernummer im parse_name und borgt sich nebenbei das Vokabular für die Eingänge bei einem Deko-Objekt, das nur dazu da ist, dem Spieler zu sagen, dass er konkrete Dinge mit immer nur genau einer Tür machen kann.


Class  Eingang

  with number,

       dekl 1,

       short_name "Eingang",

       post [; print " ", self.number; ],

       description [;

           "Die Nummer ", self.number, " steht auf dem Eingang.";

       ],

       parse_name [number_found n w;

           w = NextWord();

           while (true) {

               if (number_found == false && self.number

                   && Trynumber(wn - 1)==self.number)

                   number_found = true;

               else if (WordInProperty(w, zu_vage, name)==false) {

                   if (number_found) return n;

                   return -1;

               }

               n++;

               w = nextWord();

           }

       ],

       before [x;

         Enter: if (self provides dest) {

               x = self.dest();

               if (x ofclass Object) playerTo(x);

               return x;

           }

           "Der Eingang ist magisch versperrt!";

       ],

   has static male door scenery;

Eingang e11 Testlabor with number 11, dest "Yuck!";

Eingang e12 Testlabor with number 12, dest Nebenan;

Eingang e13 Testlabor with number 13;

Object Zu_vage Testlabor

  with dekl 1,

       short_name "Eingang",

       name 'eingang' 'tuer' 'nummer',

       description "Die Eingänge sind nummeriert von 11 bis 13",

       before [;

         Examine:

         default: "Bitte sage genau, welchen Eingang du meinst.";

       ],

       initial "Hier sind verschiedene Eingänge, die von 11 bis 13

           durchnummeriert sind.",

   has male static;

Und es gibt noch die Schließfach-Variante, bei der fast 10000 Eingänge als ein Objekt implementiert werden:


Object Eingang "Eingang"  Testlabor

  with dekl 1,

       number_found,

       number_needed 2567,

       post [;

           if (self.number_found) print " Nummer ",

               self.number_found;

       ],

       name 'eingang' 'tuer' 'nummer',

       description [;

           if (self.number_found==0)

               "Die Eingänge sind nummeriert von 1 bis 9999";

           "An Eingang ", self.number_found, " prangt eine

           goldene ", self.number_found, ".";

       ],

       before [nf;

           nf = self.number_found;

           if (nf < 0 || nf > 9999)

               "Die Türen haben Nummern von 1 (eins) bis 9999

               (neuntausendneunhundertundneunundneunzig).";

           Enter: if (nf==0) "Du gehst wahllos durch eine der

               Türen, die in eine Mehrzweckhalle führt.";

               if (nf ~= self.number_needed)

                   "Tür Nummer ", nf, " führt zu einer

                   Mehrzweckhalle.";

               deadflag = 2;

               "Hinter dieser Tür erwartet dich Fatima, die

               Perle des Orients. (Lechz!)";

       ],

       parse_name [nf n w;

           self.number_found = 0;

           w = NextWord();

           while (true) {

               nf = Trynumber(wn - 1);

               if (nf && self.number_found == false && nf ~= -1000)

                   self.number_found = nf;

               else if (WordInProperty(w, self, name)==false)

                   return n;

               n++;

               w = nextWord();

           }

       ],

       each_turn [; self.number_found = 0 ; ],

   has male static scenery door;

Wenn dir parse_name gefällt, interessiert dich vielleicht dieser Link zu Zarfs Parse-Name-Variationen..

Geschrieben um 09:42 am 11.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Wow. Wenn wir Martin nicht hätten.

Was mich persönlich jetzt verwirrt, ist der Quellcode der Standard-parse_name der Library von Andrew Plotkins Seite:



  wd = NextWord();

  while (WordInProperty(wd, self, name)) {

    num++;

    wd = NextWord();

  }

  return num;]```

Eigentlich dürfte sie keine anderen return-Werte liefern als Kris' Version. Der einzige Unterschied ist, dass sie sämtliche Wortreihenfolgen zulässt, was Kris' Version nicht tut. Dass sich das derart auswirkt, dass selbst bei korrekt eingegebener Wortreihenfolge bei Kris' Version nichts mehr läuft wie es soll, find ich schon krass.
Geschrieben um 10:55 am 11.01.2005 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Tja,

vielen Dank erstmal!

Beim nächsten mal werde ich das von Anfang an so angehen, ich möchte jetzt nur nicht die Objekte alle umbasteln und am Ende werde ich doch nicht bis April fertig ;-).

Martin:

Wenn dir parse_name gefällt, interessiert dich vielleicht dieser Link zu Zarfs Parse-Name-Variationen..

Naja, "im richtigen Leben" geht es hierbei um Busse. Und ich wollte natürlich auch die Möglichkeit

UNTERSUCHE BUS NACH BIEBRICH

zulassen. Damit es keine Probleme mit "NACH" gibt, war ich natürlich dazu gezwungen.

Meine jetzige Lösung:

Ich habe die Möglichkeit, nur 'bus' zu erkennen, aus den Objekten genommen und eine Hilfobjekt, das auf 'bus' und 'busse' reagiert implementiert (eben nur >UNTERSUCHE zuläßt und alles andere mit der Bitte um konkrete Auswahl des Busses unterbricht).

ChrisW:

Wow. Wenn wir Martin nicht hätten.

Das dachte ich auch, als ich den Code gesehen habe :-)

Vorm nächsten mal werde ich mir aber Zarfs Seiten dazu mal genauer anschauen.

Vielen Dank!

Kris

Geschrieben um 17:29 am 11.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChrisW:

Eigentlich dürfte sie keine anderen return-Werte liefern als Kris' Version. Der einzige Unterschied ist, dass sie sämtliche Wortreihenfolgen zulässt, was Kris' Version nicht tut. Dass sich das derart auswirkt, dass selbst bei korrekt eingegebener Wortreihenfolge bei Kris' Version nichts mehr läuft wie es soll, find ich schon krass.

Naja, die normale Vorgehensweise der Inform-Lib ist halt, so lange Wörter aus der name-Property einzulesen, wie es geht. Das Objekt, das die meisten Wörter aus dem Input eingesaugt hat, gewinnt (longest match). (Ich nehme mal an, dass dies bei der deutschen Lib auch so ist.)

Das geht ja auch meistens gut, denn nach einem Objekt steht typischerweise das Satzende oder eine Präposition. Und selbst, wenn zwei Objekte direkt aufeinander folgen ("Gib grünem Papagei Keks") kann man trennen, da sich das Vokabular unterscheidet oder der Spieler einen Artikel vor das zweite Objekt gesetzt hat. (Obwohl ich mir hier nicht ganz sicher bin - benutzt die Inform-Lib die Artikel zur Analyse oder filtert sie sie einfach raus und überliest sie?) Natürlich können Sätze wie "gib altem Hund alten Knochen" Probleme machen, wenn es mehrere Knochen gibt, darunter einen alten: Die Phrase "altem Hund alten" wird einfach dem Hund zugesprochen, so dass für den Knochen nur "Knochen" übrigbleibt, was zum Disambiguisieren zuwenig ist. Ein anderes Problem ist das im Handbuch beschriebene "put fly in amber in hole".

Kris' parse_name lässt nur die beiden Möglichkeiten "Eingang 11" und "11" zu. Das ist normalerweise in Ordnung, denn so würde man ja die Eingänge ansprechen. Wenn der Parser nachfragt, sieht es aber anders aus:

Erster Fall:

x eingang

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 22

Du kannst nichts dergleichen sehen.

Hier lautet der zu analysierende Satz nach Einfügen der Antwort "x 22 eingang", und das passt auf kein Objekt, man kann also nichts dergleichen sehen. (Wieso das oben mit 11 geklappt hat, erklärt das aber nicht. Rätselhaft, das.)

Zweiter Fall:

x eingang

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: eingang 11

Ich habe dich nur soweit verstanden: betrachte den Eingang 11.

Hier wird "x eingang 11 eingang" überprüft: "x" heißt "betrachte", "Eingang 11" (und nur diese beiden Wörter) sind der Eingang als noun, und dann kommt noch ein "eingang", mit dem der Parser nichts anfangen kann, was er auch in der uns unverständlichen, aber aus Sichtweise des Parsers einleuchtenden Fehlermeldung mitteilt.

Um Disambiguisierungsfragen vernünftig zu behandeln, sollte man also in Inform nicht strike Wortmuster wie "Eingang 11" oder "Bus nach Cochabamba" eingeben, sondern vielleicht eher die zweite Variante von Andrew Plotkins Seite verwenden, die ein Wort erzwingt, aber ansonsten genau wie der Inform-Parser arbeitet.

Geschrieben um 17:53 am 11.01.2005 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Martin:

(Obwohl ich mir hier nicht ganz sicher bin - benutzt die Inform-Lib die Artikel zur Analyse oder filtert sie sie einfach raus und überliest sie?)

In DM4 § 33 steht zur Disambiguation:

(3) Objects which don't fit "descriptors'' used by the player are removed:

if "my'', an object whose parent isn't the actor is discarded;

if "that'', an object whose parent isn't the actor's location is discarded;

if "lit'', an object which hasn't light is discarded;

if "unlit'', an object which has light is discarded;

if "his'' or some similar possessive pronoun, an object not owned by the

person implied is discarded.

Thus "his lit torches'' will invoke two of these rules at once.

Beim Prüfen, welches Objekt noch "im Topf bleibt", wird also der Artikel zu Rate gezogen. Ob es allerdings auch automatisch zur Erkennung diehnt, dass ein neues Objekt folgt, kann ich nicht sagen.

Gruß

Kris

Geschrieben um 18:54 am 11.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Kris:

Beim Prüfen, welches Objekt noch "im Topf bleibt", wird also der Artikel zu Rate gezogen. Ob es allerdings auch automatisch zur Erkennung diehnt, dass ein neues Objekt folgt, kann ich nicht sagen.

Das sind ja alles keine Artikel. Ich meinte, ob "the" eventuell vor der Analyse herausgefilter wird, also "Gib dem Mann das Brot" als "Gib Mann Brot" beim Parser ankommt. Ich glaube nicht, denn zumindest wird zwischen "the" und "a", also bestimmtem (für den definite mode) und unbestimmtem Artikel unterschieden.

Die descriptors dienen ganz klar der Abgrenzung von Objekten, da sie nur am Anfang der noun phrase stehen können. Abschnitt 34 des DM4 beschreibt die Artikel als mögliche descriptors, sie müssten also ebenso wie die von dir oben erwähnten Possesiv- und Demonstrativpronomen und vorangestellte Nummern (demanding numbers, "12 Lebkuchenherzchen") zur Trennung von Objekten beitragen. Es sei denn, sie gehören zum Vokabular des ersten Objekts.

Kurzer Test:


>u bogen

Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus Flachs.

>u den das des dem bogen

Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus Flachs.

>u den das des dem bogen den

Wahrscheinlich meinst du: ue den Bogen.

>u diesen jenen bogen

Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus Flachs.

>u den bogen den bogen

Wahrscheinlich meinst du: ue den Bogen.

>u jenen einen den bogen

Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus Flachs.

Die Artikel können also nicht zwischen die anderen Vokabeln eines Objekts gemischt werden, sondern müssen vorn stehen, wo sie hingehören. Ignoriert werden sie nicht.

Geschrieben um 21:35 am 11.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Martin:

(Wieso das oben mit 11 geklappt hat, erklärt das aber nicht. Rätselhaft, das.)

Okay, hab mal beide parse_name-Varianten so erweitert, dass sie ausgeben, was sie weiterreichen und für welche erkannten Worte sie dies tun.

WinFrotz:

u eingang

[Eingang11.parse_name - 'eingang' -> return 1]

[Eingang12.parse_name - 'eingang' -> return 1]

Das stimmt immer überein. Weiter gehts mit der Inform-Standardvariante (von Andrews Seite):

WinFrotz:

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: eingang 11

[Eingang11.parse_name - 'eingang' '11' 'eingang' -> return 3]

[Eingang12.parse_name - 'eingang' -> return 1]

Eingang 11 ist rund.

...

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 22

[Eingang11.parse_name - -> return 0]

[Eingang12.parse_name - '22' 'eingang' -> return 2]

Eingang 22 ist dreieckig.

Soweit alles klar.

Bei Kris' Variante hab ich ihn noch wn, also die Position des ersten weitergegebenen Wortes ausgeben lassen, in der Hoffnung, dass dann klarer wird, was der Parser da eigentlich tut.

WinFrotz:

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 11

[Eingang11.parse_name - wn 2 - '11' -> return 1]

[Eingang22.parse_name - wn 2 - -> return -1]

[Eingang11.parse_name - wn 3 - 'eingang' -> return 1]

[Eingang11.parse_name - wn 2 - '11' -> return 1]

[Eingang22.parse_name - wn 2 - -> return -1]

Eingang 11 ist rund.

Hier eigentlich ein Wunder, dass das klappt. Er schafft es tatsächlich, aus "x 11 eingang" auf Eingang11 zu kommen, offenbar weil die Eingang22.parse_name hier wirklich überhaupt nichts erkennt.

WinFrotz:

Deine Antwort: eingang 11

[Eingang11.parse_name - wn 2 - 'eingang' '11' -> return 2]

[Eingang22.parse_name - wn 2 - 'eingang' -> return 1]

[Eingang11.parse_name - wn 2 - 'eingang' '11' -> return 2]

[Eingang22.parse_name - wn 2 - 'eingang' -> return 1]

Ich habe dich nur soweit verstanden: ue den Eingang 11.

...

Deine Antwort: 22

[Eingang11.parse_name - wn 2 - -> return -1]

[Eingang22.parse_name - wn 2 - '22' -> return 1]

[Eingang11.parse_name - wn 3 - 'eingang' -> return 1]

[Eingang11.parse_name - wn 2 - -> return -1]

[Eingang22.parse_name - wn 3 - 'eingang' -> return 1]

[Eingang22.parse_name - wn 2 - '22' -> return 1]

Du kannst nichts dergleichen sehen.

Das lass ich jetzt mal unkommentiert so stehen....

Geschrieben um 11:46 am 12.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChrisW:

Okay, hab mal beide parse_name-Varianten so erweitert, dass sie ausgeben, was sie weiterreichen und für welche erkannten Worte sie dies tun.

Hehe, die Nachforschungen ziehen Kreise. Wir kriegen die Lib schon demontiert. (Ob wir sie verstehen, bleibt allerdings fraglich.)

Eigenartig. Wieso wird denn parse_name so oft aufgerufen? Vor allem, wo doch nach dem ersten Durchgang klar ist, ob ein Objekt und wenn ja welches gefunden wurde? (Ein Aufruf mit ##TheSame als action um herauszufinden, ob die gefundenen Objekte identisch sind, kann wohl ausgeschlossen werden, oder?)

Ein Verdacht beschleicht mich, schnell in germang.h nachgeschaut:


Verb 'untersuch' 'x//' 'b//' 'u//' 'betracht' 'beschreib' 'check' 'begutacht'

                *                                -> Look

                * noun                           -> Examine

                * multiexcept                    -> Examine;

Dass 'untersuche' allein eine Raumbeschreibung auslöst, soll hier mal nicht weiter untersucht werden. Aber wieso gibt es zwei Satzmuster für 'u' bzw. 'x'? Selbst, wenn man mehrere Objekte beim Untersuchen zulassen möchte - die englische Original-Lib tut dies nicht, TADS 2 (in manchen Fällen zumindest, sofern ich mich recht erinnere) schon - sind die beiden Zeilen redundant, etwas wie



                *                                -> Look

                * multi                          -> Examine;

```reicht vollkommen aus. Und [multiexcept] ist sowieso falsch, da es nur ein Objekt-Token auf dieser Zeile gibt, das zweite Objekt, das ausgeschlossen werden soll, also fehlt.

Probe aufs Exempel:

**Zitat:**
> "Bleib in der Nähe, Sohn", sagst du, "sonst wirst du dich in diesem Gewühl noch verlaufen."

>i

Du trägst:

einen Köcher (angezogen)

drei Pfeile

einen Bogen

>u bogen und köcher

Bogen: Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus  Flachs.

Köcher: Der Köcher aus Ziegenhaut hängt gewöhnlich über deiner  linken Schulter.

>u alles

Bogen: Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus Flachs.

>u köcher, pfeile, bogen und meinen sohn

Köcher: Der Köcher aus Ziegenhaut hängt gewöhnlich über deiner  linken Schulter.

Pfeil: Wie alle deine Pfeile - spitz und zuverlässig.

Bogen: Dein Bogen aus Eibenholz, bespannt mit einer Sehne aus  Flachs.

Walter: Ein ruhiger blonder Junge, der in acht Sommern schon  viel gelernt hat, was man für ein Leben in den Bergen benötigt.

Ich nehme mal an, dass der magere Output von 'alles' hier auf [multiexcept] zurückzuführen ist und dass [multi] hier alles nicht concealte untersuchen würde.

Gegenprobe auf Englisch:

**Zitat:**
> >x book, door and me

You can't use multiple objects with that verb.

Naja, ich denke mal, dass wir bei unseren Tests oben 'untersuche' statt 'nimm' benutzt haben, um das Problem des Mehrfachparsens auszuschließen. Wie sähe der Fall den bei, hmm, 'betritt' aus?
Geschrieben um 13:32 am 12.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Schnell mal zusammengebaut. Ohne die parse_name funktioniert alles, wie es soll. Mit Kris' parse_name:

Zitat:

betritt eingang 11

[Eingang11.parse_name - wn 2 - 'eingang' '11' -> return 2]

[Eingang22.parse_name - wn 2 - 'eingang' -> return 1]

Du betrittst Doktor Kleiners geheimes unterirdisches Labor durch den runden Eingang.

Zitat:

betritt eingang

[Eingang11.parse_name - wn 2 - 'eingang' -> return 1]

[Eingang22.parse_name - wn 2 - 'eingang' -> return 1]

Was meinst du, den Eingang 11 oder den Eingang 22?

Deine Antwort: 22

[Eingang11.parse_name - wn 2 - -> return -1]

[Eingang22.parse_name - wn 2 - '22' -> return 1]

Ich habe dich nur soweit verstanden: betritte den Eingang 22.

...

Deine Antwort: eingang 11

[Eingang11.parse_name - wn 2 - 'eingang' '11' -> return 2]

[Eingang22.parse_name - wn 2 - 'eingang' -> return 1]

Ich habe dich nur soweit verstanden: betritte den Eingang 11.

...

Deine Antwort: eingang 22

[Eingang11.parse_name - wn 2 - 'eingang' -> return 1]

[Eingang22.parse_name - wn 2 - 'eingang' '22' -> return 2]

Ich habe dich nur soweit verstanden: betritte den Eingang 22.

Hier klappte zwar nichts, aber die Library verhält sich korrekt. Schließlich erkennt keine der parse-names den kompletten Rest des Satzes, es bleibt immer ein Wort übrig. Das darf laut...



                *                                -> GoIn

                * noun                           -> Enter;```

...aber nicht passieren.

edit: Auch die Variante...

**Zitat:**
> Deine Antwort: 11

[Eingang11.parse_name - wn 2 - '11' -> return 1]

[Eingang22.parse_name - wn 2 - -> return -1]

Ich habe dich nur soweit verstanden: betritte den Eingang 11.

...funktioniert hier erwartungsgemäß nicht.

Ein gutes Beispiel auch dafür, dass man das weggekürzte End-E vielleicht nicht auf Teufel-komm-raus wieder anhängen sollte. Mit "betret", "untersuch" usw. ohne das End-E kann man zur Not leben, aber was ist denn "betritte".
Geschrieben um 16:59 am 12.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Aha, es ist also wie wir vermutet hatten. Nicht schön, aber zumindest erklärlich. Danke fürs schnelle Nachprüfen.

ChrisW:

Ein gutes Beispiel auch dafür, dass man das weggekürzte End-E vielleicht nicht auf Teufel-komm-raus wieder anhängen sollte. Mit "betret", "untersuch" usw. ohne das End-E kann man zur Not leben, aber was ist denn "betritte".

Oder 'ue' (ich ue, du ust, er ut). Naja, das 'e' passt schon in den meisten Fällen, wenn man mal von einigen Nicht-Verben wie 'ausführlich', 'Inventar', den Schimpfwörtern und den Abkürzungen absieht, bleiben nur wenige Fälle: (be)tritt, nimm, wirf, iss, gib und zerbrich.

Das müsste man eigentlich durch Anpassen von LanguageVerb geradeziehen können. Im Moment heißt die noch:


[ LanguageVerb i;

   if (i==#n$l)        { print "schau";              rtrue; }

   if (i==#n$z)        { print "warte";              rtrue; }

   if (i==#n$x)        { print "betrachte";          rtrue; }

   if (i==#n$i or 'inv' or 'inventory' or 'inventar')

                       { print "inventar";         rtrue; }

   rfalse;

];

Die ist wohl ewig nicht mehr angefasst worden, denn die Notation #n$l (von David Baggett einmal als "burst of line noise" bezeichnet) stammt ja noch aus dem Inform-Pleistozän. Hier müsste etwas stehen wie:


[ LanguageVerb i;

   if (i=='l//') { print "schaue"; rtrue; }

   if (i=='z//') { print "warte"; rtrue; }

   if (i=='j//') { print "ja"; rtrue; }

   if (i=='x//' or 'u//' or 'b//')

       { print "betrachte"; rtrue; }

   if (i=='i//' or 'inv' or 'inventory')

       { print "Inventar"; rtrue; }

   if (i=='betritt' or 'tritt' or 'nimm' or 'gib') {

       print (address) i ; rtrue;

   }

   if (i=='wirf' or 'brich' or 'zerbrich'

       or 'iss' or i=='friss') {

       print (address) i ; rtrue;

   }

   rfalse;

];

Wenn der Autor eigene unregelmäßige Verben einfügen will, sollte er analog dazu den Einhänger PrintVerb verwenden:


[ PrintVerb v;

    if (v=='befiehl') { print (address) v; rtrue; }

    rfalse;

];

Edit: Es sollten in LanguageVerb und PrintVerb auch alle Verben mit Umlauten und Eszett (öffne, schließe) umschrieben werden sowie Verben, die länger sind als neun Buchstaben und daher abgeschnitten werden (zerschneide, konsultiere, zerquetsche).

Geschrieben um 19:21 am 12.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Mmh. Hast recht, in den allermeisten Fällen ist das "e" wohl sinnvoll, allerdings wird es ausgerechnet in der parserm.h wieder angehängt. Meines Erachtens gehört so etwas nicht in die sprachunabhängigen Dateien, wenn man es wie in diesem Fall vermeiden kann. Dann wäre auch eine Umstellung der deutschen Library auf 6/11 weniger ein Problem als es offensichtlich ist.

Deine neue LanguageVerb sieht klasse aus. Ich werd sie mal ausprobieren und wo nötig noch ergänzen. Danke für den ganzen Aufwand, den du dir im Grunde ja fürs Konkurrenzsystem machst. :)

Geschrieben um 19:40 am 12.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChrisW:

Meines Erachtens gehört so etwas nicht in die sprachunabhängigen Dateien, wenn man es wie in diesem Fall vermeiden kann. Dann wäre auch eine Umstellung der deutschen Library auf 6/11 weniger ein Problem als es offensichtlich ist.

Das 'e' könnte man ja auch in LanguageVerb anhängen, anstatt dort nur rtrue zu sagen.

ChrisW:

Deine neue LanguageVerb sieht klasse aus. Ich werd sie mal ausprobieren und wo nötig noch ergänzen. Danke für den ganzen Aufwand, den du dir im Grunde ja fürs Konkurrenzsystem machst. :)

Bei der jetzigen Version gibt es gewiss noch einiges zu verbessern. Und LanguageVerb sähe gewiss mit einem switch-Statement anstelle der vielen ifs wesentlich besser aus.

Inform ist doch keine Konkurrenz. (Keine enstzunehmende jedenfalls. Ende 2006, wenn die Lizenzeinnahmen durch T.A.G. weiterhin stabil eintrudeln, werde ich Inform kaufen. Bis dahin wird noch eine friedliche Koexistenz vorgegaukelt. Hehe :-)

Naja, ein bisschen besser zu verstehen, wie die Lib funktioniert, kann ja nicht schaden. T.A.G. hat ja auch viel von Inform gelernt. Und ein im Code herumzustöbern macht mir auch Spaß.

Und darüber, dass meine Posts hier so zügig mit Forscherdrang und Begeisterung beantwortet werden, freue ich mich natürlich auch.

Geschrieben um 15:01 am 16.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

Martin:

Edit: Es sollten in LanguageVerb und PrintVerb auch alle Verben mit Umlauten und Eszett (öffne, schließe) umschrieben werden sowie Verben, die länger sind als neun Buchstaben und daher abgeschnitten werden (zerschneide, konsultiere, zerquetsche).

Stimmt natürlich. Aber das Ergebnis sieht dann etwa so wie unten aus. Vielleicht sollte ich mir noch was ausdenken, um Umlaute automatisiert zu ersetzen. :)



  switch(i) {

     'l//': print "schaue"; rtrue;

     'z//': print "warte"; rtrue;

     'j//': print "ja"; rtrue;

     'x//','u//','b//': print "betrachte"; rtrue;

     'v//': print "verlasse"; rtrue;

     'i//','inv','inventory': print "Inventar"; rtrue;

     

     'schuett': print "schütte"; rtrue;

     'giess': print "gieße"; rtrue;

     'uebertrag': print "übertrage"; rtrue;

     'uebergib': print "übergib"; rtrue;

     'ueberreich': print "überreiche"; rtrue;

     'fuetter': print "füttere"; rtrue;

     'praesentier': print "präsentiere"; rtrue;

     'fuehr': print "führe"; rtrue;

     'fluecht': print "flüchte"; rtrue;

     'konsultier': print "konsultiere"; rtrue;

     'oeffn': print "öffne"; rtrue;

     'durchquer': print "durchquere"; rtrue;

     'begutacht': print "begutachte"; rtrue;

     'durchsuch', 'durchwühl', 'durchstoeber':

                         print "durchsuche"; rtrue;

     'spuere', 'stoeber', 'wuehl': print "suche"; rtrue;

     'schmueck': print "schmücke"; rtrue;

     'drueck': print "drücke"; rtrue;

     'schliess': print "schließe"; rtrue;

     'verschliess': print "verschließe"; rtrue;

     'verriegel': print "verriegle"; rtrue;

     'zerstoer': print "zerstöre"; rtrue;

     'zertruemmer': print "zertrümmere"; rtrue;

     'kaempf', 'bekaempf': print "bekämpfe"; rtrue;

     'toet': print "töte"; rtrue;

     'quael': print "quäle"; rtrue;

     'pruegel': print "prügele"; rtrue;

     'schwaetz': print "schwätze"; rtrue;

     'erzaehl': print "erzähle"; rtrue;

     'erklaer': print "erkläre"; rtrue;

     'unterricht': print "unterrichte"; rtrue;

     'does': print "döse"; rtrue;

     'traeller': print "trällere"; rtrue;   

     'zerdrueck': print "zerdrücke"; rtrue;

     'zerquetsch': print "zerquetsche"; rtrue;

     'kuess': print "küsse"; rtrue;

     'schnueffl', 'schnueffel': print "schnüffle"; rtrue;

     'hoer': print "höre"; rtrue;

     'beruehr': print "berühre": rtrue;

     'fuehl': print "fühle"; rtrue;

     'befuehl': print "befühle"; rtrue;

     'saeuber': print "säubere"; rtrue;

     'glaett': print "glätte"; rtrue;

     'buerst': print "bürste"; rtrue;

     'zuend','entzuend': print "entzünde"; rtrue;

     'schluerf': print "schlürf"; rtrue;

     'fuell': print "fülle"; rtrue;

     'durchschneid': print "durchschneide"; rtrue;

     'zerschneid': print "zerschneide"; rtrue;

     'huepf': print "hüpfe"; rtrue;

         

     'betritt','tritt','nimm','gib','wirf','brich','zerbrich',

     'iss','friss', 'sprich', 'sieh', 'lies',

     'erklimm', 'erwirb' : print (address)i; rtrue;

     

     default: if(PrintVerb(i) == 0)

                 print (address)i, "e";

              rtrue;

  };

];```
Geschrieben um 19:13 am 17.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChrisW:

Stimmt natürlich. Aber das Ergebnis sieht dann etwa so wie unten aus.

Wow, das ist lang! Aber mit Glulx hast du ja keine Größenbeschränkung und ein wenig Ausgabekosmetik steht der Lib gut zu Gesicht. Die meisten Einträge sind aber tatsächlich nur Umlaut-Umwandlungen.

Chris:

Vielleicht sollte ich mir noch was ausdenken, um Umlaute automatisiert zu ersetzen.

Das ist gewiss keine schlechte Idee, obwohl (address) in der Lib eigentlich nur für Pronomen (die keine Umlaute haben) und zum Debuggen ausgegeben werden. Und natürlich in PrintCommand, wo es neben den Verben auch für einige Präpositionen ('über', 'für') nützlich sein könnte.

T.A.G. legt seine Vokabeln übrigens in der Form mit Umlaut ab, und in der Eingabe werden 'ae', 'oe', 'ue' dann ersetzt. Das habe ich mir nicht sehr gut überlegt und würde es jetzt auch andersherum machen, denn bei Wörtern wie "Feuer" oder "Quelle" gibt es beim Ersetzen ziemlichen Murks, die Regel lautet (in T.A.G.): 'ue' nicht ersetzen, wenn ein 'q', 'ä' oder 'e' vorangeht. Das klappt einigermaßen. Das Problem, dass man das scharfe s nicht automatisch erstzen kann, bleibt natürlich - und T.A.G. löst es zugunsten des Doppel-s.

Vielleicht ein wenig Overkill, aber hier eine Routine, die zu funktionieren scheint:



Array UmlautAux -> 12;

[ UmlautAddress i letter next last skip uml;

  ! Das spart uns Tipparbeit und Warnungen

  uml = UmlautAux;

  ! Vokabel auf Hilfsfeld schreiben

  @output_stream 3 UmlautAux;

  print (address) i;

  @output_stream -3;

 

  ! Vokabel mit ersetzten Umlauten ausgeben

  for (i=0 : i < uml-->0 : i++) {

      letter = uml->(i+2);

      if (i + 1 >= uml-->0) next = 0;

      else next = uml->(i+3);

     

      if (letter == 'a' && next == 'e') {

          print "@:a"; skip = true;

      } else if (letter == 'o' && next == 'e') {

          print "@:o"; skip = true;

      } else if (letter == 'u'

          && next == 'e' && last ~= 'q' or 'e') {

          print "@:u"; skip = true;

      } else if (skip) skip = false;

      else print (char) letter;

      last = letter;   

  }

];```
Geschrieben um 00:03 am 18.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275
<td valign="top"><div class="post"><p>Schick! Ich werd das in den nächsten Tagen mal gründlich testen. Momentan bisschen viel Arbeit hier. <img style="border:0" src="/images/smilies/smile.gif" alt=":)" align="bottom" width="17" height="17" /></p> <p><strong>Martin:</strong></p> <blockquote> <pre><code></code></pre> </blockquote> <p>  @output_stream 3 UmlautAux;</p> <p>  print &#40;address&#41; i;</p> <p>  @output_stream -3;```</p> <p>Eine Frage: Was passiert hier, wenn der Inhalt von i länger als die Länge von UmlautAux ist? Hab im DM4 leider keine Antwort darauf gefunden.</p> <p>In Glulx erledigt sich die Frage glücklicherweise. Da ersetze ich die drei Zeilen einfach durch PrintAnyToArray.</p></div></td>
Geschrieben um 09:58 am 18.01.2005 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

ChrisW:

Eine Frage: Was passiert hier, wenn der Inhalt von i länger als die Länge von UmlautAux ist? Hab im DM4 leider keine Antwort darauf gefunden.

Dann würde die Ausgabe die nach UmlautAux liegenden Daten korrumpieren. Beim Umleiten muss man daher darauf achten, dass das Feld groß genug ist, beziehungsweise dass der ausgegebene Text kurz ist. Hilfsfelder werden daher immer recht großzügig dimensioniert.

(Im Strict Mode wird das übrigens nicht überprüft, auch nicht, wenn man print_to_array auf einen String anwendet.)

Vokabeln sind im z-Code aber maximal neun Zeichen lang, plus zwei Bytes für die Länge, plus ein Byte Sicherheit macht zwölf. In diesem Beispiel sollte also nichts passieren. Wie das genau unter Glulx ist, weiß ich aber nicht.

ChrisW:

In Glulx erledigt sich die Frage glücklicherweise.

Ja, in Glulx ist dieses Problem gut gelöst, man kann das Schreiben auf ein Feld auch gut zum Ermitteln der Länge eines Strings verwenden.

Und der Code oben ist z-Code mit den typischen Opcodes. Das müsste man noch einglulxen oder biplattformisieren.

Für z-Code könnte man folgende (oder ähnliche) Print-Regeln schreiben:


&#91; print_array_check str arr len;

  arr->&#40;len+2&#41; = 0;

  @output_stream 3 arr;

  print &#40;string&#41; str;

  @ output_stream -3;

  if &#40;arr->&#40;len+2&#41;&#41;

      print "^&#91;** Error&#58; Buffer overflow. Exceeded maximum length ",

      len, " while printing the string ~", &#40;string&#41; str, "~ of length ",

      arr-->0, " to the buffer at ", arr, ". **&#93;^";

&#93;;

Das würde das Problem zwar nicht umgehen - wenn der Fehler ausgegeben wird, ist das nachfolgende Feld bereits korrupt - aber zumindest aufzeigen. Und das Feld müsste drei, nicht bloß zwei Zeichen länger sein als die maximale Textlänge.

Geschrieben um 18:01 am 19.01.2005 | Zitat | Editieren | Löschen
ChrisW
Mitglied
Dr Gumby
Beiträge: 275

(Leider immer noch nicht dazu gekommen, das zu testen und eine Glulx-Version zu schreiben, das wird erst am Wochenende.)

Martin:

Vokabeln sind im z-Code aber maximal neun Zeichen lang, plus zwei Bytes für die Länge, plus ein Byte Sicherheit macht zwölf. In diesem Beispiel sollte also nichts passieren. Wie das genau unter Glulx ist, weiß ich aber nicht.

Stimmt, daran habe ich nicht gedacht. Wenngleich diese Beschränkung in der Library-Version nach 6/11 fallen soll, laut den http://www.inform-fiction.org/suggestions/accept.html. In der Liste finden sich übrigens noch diverse andere schicke Sachen. So z.B., dass der Inform-Compiler künftig auch "blorbifizieren" können soll, also kompilierte Glulx-Dateien mit Bildern, Sound usw. automatisch zu einer Blorb-Datei zusammenfassen. Die Unterstützung für double-v8, also Z-Code-Dateien mit 1024KByte, ist nett, wenngleich im deutschsprachigen Raum auch noch niemand am aktuellen 512er-Limit gescheitert ist. In der Library endlich ein intelligentes UNLOCK, welches, wenn der Spieler den benötigten Schlüssel mit sich führt, automatisch diesen zum Aufschließen auswählt. usw. usf. träum

In Glulx gilt die 9-Zeichen-Beschränkung im Dictionary standardmäßig ebenfalls, kann allerdings per Compiler-Switch DICT_WORD_SIZE angehoben werden.

» Mehrere Seiten: 12
AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz