J’ai un petit problème avec les ordres à donner aux personnages… Comment faire comprendre des verbes à l’impératif ?
Pierre, tirer porte
fonctionne, mais
Pierre, tire porte
N’est pas reconnu. Sans doute une modif à apporter aux librairies ?
Autre problème, si on donne un ordre avec un noun qui n’est pas reconnu, la lib renvoie le message classique comme quoi il faut préciser. Si on enchaine avec la même commande, elle n’est pas reconnue. Exemple :
"Pierre, tirer " donne
"Pouvez vous préciser l’objet "
« Pierre, tirer porte » donne une erreur, car le parser attends un objet, et pas une commande. Si on retape « Pierre, tirer porte » (bon du premier coup) ça fonctionne…
Pour le premier problème, c’est un bug dans la lib Inform : UnknownVerb() n’est pas appelé si le premier mot de l’ordre (un verbe, donc) n’est pas reconnu. Il devrait l’être ! (Enfin il me semble, mais si quand on essaie de reconnaître un verbe on trouve quelque chose qui n’est pas connu et qu’on n’appelle pas UnknownVerb, où va le monde ! )
Je vais essayer de voir où est le bug et le corriger.
Handling of ambiguous orders given to NPCs has been improved.
Fixed a problem with misparsing caused by incomplete orders.
Je vais essayer de trouver le commit correspondant. Ou même plus radicalement, essayer de voir si copier parserm.h de 6/12 par-dessus celle de 6/11 marche ou pas (si jamais on pouvait avoir toutes les corrections de bug d’un coup, sans avoir à se préoccuper de comment traduire les « narrative voices »…) (c’est toujours dans un coin de ma tête, un de ces quatre je le ferai )
Hop, bug trouvé, ligne 1470 de parserm.h (pour la lib 6/11, mais le bug est aussi présent dans la 6/12 - c’est donc un nouveau bug tout frais que tu as trouvé là Yoruk ):
if (actor == player) {
for (j=2 : j<=num_words : j++) {
i=NextWord();
if (i == comma_word) jump Conversation;
}
verb_word = UnknownVerb(verb_word);
if (verb_word ~= 0) jump VerbAccepted;
}
En gros ce que fait le parser sur « tim, prends bière » :
je lis le premier mot : hé mais c’est pas un verbe ! alors je rentre dans le If de la ligne 1434 pour voir si c’est un ordre ou une direction
je tombe sur le if de la ligne 1470 : c’est le premier mot, alors actor est égal à player puisque c’est la valeur par défaut
j’ai trouvé une virgule plus loin, je vais à .Conversation : tout va bien, c’est un animate et je vois qui c’est ; je change l’actor en cet objet, puis je redémarre
je lis le mot que je pense être le verbe : hé mais c’est pas un verbe ! alors je rentre dans le If de la ligne 1434…
le if de la ligne 1470 : ah bah non actor c’est pas player, alors je rentre pas dans cette boucle : donc je n’appelle jamais UnknownVerb
Quel boulet ce parser. J’ai signalé aux gens de intfiction et sur le bug tracker. Le fix est simple : faire sortir l’appel à UnknownVerb du if, c’est à dire remplacer le code ci-dessus par :
if (actor == player) {
for (j=2 : j<=num_words : j++) {
i=NextWord();
if (i == comma_word) jump Conversation;
}
}
verb_word = UnknownVerb(verb_word);
if (verb_word ~= 0) jump VerbAccepted;
Super, merci de ton retour ! Bon je vais modifier ma lib pour inclure ce changement.
J’avoue ne même pas savoir quelle est la version des bibliothèques FR que j’utilise actuellement… Je le vois pourtant à chaque fois que je compile, mais impossible de me souvenir de la version…
Parserm.h est un fichier de la bibliothèque Inform « générale », qu’on n’a pas du tout modifié pour la bibliothèque francophone (d’ailleurs, réponse de zarf sur ton bug: il est là depuis la version 6/10 et il est aussi dans I7!). La version qu’on a c’est 6/11, mais la 6/12 est sortie cet été avec des nouvelles améliorations (par exemple, support natif du changement de temps et de personne d’énonciation, en tout cas en anglais). A cause de ça, je doute que la lib FR actuelle (2.3/2.4dev) soit compatible avec la lib 6/12, donc il faut traduire/modifier, c’est épineux et pas encore fait… Bref, pour l’instant, tout le monde a Inform 6/11 + Bibli FR 2.3 ou 2.4dev
(y’a aussi les versions non-officielles de la lib FR, comme celle d’auraes mais qui n’est pas publique je crois, et la mienne qui est sur mon Bitbucket)
Alors, je crois que j’ai répondu à côté dans mon post précédent et que j’avais pas bien compris ta remarque ^^’ désolé !!
Je viens d’envoyer un mail à David Griffith, qui m’a montré ce problème sur Mantis. Ca a l’air d’être le même que le tien ; mais ils disent que le problème n’apparaît pas dans la bibli 6/11. C’est bizarre, parce que je crois que tu as bien la 6/11 (vu que, par exemple, La Source de Zig est 6/11), et moi j’ai la 6/11 et j’ai ton bug. Après réflexion je crois qu’ils se sont mal compris : le bug « directions cardinales » n’en est pas un, mais il reste toujours l’autre. Je vais lui demander de rouvrir le bug.
Et oui, c’est bien un bug : si on tape >pierre, tirer puis >tirer porte, le parser essaie de parser « tirer porte » ; si on tape >pierre, tirer puis >pierre, tirer porte, le parser essaie de parser « pierre, tirer pierre, tirer porte » Bref, le code qui désambigue se comporte différemment. J’ai l’intuition que le code est du genre « si le premier mot est un verbe ignore la désambiguation, sinon rajoute à la commande », mais il faudrait plutôt « si le premier mot est un verbe ou si il y a une virgule dans l’input, ignore, sinon rajoute »…
Il apparaît donc que tu as trouvé deux bugs Bien joué !!
Suite et fin : c’est le mauvais bug sur Mantis je crois, en tout cas y’a du code qui a été rajouté dans 6/12 (line 3089) pour ce cas particulier-là !
Pour le fix, c’est en deux étapes : premièrement cherche ce bout de code dans parserm.h (ligne 2932 chez moi)
! Once again, if the reply looks like a command, give it to the
! parser to get on with and forget about the question...
if (first_word ~= 0) {
j = first_word->#dict_par1;
if (0 ~= j&1) {
CopyBuffer(buffer, buffer2);
return REPARSE_CODE;
}
}
et remplace par
! Once again, if the reply looks like a command, give it to the
! parser to get on with and forget about the question...
if (first_word ~= 0) {
j = first_word->#dict_par1;
if (0 ~= j&1) {
CopyBuffer(buffer, buffer2);
return REPARSE_CODE;
}
if (NumberWords(parse2) > 2) {
j = WordValue(2, parse2);
k = WordValue(3, parse2);
if (j == ',//' && k && ((k->#dict_par1)&1)) {
CopyBuffer(buffer, buffer2);
return REPARSE_CODE;
}
}
}
Deuxièmement, va tout à la fin du fichier et rajoute
! 6/12 nice functions
#Ifdef TARGET_ZCODE;
[ WordValue wordnum p; ! Dictionary value of 'wordnum' string in buffer
if (p==0) p=parse;
return p-->(wordnum*2-1);
];
[ NumberWords p; ! Number of parsed strings in buffer
if (p==0) p=parse;
return p->1;
];
#Ifnot; ! TARGET_GLULX
[ WordValue wordnum p; ! Dictionary value of 'wordnum' string in buffer
if (p==0) p=parse;
return p-->(wordnum*3-2);
];
[ NumberWords p; ! Number of parsed strings in buffer
if (p==0) p=parse;
return p-->0;
];
#Endif;
Et voilà
Je crois (mais je suis pas sûr) que mon parserm.h est plus ou moins inchangé à part ces deux bugs-là, donc si tu n’as pas peur (enfin, fais un diff quand même si tu peux ^^'), mon parserm.h est en pièce jointe !
Je trouve quand même que le bug donné sur Mantis est le même, à part peut être la partie sur les points cardinaux. Mon code I6 est très similaire (juste un poil plus étoffé) (comprenez que je ne le poste pas, c’est mon jeu du concours !)
Merci en tout cas, j’effectue la modif donnée et je te tiens au courant. J’en profiterai pour redonner toutes les versions des libs que j’utilise…
… Pardon, décidément ca ne me réussit pas de poster des commentaires à trois heures du matin…
Ce que je voulais dire, c’est que la réponse de David Griffith (le lien vers Mantis) ne correspondait pas à ce qui avait été fait, vu qu’ils y disent « pas de bug avec 6/11 » mais quand on regarde le code y’a des trucs qui ont été rajoutés entre la 6/11 et la 6/12 précisément pour ce cas particulier !