Un ptit bug dans les biblis d'I6 ?

J’ai l’impression d’avoir trouvé un petit bug dans les bibliothèques francophones I6 en testant mon jeu.
J’ai un objet container fermé qui contient un autre objet, le tout dans l’inventaire du joueur (je ne sais pas si ça change grand-chose mais je le dis quand même). Voilà ce que j’obtiens :

prendre x dans y
Il est malheureusement fermé.

Il manque donc un retour à la ligne quelque part :smiley: (ah, j’ai bien dit que c’était un petit bug, hein)
J’ai vaguement regardé dans la bibliothèque, c’est la réponse par défaut de l’action Remove, mais j’ai pas l’impression qu’il manque quelque chose. Et je ne pense pas que ça soit mon jeu ! Bref, si quelqu’un a une idée et un peu de temps pour regarder, c’est un bug qui serait sans doute vite réglé… Merci !

Merci pour le signalement. J’ai comparé avec English.h et effectivement il y a un bug. C’est corrigé sur la dernière version sur le dépôt subversion. Peux-tu tester ?

Voilà le patch :

Index: French.h
===================================================================
--- French.h    (révision 190)
+++ French.h    (copie de travail)
@@ -1311,8 +1311,8 @@
     }
     Remove: switch (n) {
         1:  if (x1 has pluralname)
-                print "Ils sont malheureusement ferm�s."; !*! elle(s)
-            else print "Il est malheureusement ferm�."; !*!
+                "Ils sont malheureusement ferm�s."; !*! elle(s)
+            else "Il est malheureusement ferm�."; !*!
         2:  if (x1 has pluralname)
                 print "Mais ils ne sont pas";
             else print "Mais ce n'est pas";

Ca marche très bien, merci ! :smiley:

Dans le même registre, mais en encore plus obscur :

>vf
Homeland Security
par Hugo Labrande
Release trucmachin interpréteur machin

Compilé avec la version 2.4dev de la bibliothèque francophone.
[Le texte de mon daemon commence tout de suite sans saut de ligne.]

Si je ne me trompe pas, il faudrait enlever le print de la ligne 29 du fichier FrenchG.h et enlever le chapeau final ? (ie « Compilé avec » au lieu de print « Compilé avec^ »)

(bon en théorie vu que c’est un méta-verbe je devrais pas faire démarrer mon daemon, mais je me suis trompé dans mon code, et heureusement on va dire, puisque ça permet de découvrir une petite erreur ^^)

EDIT: Ah bah non, c’est un vrai bug ça aussi ! Il manque le token ‹ meta › pour le verbe ‹ vf ›, alors qu’il y est pour ‹ version française › !!! (c’est pour ça que mon daemon se lançait alors qu’il fallait pas qu’il se lance) La ligne 97 est donc aussi à changer :wink: (ou alors, changer juste la ligne 97, mais je suis pour changer les deux, au cas où, c’est plus propre !)

Je vais regarder. Si j’oublie relance-moi :slight_smile:

Ok ça marche :slight_smile:

Sinon, je pourrais faire les modifications moi-même, même si j’avoue que je préfère te demander avant au cas où je raconte des bêtises :wink: Dis moi si tu veux à un moment que j’arrête de demander si on pourrait faire des modifs et que tu préfères que je les fasse moi-même :stuck_out_tongue:

Il y a un souci avec la gestion du tiret dans vos librairies. Elle coupe tous les mots, contrairement à ce qu’elle affirme. Elle coupe donc aussi les mots du dictionnaire : ‹ dix-sept › ‹ dix-huit › ‹ dix-neuf › grand-père et autres.
Je cite :
« insertion d’un espace avant chaque tiret… »
« conserve ‹ -lui ›,‹ -le ›,‹ -la ›… et les mots prévus par le joueur »
Eh, bien non !? Puisque une espace à été insérée devant chaque tiret ! C’est écrit noir sur blanc !
Extraits :

[code]! insertion d’un espace avant chaque tiret et après chaque apostrophe
for (i=WORDSIZE:i<WORDSIZE+NbChars():i++) {
if (buffer->i == ‹ - ›) LTI_Insert(i++, ’ ‹ );
if (buffer->i == ‹  › ›) LTI_Insert(++i, ’ ‹ ); ! ‹  › › !*! autre notation ? ‹ ' › par exemple ?
}
Tokenise__(buffer,parse);

! enlève le tiret de départ des mots qui ne sont pas dans le dictionnaire
[ enleve_tirets x i word at len;
i=NULL; ! pour retirer warning a la compilation glulxe
for (x=0:x<NbMots():x++) ! pour chaque mot
{
word=Mot(x);
at=PositionMot(x);
len=LongueurMot(x);
if (word==0) ! non compris
{
if (buffer->at==‹ - ›) buffer->at=’ ';
Tokenise__(buffer,parse);
}
}
];

! enlever le tiret en début de mot pour ceux qui n’existent pas dans le dictionnaire
! (conserve ‹ -lui ›,‹ -le ›,‹ -la ›… et les mots prévus par le joueur)
enleve_tirets();[/code]
Je fais autrement :[ CoupeTiret motn at lgm; at = PosMot(motn); lgm = LenMot(motn) + at; for ( : at < lgm : at++) { if ((buffer->at) == '-') { if (DictionaryLookup(buffer + at, lgm - at)) { LTI_Insert(at++,' '); break; } } } ];Si le mot contient un tiret et qu’il n’est pas dans le dictionnaire, je vais voir si du tiret à la fin du mot, ce motif existe dans le dictionnaire. Si oui, c’est le cas pour les pronoms, je coupe le mot. Les autres mots, qu’ils soient dans le dictionnaire ou pas, ne sont pas altérés.

J’ai appliqué les modifications de mule hollandaise.

Auraes, si tu as un patch à proposer pour French.h on peut l’appliquer.

Super, Stormi, merci !

En ce qui concerne les tirets, c’est vrai que j’ai remarqué que les mots avec des tirets n’étaient pas reconnus - je pensais que, par défaut en Inform, il fallait mettre les deux parties du mot pour que ça soit reconnu. Ca serait bien de le corriger si on peut ; en pratique, si on veut vraiment être complet il faut aussi inclure les deux parties du mot (si le joueur tape « pense bete » au lieu de « pense-bete »), mais on n’y pense pas toujours en codant. Auraes, comment s’intègrerait ta fonction au code ? Il faudrait remplacer enleve_tirets par CoupeTirets ?

Bon, juste à l’instant je viens de m’apercevoir d’une chose :
*** IL FAUT VIRER LES ‹ à › DE FrenchG.h ***
Et pourquoi il posait des problèmes Ce ‹ à › !? Mais parce qu’il est DANS LE DICTIONNAIRE puisque il est dans la grammaire. Et la routine enleve_accents() n’enlevait les accents que sur les mots qui N’ÉTAIENT PAS DANS LE DICTIONNAIRE !!!
Donc, impossible de supprimer l’accent du ‹ à ›.

(Lire ABSOLUMENT le message précédent.)
Bon… la suite : Ce que j’ai fait à French.h:

1 : j’ai regroupé les routines zcode et Glulx pour plus de lisibilité.

2 : j’ai remplacé la routine enleve_tirets et enleve_accents

3 : Dans la mesure ou le tiret ne pose plus de problèmes, j’ai renommé correctement les objets CompassDirection : nordouest… en nord-ouest… et supprimé les routines qui faisaient la modification. C’est quand même plus cohérant !

La routine enleve_accents était inéficasse : pour chaque caractère sans accent, ce qui est le plus probable, elle parcourait l’ensemble du tableau. Pour un caractère ASCII il vaut mieux sortir immédiatement.
À quoi sert la variable : global enleveaccents=1, la routine ne l’utilisait pas ?

J’ai placé les routines dés le début de LanguageToInformese parceque je ne veux pas me « plonger » dans le code qui suit. Et c’est certainement un bon emplacement.

Cela semble fonctionner.

Pour tester j’ai ajouté à la fin de LanguageToInformese() la routine buferparse() qu’il faudra enlever.
Le code pour tester est là:

!% -C1 !% +language_name=nFrench ! ------------------------------------------------------------------------------ Include "Parser"; Include "VerbLib"; ! ------------------------------------------------------------------------------ ! Affiche [mot] = Mots dans le dictionnaire [ buferparse motn at lgm; print "------------------------^"; print "bText : "; for (at = WORDSIZE : at < WORDSIZE + NbChars() : at++) print (char) buffer->at; print "^bParser : "; for (motn = 0 : motn < NbMots() : motn++){ at = PositionMot(motn); lgm = LongueurMot(motn) + at; if (Mot(motn)) print " ["; else print " "; for ( : at < lgm : at++) print (char) buffer->at; if (Mot(motn)) print "] "; else print " "; } print "^------------------------^"; ]; ! ------------------------------------------------------------------------------ Object room with description "ROOM" has light; ! ------------------------------------------------------------------------------ [ Initialise; location = room; ]; ! ------------------------------------------------------------------------------ Include "FrenchG";

Auraes, aurais-tu des exemples concrets illustrant ce que tes modifications apportent ? De plus je n’ai pas compris ce que tu entends par « Elle coupe tous les mots ».

Je viens de faire un essai rapide en rajoutant « caisse-enregistreuse » dans un de mes jeux. Avec la version ancienne des bibliothèques, ce mot n’est pas pris en compte quoi que l’on tape. Avec ta version, ça fonctionne si on tape « caisse-enregistreuse » (mais pas « caisse enregistreuse »), donc c’est déjà un point positif. Ça permet de faire d’autres choses également ?

J’ai vu également un appel à « buferparse(); », mais si je le laisse, ça ne compile pas, du coup je l’ai retiré lors de mes essais.

Enfin, je suis prêt à intégrer tes modifications, si Stormi donne également son aval, mais malgré tout comme on n’a pas prévu de test de régression en l’état actuel des choses, cela fait un peu peur de rajouter ça comme ça, on ne sait pas s’il n’y a pas de risque d’autres effets de bords vis à vis du code existant (je ne suis pas assez calé en inform pour juger de ça), par exemple des ralentissements dû à certaines boucles etc.

Un truc qui serait pas mal d’améliorer aussi c’est la gestion des apostrophes, genre pour « chef d’orchestre », à chaque fois ce n’est pas pris en compte.

buferparse() il faut l’enlever. C’est pour afficher et tester le parser avec le code du message précédent. Compile le message précédent et test les librairies.

!!? Tout les mots avec un tiret étaient coupés. Même ceux du dictionnaire : dix-sept dix-huit dix-neuf. Ils ne le sont plus. Tu peux utiliser des mots comme grand-père… Et la propriété ‹ name › des objets CompassDirection à été corrigée : plus de nordouest sudouest… mais nord-ouest sud-ouest…

Des ralentissements !? La routine enleve_accents() testait pour n’importe quel mot saisit qui n’était pas dans le dictionnaire et pour chaque caractères du mot, l’ensemble de la table des caractères accentués ! Pourquoi parcourir toute la table pour un caractère non accentué ?
Des effets de bords : et ce fameux ‹ à ›, ce n’était pas un effet de bord, et le fait d’être obligé de nommer les objets du compass nordest sudouest… ce n’était pas un effet de bord ? Et regarde ce que je viens de voir dans LanguageToInformese() :

for (i=0:i<NbMots():i++) ! balayer toute la phrase { [...] if (word == 'dessus') { i = 0; continue; } [...] }i = 0; continue; pose problème : le principe, c’est de balayé la phrase et si il y a des modifications de remettre i à 0 et de balayer à nouveau la phrase. Sauf que la prochaine boucle commencera à 1 et non pas à 0, malgré le i = 0. Pour une boucle qui commence à 0, Il faut mettre i à -1 avec un continue. Pour une boucle qui commence à 1, Il faut mettre en effet i à 0 avec un continue, pour pouvoir à nouveau parcourir toute la boucle.
Pour tester :[code]Global n;

[ test i; if( i == 5) { n++; return 1; } rfalse; ];

[ main key i j;
!/*
for( i = 0 : i < 15 : i++){
if(n == 3) break;
print i, " ";
j = test(i);
if(j){
print " | ";
i = 0;
continue;
}
}
!/*
n = 0;
new_line;

for( i = 0 : i < 15 : i++){
	if(n == 3) break;
	print  i, " ";
	j = test(i);
	if(j){
		print " | ";
		i = -1;
		continue;
	}
}

!/*
@read_char 1 ->key;
];[/code]J’obtiens :
Boucle 1: i = 0
012345 | 12345 | 12345 ! Le 0 n’apparait qu’une fois !? (C’est normal.)
Boucle 2 : i = -1
012345 | 012345 | 012345 O.K, je parcours tous les mots à chaque tour de boucle.

[code]
[ main i;
for( i = 0 : i < 15 : i++){
continue;
}
];

![ main i
! store i short_0
! .L0
! jl i short_15 to L2 if FALSE
! jump L1
! .L1
! inc i
! jump L0
! .L2
! rtrue
!]
[/code] Le ‹ jump L1 › c’est le continue : il se branche sur .L1 qui est bien situé avant ‹ inc i ›. Donc même si avant le continue, je met i à 0, i sera incrémente avant le prochain tour de boucle.

Bon, je décroche. Faites ce que vous voulez.

Faut pas prendre la mouche comme ça. Nous ne sommes pas à l’origine de ces bibliothèques même si nous tentons de les maintenir. Ce n’est pas simple de rentrer dedans ni de les modifier sans que ça casse quoi que ce soit à des endroits parfois inattendus, donc il est logique d’être assez conservatif et de préférer appliquer les changements un par un et de chercher à bien les comprendre.

Je n’ai pas encore compris quel est le problème avec le ‹ à ›. D’accord l’accent n’est pas enlevé, mais quelle conséquence cela a sur les jeux eux-mêmes ?

Edit : ah si je sais. C’est ce qui nous a obligé à préciser ‹ a ›/‹ à › à chaque fois qu’on utilise ‹ à › dans les grammaires de nos verbes.

C’est le principal problème que je vois. Finalement le fait que les tirets ne sont pas gérés au milieu du mot, ça a l’avantage de nous forcer à faire autrement d’une manière qui marche toujours pour le joueur.

Le fonctionnement actuel : je veux que « grand-père » soit géré dans le jeu, j’ajoute « grand » et « pere » dans le name. Ainsi « regarder le grand-père » ça fonctionne. Pourquoi ? Parce que la phrase devient « regarder le grand -père » par l’ajout d’un espace, et après nettoyage des tirets la phrase est devenue « regarder le grand père » (j’occulte le nettoyage de ‹ le ›, j’ai oublié à quel moment ça prend place et pas nécessaire pour l’exemple. Il y a aussi le nettoyage des accents.). Et cerise sur le gateau pour les paresseux, « grand » et « père » fonctionneront pour le désigner aussi. En cas de plusieurs objets avec « grand » ou « père » c’est le système de disambiguation qui intervient : « précisez : le grand-père ou le père de Marc ? ».

Bref, sur la question des tirets, ce qu’avait fait JL me semble le meilleur compromis. Mais peut-être qu’un aspect m’échappe.

J’ai regardé pour les objets du compas. Qu’est-ce que le changement apporte à part du code un peu plus « beau » ? La version actuelle de la bibliothèque gère bien les directions, avec et sans tirets, grâce à un traitement spécifique dans LanguageToInformese. Aller au nord-est, Aller au nord est, nord-est, nord est, tout ça fonctionne.

  1. nord-est devient nord -est
  2. nord -est devient nord est
  3. LanguageToInformese repère « nord est » et le transforme en nordest ce qui correspond à la propriété ‹ name › de l’objet « nord-est ».

=> L’utilisateur ne voit rien et ça marche.

Il y a peut-être des bugs que cela cause et qui motiveraient à changer ce fonctionnement (mais si ça implique arrêter de couper les mots qui ont des tirets comme dit plus haut, je suis pas très chaud) ?

Si je comprends bien, on retire tous les ‹ à › de FrenchG.h, et une fois qu’on a retiré le dernier ‹ à › hop il sort du dico et donc ça retire le besoin même de les écrire dans les grammaires ? Joli.

Bon, mais si j’ai bien compris :

  • si on les met dans la grammaire on a besoin de les mettre dans la grammaire comme alternative à ‹ a ›. Ça marche mais c’est contraignant quand on écrit un nouveau verbe ou qu’on en modifie un.
  • si on les met pas dans la grammaire on n’a pas besoin (et surtout on ne DOIT pas) les mettre dans la grammaire. Ça marche mais ça cassera complètement si un joueur a le malheur de rajouter ‹ à › dans son jeu.

La meilleure solution ne serait-elle pas de traiter ce cas particulier dans enleve_accents (en plus de retirer les ‹ à › de la grammaire) afin de garantir que si un jeu rajoute ‹ à › dans le dictionnaire le retrait des accents fonctionne toujours ?

Autre question que cela soulève : veut-on parfois différencier ‹ à › et ‹ a › ?

Tu sembles avoir raison. Heureusement, je pense qu’il y a 0 conséquence. En effet, on n’a pas besoin de faire des modifications en cascade sur le même mot ! Mais un jour peut-être donc autant corriger la boucle.

J’ai committé un correctif sur la branch trunk de subversion, au pire si on s’est trompé on finira par le détecter. Mais j’ai fait quelques tests avec « trace 7 », qui permet d’afficher les infos de debug du parser, et ça semble fonctionner exactement pareil qu’avant, ce qui corrobore mon hypothèse selon laquelle c’était sans conséquence.

Exemple

>regarder dessus dessous nord-est sud ouest
[ LanguageToInformese:
* Buffer reçu : |regarder dessus dessous nord-est sud ouest|
  [ enleve_tirets :
  - Buffer reçu : |regarder sur -lui sous -lui  nordest  sudouest|
  - Buffer sans tirets : |regarder sur -lui sous -lui  nordest  sudouest|
  [ enleve_accents :
  - Buffer reçu : |regarder sur -lui sous -lui  nordest  sudouest|
  - Buffer sans accents : |regarder sur -lui sous -lui  nordest  sudouest|
  [ enleve_accents :
  - Buffer reçu : |regarder sur -lui sous -lui  nordest  sudouest|
  - Buffer sans accents : |regarder sur -lui sous -lui  nordest  sudouest|
* Buffer traduit en informese : |regarder sur -lui sous -lui  nordest  sudouest|
[ "regarder" regarder / "sur" sur / "-lui" -lui / "sous" sous / "-lui" -lui / "nordest" nordest / "sudouest" sudouest ]

!??
J’ai viré le continue, la routines est beaucoup plus rapide : pour for (i=0:i<NbMots():i++), la routine NbMots() et appelée à chaque itération ce qui est inutile tant qu’il n’y a pas eu de modifications.

La routine ne décolle, dorénavant, les apostrophes que pour les mots qui ne sont pas dans le dictionnaire.

Qu’est-ce qui fonctionnait avant et qui ne fonctionne plus avec mes modifications ?