Question bête, qu’on vient de remarquer sur ClubFloyd : quand on fait un jeu à la troisième personne, est-ce qu’il ne vaudrait mieux pas reconnaître les commandes >x lui ou >x elle ? (Plutôt que >x moi, qui est cohérent avec « vous » ?)
C’est pas faux, mais ça causerait un conflit dans les pronoms.
« >prendre elle » (ce qui n’est pas très correct grammaticalement parlant…) est compris comme « >la prendre ». Par exemple :
[code]>x la clef
Cette vieille clef est toute rouillée. Elle pense qu’elle ouvre le coffre.
prendre elle
Elle prend la clef.[/code]
À la deuxième action, le personnage-joueur prend la clef, mais devrait-il se prendre lui-même à la place, comme tu l’indiques ? Je ne pense pas. Donc à mon avis, c’est pas vraiment faisable de faire ce que tu proposes.
On peut en revanche écrire « >se x » pour s’examiner soi-même (ou « >me x », ou « >vous x », etc.).
Aussi, c’est marrant, je pense que personne ne penserait à écrire « >examiner elle », mais pourtant « >x elle » ne dérange pas vraiment.
Je ne sais pas exactement comment c’est géré en anglais, mais c’est l’une des commandes qu’elles ont essayé, alors je me demandais. Mais oui ça doit être sûrement pareil, parce que y’a toujours le problème des pronoms ! Du coup, nevermind hein
Je pense que c’est parce qu’en anglais, on met « her » après le verbe, alors qu’en français, comme je l’ai dit, c’est pas correct d’écrire « examiner elle » ; le pronom doit être avant le verbe.
Et puis je viens de tester, en anglais, ça ne comprend que « me » et « myself ». Faudrait limite considérer ça comme un bug…
Enfin bref, je pense que ça vaut pas la peine de se fatiguer dessus. ^^ La prochaine fois, tu leur diras qu’en bon français on écrit « s’examiner » !
J’ai réécrit entièrement et à partir de zéro la routine permettant d’afficher les nombres en lettres. Et tout semble fonctionner, hourra !
L’ancienne affichait des espaces en trop, parfois en moins aussi, des « s » où il n’en fallait pas (c’est une vrai plaie les « quatre-vingts » et les « cents » !) et autres choses du même genre.
La mienne paraît fonctionner correctement. Je met le code dessous au cas où quelqu’un trouverait une erreur rien qu’en le lisant. Je vous invite à tester, parce que j’ai pas eu le courage d’essayer tous les nombres jusqu’à 2 147 483 647.
[code]Include (-
Array LanguageNumbers table
‹ un › 1 ‹ une › 1 ‹ deux › 2 ‹ trois › 3 ‹ quatre › 4 ‹ cinq › 5
‹ six › 6 ‹ sept › 7 ‹ huit › 8 ‹ neuf › 9 ‹ dix › 10
‹ onze › 11 ‹ douze › 12 ‹ treize › 13 ‹ quatorze › 14 ‹ quinze › 15
‹ seize › 16 ‹ dix-sept › 17 ‹ dix-huit › 18 ‹ dix-neuf › 19 ‹ vingt › 20
‹ vingt et un › 21 ‹ vingt-deux › 22 ‹ vingt-trois › 23 ‹ vingt-quatre › 24
‹ vingt-cinq › 25 ‹ vingt-six › 26 ‹ vingt-sept › 27 ‹ vingt-huit › 28
‹ vingt-neuf › 29 ‹ trente › 30
;
[ LanguageNumber n s f;
! L’argument « s » sert à spécifier si on n’est pas en train de construire la fin du nombre(c-à-d les 3 derniers chiffres). Si s == 1, alors on est à l’intérieur du nombre et on ne peut pas ajouter un « s » à « cent » et à « quatre-vingt ».
if (n == 0) { print « zéro »; rfalse; }
if (n < 0) { print "moins "; n = -n; }
#Iftrue (WORDSIZE == 4);
if (n >= 1000000000)
{
LanguageNumber(n/1000000000, 1); print " ";
print « milliard »;
if (n/1000000000 > 1) { print « s »; }
f = 1;
n = n%1000000000;
}
if (n >= 1000000)
{
if (f == 1) { print " "; }
LanguageNumber(n/1000000, 1); print " ";
print « million »;
if (n/1000000 > 1) { print « s »; }
f = 1;
n = n%1000000;
}
#Endif;
if (n >= 1000)
{
if (f == 1) { print " "; }
if (n/1000 ~= 1) { LanguageNumber(n/1000, 1); print " "; }
print « mille »;
f =1;
n = n%1000;
}
if (n >= 100)
{
if (f == 1) { print " "; }
if (n/100 ~= 1) { LanguageNumber(n/100); print " "; }
print « cent »;
if (n%100 == 0 && n/100 > 1 && s == 0) {print « s »; }
f = 1;
n = n%100;
}
if (n >= 10)
{
if (f == 1) { print " « ; }
switch(n/10)
{
1: if (n == 11) { print « onze »; return; }
if (n == 12) { print « douze »; return; }
if (n == 13) { print « treize »; return; }
if (n == 14) { print « quatorze »; return; }
if (n == 15) { print « quinze »; return; }
if (n == 16) { print « seize »; return; }
if (n == 10 || n >= 17 ) { print « dix »; }
2: print « vingt »;
3: print « trente »;
4: print « quarante »;
5: print « cinquante »;
6: print « soixante »;
7: print « soixante »;
if (n-60 == 11) { print " et onze »; return; }
print « - »; LanguageNumber(n-60); return;
8: print « quatre-vingt »;
if (n%10 == 0 && s == 0) { print « s »; }
if (n%10 == 1) { print « -un »; return; }
9: print « quatre-vingt »;
print « - »; LanguageNumber(n-80); return;
}
if (n%10 == 1) { print " et "; }
if (n%10 > 1) { print « - »; }
n = n%10;
}
switch(n)
{
1: print « un »;
2: print « deux »;
3: print « trois »;
4: print « quatre »;
5: print « cinq »;
6: print « six »;
7: print « sept »;
8: print « huit »;
9: print « neuf »;
}
];
-) instead of « Numbers » in « Language.i6t ».[/code]
Quand j’aurai le temps, je m’attaquerai aux heures en lettres.
(au passage, c’est le premier code I6 que j’écris tout seul. )
EDIT d’une journée plus tard:
C’est aussi fait pour les heures ! (plus quelques corrections dans la routine ci-dessus.)
Comme pour les nombres, ce serait bien si vous jetiez un coup d’œil au code et que vous testiez (ce coup-ci j’ai pu tout essayer, il n’y a « que » 1440 heures possibles )
Include (-
[ PrintTimeOfDayEnglish t h m dir aop half;
h = (t/ONE_HOUR); m = t%ONE_HOUR; dir = " ";
if (m > HALF_HOUR) { h = h+1; if (h == 24) h = 0; m = ONE_HOUR-m; dir = " moins "; half = 1; }
switch(h)
{
0: print "minuit";
1: print "une heure";
12: print "midi";
21: print "vingt et une heures";
default: print (number) h, " heures";
}
if (m > 0)
{
print (string) dir;
switch(m)
{
1: print "une";
21: print "vingt et une";
QUARTER_HOUR: if (half == 0) print "et "; else print "le "; print "quart";
HALF_HOUR: print "et demie";
default: print (number) m;
}
}
];
-) instead of "Analogue Printing" in "Time.i6t".
L’ancien code n’affichait pas en format 24 heures, écrivait des « s » en trop, et était vraiment compliqué pour rien (certains morceaux étaient dans des conditions qui étaient toujours fausses, par exemple !).
L’extension est presque finie !
P. S. — Au fait, est-ce que ces routines sont aussi dans les biblis francophones d’I6 ? Si c’est le cas, il faudra les remplacer par les nouvelles ci-dessus.
Beau travail !
Justement je crois que non, je crois que ça faisait partie du code qu’on avait la flemme de regarder en détail Je vais essayer de tester ça bientôt, et je les rajouterai ! Merci à toi !
Est-ce qu’il y a un moyen de comparer des caractères unicode en I6 ? Parce que si on peut le faire avec I7, ça doit être possible, non ?
Du style, ça ça fonctionne (I7) :
if the character number 1 in T matches the text "œ":
blablabla;
Mais pas ça (I6) :
if (text->0 == 'œ') blablabla;
Je sais qu’on peut utiliser « @oe » pour l’affichage de la ligature, mais ça marche pas pour la comparaison.
Tout ça pour provoquer l’élision du déterminant avec des mots comme « œil ». J’ai contourné le problème avec le code I7 ci-dessus, mais ce serait mieux directement dans la routine LanguageContraction, je pense.
Et en comparant les numéros de codes ZSCSII ? J’ai pas la syntaxe en tête, mais le DM4 en parle. J’ai chez moi des exemples de codes qui manipulent toutes les tables de caractères, je vais jeter un oeil.
Oui, c’est Table 2B dans le DM4. Pour le e dans l’o, c’est numéro 220
Je sais pas si c’est possible de comparer des chaînes en Unicode par contre !
Qu’est-ce que tu veux dire par « c’est pour l’élision du déterminant » ? C’est pas fait de base par la bibli ?
EDIT: arf non en effet, c’est pas fait de base pour la bibli ! Zut alors ! Je me charge de la modif pour les biblis I6. Merci à toi !!
Je viens de tester ton code pour les nombres ! Il y a un bug pour 4608 et 181
J’ai aussi simplifié du code (if n-60==11 → if n==71…) et utilisé une plus grande table pour les cas finaux, ce qui me permet de me débarasser des appels récursifs à LanguageNumber pour 60 et 80.
Pour LanguageNumbers, j’allais faire une remarque comme quoi ça serait bien d’aller y chercher les résultats, mais pour tout dire je viens de m’apercevoir que je n’ai aucune idée d’à quoi ce truc sert. J’ai demandé sur intfikcheunne.
Bref, nouvelle version du code :
[ LanguageNumber n s f;
! L'argument "s" sert à spécifier si on n'est pas en train de construire la fin du nombre(c-à-d les 3 derniers chiffres). Si s == 1, alors on est à l'intérieur du nombre et on ne peut pas ajouter un "s" à "cent" et à "quatre-vingt".
if (n == 0) { print "zéro"; rfalse; }
if (n < 0) { print "moins "; n = -n; }
#Iftrue (WORDSIZE == 4);
if (n >= 1000000000)
{
LanguageNumber(n/1000000000, 1); print " ";
print "milliard";
if (n/1000000000 > 1) { print "s"; }
f = 1;
n = n%1000000000;
}
if (n >= 1000000)
{
if (f == 1) { print " "; }
LanguageNumber(n/1000000, 1); print " ";
print "million";
if (n/1000000 > 1) { print "s"; }
f = 1;
n = n%1000000;
}
#Endif;
if (n >= 1000)
{
if (f == 1) { print " "; }
if (n/1000 ~= 1) { LanguageNumber(n/1000, 1); print " "; }
print "mille";
f = 1;
n = n%1000;
}
if (n >= 100)
{
if (f == 1) { print " "; }
if (n/100 ~= 1) { LanguageNumber(n/100); print " "; }
print "cent";
if (n%100 == 0 && n/100 > 1 && s == 0) {print "s"; }
f = 1;
n = n%100;
}
if (n >= 20)
{
if (f == 1) { print " "; }
switch(n/10)
{
2: print "vingt";
3: print "trente";
4: print "quarante";
5: print "cinquante";
6: print "soixante";
7: print "soixante";
if (n == 71) { print " et onze"; return; }
8: print "quatre-vingt"; if (n == 80 && s == 0) { print "s"; } if (n == 81) { print "-un"; return; }
9: print "quatre-vingt";
}
if (n%10 == 1) { print " et "; }
if (n%10 > 1) { print "-"; }
n = n%10;
f=0;
}
if (f == 1) { print " "; }
! ceci ne marche pas : print (string) LanguageNumbers->(n-1); return;
switch(n)
{
1: print "un";
2: print "deux";
3: print "trois";
4: print "quatre";
5: print "cinq";
6: print "six";
7: print "sept";
8: print "huit";
9: print "neuf";
10: print "dix";
11: print "onze";
12: print "douze";
13: print "treize";
14: print "quatorze";
15: print "quinze";
16: print "seize";
17: print "dix-sept";
18: print "dix-huit";
19: print "dix-neuf";
}
];
Pour les heures, quand tu dis « le vieux code », c’est lequel ? En fait, je ne crois pas qu’il y ait d’équivalent à « PrintTimeOfDayEnglish » dans la bibliothèque I6. C’est utilisé pour quoi exactement ?
J’ai pas vu l’erreur avec 181. Par contre, c’est bien vu pour 4608. Pour le « if n-60 == 11 », j’avoue que j’ai un peu honte…
Pour l’array au début, moi aussi je me demandais à quoi il pouvait servir, vu que dans la routine originale en anglais, un switch était aussi utilisé, plutôt que d’aller chercher les nombres dans la table.
Pour la routine sur les heures c’est pour afficher l’heure en lettres.
La description de la montre est "Il est [time of day in words].".
Ce qui affichera quelque chose comme « Il est quatorze heures et quart » ou « Il est neuf heures moins vingt » par exemple. C’est une routine incluse par défaut dans I7.
Le vieux code, c’est celui dans ce post.
Pour le « œ », tu l’a rajouté dans la bibli d’I6 ? Ça marche ou pas ? Par défaut, Inform ne reconnaît pas ce caractère.
En passant…
Pour LanguageNumber(), j’avais fait ça :[ LanguageNumber n; !-32768 <= n <= +32767
if (n == 0) { print "zéro"; rfalse; }
if (n < 0) { print "moins "; n=-n; }
if (n >= 1000) {
if (n >= 2000){ print (LanguageNumber) n/1000; print " ";}
print "mille";
n = n%1000;
if (n) print " ";
}
if (n >= 100) {
if (n >= 200){ print (LanguageNumber) n/100; print " ";}
print "cent";
if (n == 100) rfalse;
n = n%100;
if (n) print " "; else print "s";
}
if (n==0) rfalse;
switch(n)
{
1: print "un"; ! "une" ?
2: print "deux";
3: print "trois";
4: print "quatre";
5: print "cinq";
6: print "six";
7: print "sept";
8: print "huit";
9: print "neuf";
10: print "dix";
11: print "onze";
12: print "douze";
13: print "treize";
14: print "quatorze";
15: print "quinze";
16: print "seize";
17: print "dix-sept";
18: print "dix-huit";
19: print "dix-neuf";
20: print "vingt";
30: print "trente";
40: print "quarante";
50: print "cinquante";
60: print "soixante";
70: print "soixante-dix";
71: print "soixante et onze";
72 to 79: print "soixante-", (LanguageNumber) 10 + n%10;
80: print "quatre-vingts";
81 to 89: print "quatre-vingt-", (LanguageNumber) n%10;
90 to 99: print "quatre-vingt-", (LanguageNumber) 10 + n%10;
default:
print (LanguageNumber) n - n%10;
if (n%10 == 1) print " et "; else print "-";
print (LanguageNumber) n%10;
}
];
L’intervalle est, par contre, celui d’un entier signé de 16 bits (-32768 <= n <= +32767).
Il me semble qu’il faut se méfier des problèmes d’accords que pose l’usage combiné de mille, million et miliard.
« MILLE MILLIARDS DE MILLE SABORDS DE TONNERRE DE BREST ! »
Auraes: merci pour le code - oui, ça revient au même, l’autre code est peut-être un peu plus verbeux mais bon. Et oui, il y a peut-être des subtilités pour millions et milliards, à regarder !
Natrium: pour 181 c’était genre « cent quatre-vingt et un » au lieu de « cent quatre-vingt un » (en tout cas à l’oral je le dis comme ça :p).
En ce qui concerne LanguageNumbers, j’ai eu une réponse : c’est utilisé dans parserm.h, et il faut utiliser « print (address) LanguageNumbers–>N » ; j’avais pas vu ! Si c’est le cas, on peut remplacer le switch de la fin par un lookup dans le tableau, c’est pratique Je modifierai le code quand j’aurai le temps.
Pour le oe, c’est fait (erf, Bitbucket n’affiche pas bien les accents - mais si tu télécharges le fichier ça ira. Bref, j’ai fait tous les accents et j’ai aussi remplacé les ç et ñ et ÿ dans l’input du joueur par des c, n, y.)
Vous êtes dans la confusion avec l’Unicode (UTF-8) : œ ou @oe ne posent pas de problèmes avec I6, quelque soit l’usage ; le code affiche dans les deux cas : OK.
[code]!% -Cu
Array text → « œuf »;
[ main key;
if (text->0 == ‹ œ ›)
print « OK »;
@read_char 1 → key;
];[/code][code]Array text → « @oeuf »;
[ main key;
if (text->0 == ‹ @oe ›)
print « OK »;
@read_char 1 → key;
];[/code]I6 ne gère l’UTF-8 (optionnel) que pour le source, il disparaît lors du prétraitement. Le programme compilé ne gère pas l’Unicode.
Cette situation ne peut pas arriver je pense, puisque le nombre le plus grand possible avec Glulx est 2 147 483 647, donc pas de mille milliards.
J’ai essayé, Inform 7 (Glulx en particulier) gère l’unicode, apparemment. J’ai essayé ces deux cas-ci:
print (char) 220;
print (char) 339;
Le premier affiche « Ü » alors que 220 est le code ZSCII de « œ ».
Le deuxième affiche bien « œ », car 339 est le code unicode de « œ » (en décimal).
De plus,
print "œ";
affiche en jeu « [unicode 339] » (littéralement).
Enfin, j’aimerai savoir exactement quel code coller et où le faire pour gérer l’élision de « œ ». Et il faut que ça marche avec Glulx, dans Inform 7. Merci !
(Pas besoin de se soucier de z-machine, le simple fait d’écrire son jeu en français le rend trop lourd pour ce format.)
EDIT : à la ligne 745 de French.h, il y a la routine LanguageNumber, mais une ancienne version, pas celle qu’on vient de faire.
OK, j’ai trouvé le problème : Glulx n’a pas la même table de caractères que la Z-Machine Auraes tu as testé en Z-code et en effet ça marche ; Natrium tu as compilé du Glulx et ça marche pas ! Je pense que c’est un bug du compilateur Glulx, ou juste une différence dans la conception…
Du coup, j’ai corrigé mes fonctions IsAnA et tout, cf mon BitBucket. Mais ça n’a pas l’air de marcher, quoi que je fasse. En fait, je soupçonne que mon compilateur Glulx est trop vieux…
Est-ce que quelqu’un pourrait tester mes fonctions ? Genre « IsAnO(‹ @oe ›) » devrait renvoyer 1, et donc l’élision devrait bien se faire… Sinon c’est que je me suis trompé quelque part.
Natrium: Je comprends pas l’histoire de la ligne 745, tu veux dire sur mon BitBucket ? Si c’est le cas c’est la toute dernière version (regarde le switch ou l’appel à LanguageNumbers–>(2*n+1) tout à la fin).
Pour gérer l’élision, en I6 c’est dans une fonction qui s’appelle LanguageContraction, qui renvoie 1 si il faut faire une élision et 0 sinon. Cf mon code, ligne 710 !
Fin de l’histoire : @oe fera un bug dans Glulx tant que Glulx ne supportera pas les caractères unicode avec un numéro plus grand que 256 ! (Si vous compilez, ça vous donne « Erreur: les char unicode >256 ne sont pas encore supportés »)
Quand on met les caractères dans un string, c’est en fait un byte-array avec des valeurs entre 0 et 255, et le pauvre « oe » est le seul caractère accentué supporté par la z-machine qui a un numéro unicode >256… du coup le test « c == 339 » ne sera jamais vrai (‹ @oe ›, c’est 339, mais quand on essaie d’y accéder on obtient 83 parce que 256+83=339…), et donc un jeu Glulx écrira toujours « le oeil » tant que la feature ne sera pas rajoutée à glulx. Je fais un ticket sur mantis en suivant.
Ouaip, je viens d’essayer, ça marche pas.
N’empêche, Inform 7 peut comparer « œ », et comme le code I7 est traduit en I6 lors de la compilation, ça doit bien être possible à le faire directement en I6, non ? Parce que j’ai quand même réussi à provoquer l’élision avec « œuf » avec le code suivant :
To say le/la/les/l' (O - object):
unless the character number 1 in "[O]" matches the text "œ", case insensitively:
say "[the O]";
else:
say "l['][O]".
Je vais garder ça en attendant alors.
(dommage que 83 corresponde à un s majuscule. Si c’était un caractère qui n’était pas susceptible d’être au début du nom d’un objet, on aurait pu remplacer par ça. Encore qu’un nom commun ne commence pas si souvent par un s majuscule.)
Par ailleurs, quand j’ai copié ton code, ça faisait planter le compilateur si je remplaçais pas « Tokenise__(buffer,parse); » par « VM_Tokenise(buffer,parse); »
Dans le code que j’ai, le premier est systématiquement commenté en faveur du second. Je sais pas si tu devrais revoir ton code pour ça, vu que je ne sais pas ce que ça fait.
Enfin, oublie ce que j’ai dit sur la ligne 745.
Tokenise__ est une fonction présente dans les biblis I6, et apparemment VM_Tokenise apparaît dans plein de code I7 - je pense que VM_Tokenise c’est spécifique à I7, en tout cas ça n’existe pas en I6
Hmm, intéressant que ça marche en I7 ! Je sais pas comment c’est fait, mais c’est chouette
Dans la mesure ou le source de la bibliothèque i7 est en UTF-8, il doit être possible de détecter ‹ œ › (C593 en Hexa) avec du code I6 dans la bibliothèque i7 comme ceci :
if (text->0 == $C5 && text->1 == $93)
[ LanguageContraction text;
if (text->0 == 'a' or 'e' or etc...) ! caractères <= 256
return 1;
if (test->0 == $C5 && text->1 == $93 or $92) ! œ Œ
return 1;
return 0;
];
Pas testé.