Autor |
Nachricht |
< "William Tell" (IBG) in deform |
|
Verfasst am:
So, 10 Jan 2010 - 9:55
|
|
|
Wasserträger

Anmeldungsdatum: 21.05.2006
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:
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:
Code: |
>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:
Code: |
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;
|
|
|
|
|
 |
|
Verfasst am:
So, 10 Jan 2010 - 13:25
|
|
|
Experte

Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München
|
|
Lukas hat folgendes geschrieben: | 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:
Code: |
Constant INVENTORY_BULLET = "- ";
|
Lukas hat folgendes geschrieben: | 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:
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!";
],
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 hat folgendes geschrieben: | 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.) _________________ Every silver lining has a cloud. |
|
|
|
 |
|
Verfasst am:
So, 10 Jan 2010 - 13:31
|
|
|
Wasserträger

Anmeldungsdatum: 21.05.2006
Beiträge: 42
|
|
Danke für die ausführliche Antwort! Das klärt alles auf. |
|
|
|
 |
|
|
Alle Zeiten sind GMT + 1 Stunde (MEZ) |
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|