IF-Forum

» IF-Forum - Autorencafé - Schreiben! - "William Tell" (IBG) in deform
AntwortenNeues ThemaNeue Umfrage

"William Tell" (IBG) in deform

Geschrieben um 10:55 am 10.01.2010 | Zitat | Editieren | Löschen
Lukas
Mitglied
Bachelor Gumby
Beiträge: 42

Ich arbeite gerade den Inform Beginner's Guide durch und habe das Beispiel "Willam Tell" dabei mitgetippt und zur Übung gleich auf Deutsch (mit deform) übersetzt. Jetzt zeigt das Spiel aber ein paar Eigenheiten, bei denen mir als Anfänger noch nicht klar ist, wo sie herrühren.

Im Spiel werden ja drei Pfeile definiert, die zusammengebündelt sind. Hier mein Code:


Class Arrow

    with name 'pfeil' 'pfeile//p',

    article "einen",

    plural "pfeile",

    description "Spitz und treffsicher -- wie alle deine Pfeile.",

    before [;

        Drop,Give,ThrowAt:

        print_ret "Du passt besser gut auf deine spitzen Pfeile auf.";

        Eat:

        print_ret "Was für eine bizarre Idee - du bist kein Fakir!";

    ];

   

Arrow "Pfeil" quiver

    has male;

Arrow "Pfeil" quiver

    has male;

Arrow "Pfeil" quiver

    has male;   

Zunächst fällt auf, dass im Inventar vor die drei Pfeile ein zusätzliches Leerzeichen gesetzt wird, ohne dass mir klar ist, warum:


>i

Du hast Folgendes:

  einen Köcher (angezogen)

    drei pfeile

  einen Bogen

Wenn ich nun z.B. "iss pfeil" eingebe, wird ein Pfeil davor aufgehoben, um dann im Inventar gesondert ("einen Pfeil") aufgeführt zu werden. Kann man es irgendwie verhindern, dass so zusammengebündelte Objekte getrennt werden, abgesehen davon, dass man die Aktion des Nehmens abfängt?

Weiters fiel mir etwas bei dem berühmten Apfel auf. Bei jedem Befehl, der auf ihn bezogen ist, z.B. "u apfel" oder "iss apfel", gibt der Parser zunächst "(den Apfel)" aus, als müsste das in meinem Befehl ergänzt werden. Warum? Hier mein Code des Apfels:


Object apple "Apfel"

    with name 'apfel',

    description [;

        if (location == marketplace)

        print_ret "Von dieser Entfernung aus kannst du ihn kaum sehen.";

        else

        print_ret "Der Apfel ist braun und grün gefleckt.";

    ],

    before [;

        Drop:

        print_ret "Ein Apfel ist ziemlich was wert --

        lass das besser sein.";

        Eat:

        print_ret "Helga schenkte ihn Walter...";

        FireAt:

        if (location == marketplace) {

            if (BowOrArrow(second) == true) {

            score = score + 1;

            deadflag = 2;

            print_ret "Bedächtig spannst du einen Pfeil in deinen Bogen und zielst

            am genauesten in deinem Leben. Ängstlich, mit angehaltenem Atem

            und ohne zu Zwinkern lässt du den Pfeil los. Er fliegt über den Platz

            zu deinem Sohn hin und durchbohrt den Apfel, ihn an die Rinde nagelnd.

            Die Menge schreit auf vor Begeisterung, aber Gessler wirkt definitiv

            enttäuscht.";

            }

            return true;

        }

        else

        return false;

    ],   

    has male;
Geschrieben um 14:25 am 10.01.2010 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Lukas:

Zunächst fällt auf, dass im Inventar vor die drei Pfeile ein zusätzliches Leerzeichen gesetzt wird, ohne dass mir klar ist, warum:

Das ist kein Leerzeichen, sondern eine Einrückung, die anzeigt, dass sich die Pfeile im Köcher befinden, ähnlich der Ordner-Hierarchie in einem Dateimanager. Das wird vielleicht deutlicher, wenn Du zu Beginn des Quellcodes folgendes definierst:


Constant INVENTORY_BULLET = "- ";

Lukas:

Wenn ich nun z.B. "iss pfeil" eingebe, wird ein Pfeil davor aufgehoben, um dann im Inventar gesondert ("einen Pfeil") aufgeführt zu werden. Kann man es irgendwie verhindern, dass so zusammengebündelte Objekte getrennt werden, abgesehen davon, dass man die Aktion des Nehmens abfängt?

