German
version 3/111222 by Team GerX
Section - Libcheck - Not for release
Include (-
#ifdef DEBUG;
Global LC_notice_printed = false;
Array LibcheckIgnoreVerbs table
! *** Dies sind alle von GerX vordefinierten Verben, die möglicherweise
! auf 'e' oder 'en' enden. Diese werden beim Verben-Libcheck ignoriert,
! damit nur die vom Autor neu hinzugefügten Verben geprüft werden.
! *** (14.11.2011) 'fuerwoerter' und 'scheibenkleister' hinzugefügt,
! um bei Vokabellängen von 10, 11 und 15 Einträgen falsche
! Meldungen des Libchecks zu verhindern.
'baumle' 'durchstoeber' 'ende' 'fuerwoerter' 'klettre' 'konsultier'
'lage' 'meldungen' 'nee' 'noe' 'oeffne'
'pronomen' 'punkte' 'restore' 'save' 'scheibenkleister' 'schnueffel'
'scope' 'score' 'showme' 'streichle' 'superbrief'
'trace' 'tree' 'verbose' 'verschliess' 'wedle'
'durchschneid' 'praesentier' 'zertruemmer'
'lade' 'laden'
! *** Die Vokabeln der Standard-Lib, die Umlaute
! enthalten, werden ebenfalls übergangen.
'rueckgängig' 'rückgaengig' 'rückgängig' 'zurück' 'äh'
;
[ PerformLibcheckAll s i;
if (~~s) ShowDictStat();
XLibcheck1(s, i);
XLibcheck2(s, i);
XLibcheck3();
LibcheckAnnounce(2);
];
[ UmlautCheck i letter length start invalid;
!if (i < 256) return; ! für Changing Gender
#ifdef TARGET_GLULX;
length = Glulx_PrintAnyToArray(StorageForShortName, 24, i);
start = 0;
#ifnot;
@output_stream 3 StorageForShortName;
print (address) i;
@output_stream -3;
length = StorageForShortName-->0;
start = 2;
#endif;
! *** Vokabel nach Umlauten durchsuchen
for (i=0 : i < length : i++) {
letter = StorageForShortName->(i+start);
if (letter == CHAR_AE or CHAR_OE or CHAR_UE or CHAR_SS) invalid = true;
}
return invalid;
];
[ DictWordCorrection i max letter length start umlaute;
#ifdef TARGET_GLULX;
length = Glulx_PrintAnyToArray(StorageForShortName, 24, i);
start = 0;
#ifnot;
@output_stream 3 StorageForShortName;
print (address) i;
@output_stream -3;
length = StorageForShortName-->0;
start = 2;
#endif;
umlaute = 0;
if (max) length = max;
! *** Vokabel i nach Umlauten durchsuchen und mit Umschreibungen ausgeben
for (i=0 : i < length : i++) {
letter = StorageForShortName->(i+start);
#ifdef TARGET_ZCODE;
if (letter == CHAR_AE or CHAR_OE or CHAR_UE or CHAR_SS) umlaute++;
#endif;
switch (letter) {
CHAR_AE: print "ae";
CHAR_OE: print "oe";
CHAR_UE: print "ue";
CHAR_SS: print "ss";
default: print (char) letter;
}
}
#ifdef TARGET_ZCODE;
if (length == 9-(umlaute*3)) print "(...)";
#ifnot;
if (length == DICT_WORD_SIZE) print "(...)";
#endif;
];
[ LibcheckAnnounce n newlines i;
say__p = 0;
newlines = 2-newlines;
switch (n) {
1: if (~~LC_notice_printed) {
LC_notice_printed = true;
print "LIBCHECK hat Probleme gefunden:";
for (i=0 : i < newlines : i++) print "^";
}
2: if (LC_notice_printed) {
LC_notice_printed=false;
print "^Hinweis: Mit dem Kommando LIBCHECK kann dieser Test
jederzeit während des Spiels ausgeführt werden. Mit der
Option ~Use skip libcheck.~ wird der automatische Libcheck
bei Spielbeginn übersprungen.
^^
LIBCHECK ENDE.^^";
}
}
];
[ SuffixAddress dw mode i letter start length;
! Vokabel auf Hilfsfeld schreiben
#ifdef TARGET_GLULX;
length = Glulx_PrintAnyToArray(UmlautAux, 24, dw);
start = 0;
#ifnot;
@output_stream 3 UmlautAux;
print (address) dw;
@output_stream -3;
length = UmlautAux-->0;
start = 2;
#endif;
! *** Vokabel mit abgesetzten Endungen ausgeb|en
for (i=0 : i < length : i++) {
letter = UmlautAux->(i+start);
if (i == length-mode) print "|";
print (char) letter;
}
print " [Korrekturvorschlag: ";
DictWordCorrection(dw, length-mode);
print "]";
];
[ ShowDictStat dict_entries a i j
verb_count meta_count noun_count prep_count;
say__p = 0;
dict_entries = (dict_start - dict_end)/dict_entry_size;
if (dict_entries < 0) dict_entries = -dict_entries;
for (a = 0 : a < dict_entries : a++ ) {
! *** Adresse berechnen
i = dict_start + a*dict_entry_size;
j = i->#dict_par1;
if (j & 1) verb_count++;
if (j & $$00000010) meta_count++;
if (j & $$10000000) noun_count++;
if (j & $$00001000) prep_count++;
}
print "Info: Maximale Länge der Wörterbucheinträge: ";
#ifdef TARGET_ZCODE;
print "9 Zeichen. Das Limit kann in Z-Code nicht erhöht
werden. Umlaute und ß belegen jeweils 4 Zeichen
einer Vokabel.";
#ifnot;
print DICT_WORD_SIZE, " Zeichen. Das Limit kann in Glulx
erhöht werden: Use DICT_WORD_SIZE of <N>.";
#endif;
print "^^Das ";
#ifdef TARGET_GLULX;
print "Glulx";
#ifnot;
print "Z-Machine";
#endif;
print "-Wörterbuch enthält ", dict_entries, " Einträge. Davon sind ",
verb_count, " als Verben, ", meta_count, " als Meta-Befehle, ",
noun_count, " als Objektsynonyme und ", prep_count, " als
Präpositionen gekennzeichnet.^^";
];
[ CheckIgnoreLists word ignore_lib_verbs n j;
if (ignore_lib_verbs == false) rfalse;
for (n = 1 : n <= LibcheckIgnoreVerbs-->0 : n++ )
if (LibcheckIgnoreVerbs-->n == word) { j = -1; break; }
if (j==-1) rtrue;
if (AddressInTable(word, (+ Table of blessed verb forms +) )) rtrue;
rfalse;
];
[ XLibcheck1 silent ignore_lib_verbs o n errors i j synonyms_listed dict_entries
a gender_error;
say__p = 1;
! *** Gesamtliste aller Vokabeln mit Umlauten ohne Objektbezug erstellen,
! um auch die Vokabeln zu erwischen, die nicht in der name-Property
! eines Objekts stehen.
! *** Anzahl der Wörterbucheinträge ermitteln. Eine Schleife direkt über die
! Adressen kann wegen eines "signed integer overflows" fehlschlagen.
dict_entries = (dict_start - dict_end)/dict_entry_size;
if (dict_entries < 0) dict_entries = -dict_entries;
for (a = 0 : a < dict_entries : a++ ) {
! *** Adresse berechnen
i = dict_start + a*dict_entry_size;
if (CheckIgnoreLists(i, ignore_lib_verbs)) continue;
if (UmlautCheck(i)) {
errors++;
if (errors == 1) {
LibcheckAnnounce(1);
print "Gesamtliste aller Vokabeln, die Umlaute
oder 'ß' enthalten:^^";
}
j = i->#dict_par1;
print errors, ": ", (address) i;
if (j & 1) print " [Verb] [Korrekturvorschlag: siehe Verben-Check
weiter unten]^";
else {
if (j & $$10000000) {
print " [Objekt-Synonym]";
synonyms_listed++;
}
if (j & $$00001000) print " [Präposition]";
if (j & $$00000010) print " [Meta-Verb]";
print " [Korrekturvorschlag: ", (DictWordCorrection) i, "]^";
}
}
}
if (errors) {
print "^Hintergrund: Vokabeln (Verben und Präpositionen in Satzmustern
sowie Synonyme für Objekte), die Umlaute (ä, ö, ü) oder
Eszett (ß) enthalten, können vom GerX-Parser nicht korrekt mit der
Eingabe des Spielers abgeglichen werden, da sämtliche Umlaute und ß
in der Spielereingabe vor der Analyse durch Umschreibungen ersetzt werden.
Umlaute und ß in Vokabeln müssen deshalb immer mit
ae, oe, ue und ss umschrieben werden (siehe Korrekturvorschlag).
Nur so werden alle Umlaute und ß sowie deren Umschreibungen
in der Spielereingabe korrekt vom Spiel verstanden.^^";
}
errors = 0;
objectloop (o has mark_as_room || o has mark_as_thing || o in Compass) {
n = 0;
if (o has male) n++;
if (o has female) n++;
if (o has neuter) n++;
if (o has pluralname) n++;
if (o provides grammatical_gender
&& o.grammatical_gender < 4 && o has pluralname) n++;
if (n ~= 1) {
LibcheckAnnounce(1);
print "Objekt ", o, " (", (der) o, ") hat ";
if (n) print "keine eindeutige Genus/Numerus-Definition.^";
else print "keine Angabe zum Genus/Numerus.^";
errors++;
gender_error = true;
}
! *** Vokabeln mit Umlauten und 'ß' in der name-Property eines
! Objekts identifizieren
for (n = 0 : n<o.#name/WORDSIZE : n++) {
if (UmlautCheck(o.&name-->n)) {
LibcheckAnnounce(1);
errors++;
if (errors == 1) print "Objektdefinitionen:^^";
print "Die Vokabel '", (address) o.&name-->n,
"' von Objekt ", o, " (", (der) o, ") enthält
Umlaute oder 'ß'.^";
}
}
}
if (errors == 0) {
if (LC_notice_printed || ~~silent) {
print "Keine";
if (synonyms_listed) print " offensichtlichen";
}
}
else if (errors) print "^", errors;
if (LC_notice_printed || errors || (errors==0 && ~~silent) ) {
print " Fehler bei den Objektdefinitionen.";
if (gender_error) { print "^^Achtung: Mehrdeutige oder fehlende
Genus-Definitionen sollten nicht vorkommen.
Möglicherweise wurde das Attribut ~plural-named~ zusätzlich
zu einem ~grammatical gender~ vergeben oder der Genus
als Attribut einer Klasse (Kind) zugewiesen, anstatt ihn direkt
beim Objekt zu definieren.
^^
Die Ursachen dafür könnten
aber auch in eingebundenem Inform-6-Code liegen oder ein Fehler in
GerX sein.^";
}
else {
if (errors) print " Siehe Korrekturvorschlag in der Gesamtliste
weiter oben.";
print "^";
}
if (synonyms_listed && (synonyms_listed ~= errors) ) {
print "^Achtung: ";
if (synonyms_listed==1) print "Es wurde ein Objektsynonym gefunden,
das Umlaute/ß enthält";
else print "Es wurden ", synonyms_listed, " Objektsynonyme gefunden, die
Umlaute/ß enthalten";
print " (siehe
Gesamtliste weiter oben). Objekte mit dem Attribut ~privately-named~
oder gruppierten Vokabeln (~vokabel1/vokabel2/vokabel3~),
die nicht automatisch geprüft werden können, sollten
deshalb manuell auf ";
if (synonyms_listed>1) print "die gelisteten Synonyme";
else print "das gelistete Synonym";
print " hin überprüft werden.^";
}
}
];
[ XLibcheck2 silent ignore_lib_verbs i j k last last2 mode warnings dict_entries
a suffix_warning;
say__p = 1;
dict_entries = (dict_start - dict_end)/dict_entry_size;
if (dict_entries < 0) dict_entries = -dict_entries;
! *** Verben auf Endung 'e', 'n' (nach 'l') oder 'en' + Umlaute/ß prüfen:
warnings = 0;
suffix_warning = false;
for (a = 0 : a < dict_entries : a++ ) {
i = dict_start + a*dict_entry_size;
j = i->#dict_par1;
if (j & 1) {
if (CheckIgnoreLists(i, ignore_lib_verbs)) continue;
last = LastCharacterAddress(i);
last2 = LastCharacterAddress(i, 1);
! *** (22.02.2011) Verben, die auf 'ae', 'ee', 'ie', 'oe' oder 'ue'
! enden, werden nicht angemeckert.
if (last == 'e' && last2 == 'a' or 'e' or 'i' or 'o' or 'u') continue;
if (last2 == 'l' && last == 'n') mode = 1;
else if (last2 == 'e' && last == 'n') mode = 2;
else if (last == 'e') mode = 1;
if (mode || UmlautCheck(i)) {
if (mode) suffix_warning = true;
warnings++;
if (warnings == 1) {
LibcheckAnnounce(1,1);
print "^Folgende Verben haben Endungen und/oder enthalten Umlaute/ß:^^";
}
print warnings, ": ";
SuffixAddress(i, mode);
print "^";
mode = 0;
}
}
}
if (suffix_warning) {
print "^Hintergrund: Verben sollten immer im Imperativ (der Befehlsform)
für die 2. Person Singular angegeben werden, wobei der Spieler
das Spiel konventionsgemäß duzt. Es empfiehlt sich, immer die
knappste Form eines Verbs (~geh~) ohne Endungen zu definieren, damit
möglichst viele Wortformen (~geh~, ~gehe~, ~gehen~, ~geht~)
verstanden werden (siehe Korrekturvorschlag).
Der Parser erkennt Endungen in der Spielereingabe, deshalb braucht
man sie nicht extra anzugeben.";
print "^^Tipp: Wenn das Verb auch ohne die Endung einen gültigen
Imperativ darstellt, sollte die bestehende Definition geändert
und ausschließlich die Form ohne Endung verwendet werden.
^^
Sind Verben mit der Endung 'e', 'en' oder 'n'
notwendig, weil sie entweder ohne Endung keine korrekte Form haben
(z.B. 'knuddl' als ungültige Imperativ-Form des Verbs 'knuddeln') oder
gar keine (deutschen) Verben sind (z.B. 'ausgaenge', 'analyze'),
kann man diese in einem Not-for-release-Abschnitt in die fortgesetzte
Tabelle ~Table of blessed verb forms (continued)~ eintragen und
somit abgsegnen; die Verben in dieser Tabelle werden beim nächsten
Library-Check ignoriert und nicht mehr als Fehler gemeldet.
^^
Es folgt ein Beispiel für eine Tabelle mit dem Verb 'knuddle' und
dem englischen Verb 'analyze', deren Formen ohne 'e' keine gültigen
Imperative sind und deshalb mit 'e' am Ende definiert werden sollten:
^^
Section - Abgesegnete Verbformen - Not for release
^^Table of blessed verb forms (continued)^
Verb^
~knuddle~^
~analyze~^";
}
if (warnings==0 && silent==false) {
print "^Keine Fehler bei den Verben-Definitionen.^";
if (~~LC_notice_printed) print "^";
}
];
[ XLibcheck3 n index par errors word orig syn;
say__p = 1;
n = LanguageSynonyms2-->0;
for (index = 1 : index < n : index = index + 2) {
word = LanguageSynonyms2-->index;
par = word->#dict_par1;
if (~~(par & $$10001000)) continue;
errors++;
orig = LanguageSynonyms2-->index;
syn = LanguageSynonyms2-->(index+1);
if (errors == 1) {
LibcheckAnnounce(1,1);
print "^Folgende Wörter in Understand-Definitionen können niemals verstanden werden:^^";
}
print errors, ": ", (address) word;
if (par & $$00001000) print " [Bestandteil eines oder mehrerer Satzmuster]";
if (par & $$10000000) print " [Bestandteil eines oder mehrerer Objekt-Synonyme]";
print " [Korrekturvorschlag: ~", (PrintText) syn, "~]^";
}
if (errors) {
print "^Hintergrund: Einige Wörter in der Spielereingabe werden
vor der Analyse durch anderen Text ersetzt. Dies
sind vor allem Verschmelzungen von Präpositionen und Artikeln,
wie z.B. ~im~, ~zum~ usw. Vor der Satzanalyse werden sie in ihre Bestandteile
zerlegt und durch ~in dem~, ~zu dem~ usw. ersetzt. Deshalb können Objektsynonyme
und Satzmuster, in denen diese Wörter als Vokabeln vorkommen,
unter keinen Umständen verstanden werden.^^";
print "Tipp: Die Understand-Definitionen sollten gemäß
der Korrekturvorschläge angepasst werden. Nur so werden die
ursprünglichen und die ersetzten Formen (z.B. ~",
(address) orig, "~ und ~", (PrintText) syn, "~)
gleichermaßen verstanden.^^";
}
];
#endif; ! DEBUG
-).
Include (-
#ifdef DEBUG;
! *** (06.05.2011) Für den Synonym-Libcheck (XLibcheck3) müssen die Worte,
! die vor dem Parsen durch Synonym-Strings ersetzt werden, als
! Vokabeln im Wörterbuch vorhanden sein. Aber: Damit überprüft werden
! kann, ob der Autor sie als Objekt-Synonym verwendet hat, tarnen
! wir die früheren Vokabeln aus dem Array LanguageSynonyms zunächst
! als Verben.
!
! Dass die Vokabeln ursprünglich Verben sind, ist kein Problem:
! Versucht der Spieler z.B. >DURCHS, kann das Wort niemals als
! Verb verstanden werden, weil der Befehl für den Parser >DURCH DAS
! lautet.
Verb meta 'am' 'ans' 'aufs' 'beim' 'durchs' 'fuers' 'hinterm' 'hinters' 'im' 'ins'
'nebens' 'uebers' 'ueberm' 'unters' 'unterm' 'vom' 'vors' 'vorm'
'zum' 'zur' 'darin' 'damit' 'beide'
* -> SynonymLibcheckDummy
;
[ SynonymLibcheckDummySub; return L__M(##Miscellany, 10); ];
#endif;
-) before "Flex.i6t".
Include (-
#ifdef DEBUG;
[ InitialiseLanguageSynonyms2 n index word;
! *** (18.05.2011) Spielbeginn: Kopie von LanguageSynonyms erstellen, allerdings
! mit Vokabeln statt Strings.
n = LanguageSynonyms2-->0 = LanguageSynonyms-->0;
for (index = 1 : index < n : index = index + 2) {
word = LanguageSynonyms-->index; ! Ein String ...
VM_PrintToBuffer(buffer, 24, word);
VM_Tokenise(buffer, parse);
word = parse-->1; ! ... und jetzt ein Wörterbuch-Eintrag (eine Vokabel)!
LanguageSynonyms2-->index = word;
LanguageSynonyms2-->(index+1) = LanguageSynonyms-->(index+1);
}
];
#endif;
-).
[Section - Temporary bug fixes]
German ends here.