Dass der Pfeil nach dem Nehmen gesondert aufgeführt wird, liegt auch an dieser Hierarchie des Inventars: Einen Pfeil hast Du in der Hand, die beiden anderen sind noch im Köcher.

Dass zunächst versucht wird, den Pfeil aufzuheben, obwohl die Aktion "iss Pfeil" an sich unsinnig ist, ist eine Schwäche des Inform-Parsers, der versucht, viel zu viel bereits im Stadium der Satzanalyse zu erledigen. In der Version 6/11 und damit auch in deform ist es aber möglich, das implizite Aufheben des Pfeils mit der Eigenschaft before_implicit zu unterbinden:


Class Arrow

    with name 'pfeil' 'pfeile//p',

    article "einen",

    plural "pfeile",

    description "Spitz und treffsicher -- wie alle deine Pfeile.",

    before [;

        Drop,Give,ThrowAt:

        print_ret "Du passt besser gut auf deine spitzen Pfeile auf.";

        Eat:

        print_ret "Was für eine bizarre Idee - du bist kein Fakir!";

    ],

    before_implicit [;

        Take: if (action_to_be == ##Eat) return 2;

    ],

    has male;

Die Methode before_implicit sollte einen der folgenden Werte zurückgeben:

0 verfährt so, als ob kein before_implicit definiert wäre; es wird also versucht, den Pfeil aufzuheben, was in Klammern mitgeteilt wird. 1 macht dasseble, aber ohne Meldung in Klammern. 2 unterbindet das Aufheben und fährt mit der Aktion fort. Das bedeutet, dass für solche Aktionen die Voraussetzung, dass nach dem erfolgreichen Parsen eines [held]-Tokens das entsprechende Objekt beim Spieler ist, nicht mehr wahr ist. (Was uns in Deinem Fall aber egal ist.) Und schließlich sagt 3 explizit, dass ich das Objekt nicht habe.

Dass man gleiche Objekte einzeln oder mit einer Zahlenangabe ansprechen kann, ist gewünscht. Wenn ein Objekt eigentlich eine Anzahl von Objekten ist, wie bei deinen Pfeilen, könnte man diese Gruppe auch als ein Objekt implementieren. Dann müsstest Du 'pfeil' und 'pfeile' (nicht 'pfeile//p') als Vokabeln definieren und vermutlich auch eine Eigenschaft count oder so, die angibt, wieviele Pfeile noch übrig sind. Da man die Pfeile nichgt einfach so weggeben kann, muss diese Anzahl nur beim eigentlichen Befehl, nämlich dem Schießen, berücksichtigt werden. (Wenn die Pfeile aufgebraucht sind, muss man sie natürlich aus dem Inventar entfernen. Oh, und die Anzahl der Pfeile sollte als article oder so implementiert werden, da mit diesem Eigenbau das automatische Zählen nicht mehr funktioniert.)

Lukas:

Weiters fiel mir etwas bei dem berühmten Apfel auf. Bei jedem Befehl, der auf ihn bezogen ist, z.B. "u apfel" oder "iss apfel", gibt der Parser zunächst "(den Apfel)" aus, als müsste das in meinem Befehl ergänzt werden. Warum?

Die Ursache hierfür liegt vermutlich nicht beim Code des Apfels, sondern bei einem anderen Objekt. Diese Angaben in Klammern (inferences) werden immer dann ausgegeben, wenn der Parser eigenmächtig entscheiden muss, weil entweder kein Objekt angegeben wurde oder weil ein Objekt mehrdeutig war. Wenn er selbst entscheidet, kommt diese Angabe, ansonsten eine Nachfrage.

Ich vermute also, dass es ignedwo in Deinem Tell-Beispiel ein scenery-Objekt gibt, dass auch auf die Vokabel 'apfel' hört. (Die Vermutung, dass dieses andere Objekt das Attribut scenery besitzt, beruht darauf, dass solche Objekte bei der Einschätzung des Parsers, ob es gemeint ist, niedriger eingestuft werden.)

Geschrieben um 14:31 am 10.01.2010 | Zitat | Editieren | Löschen
Lukas
Mitglied
Bachelor Gumby
Beiträge: 42

Danke für die ausführliche Antwort! Das klärt alles auf.

AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz