Un module essentiel de PARAGANOS est celui permettant de simuler des dés. Il dispose pour l'instant de deux implémentations, la première en C++, comprenant un analyseur syntaxique d'expressions de dés, la seconde en Lisp.
Ce module est relativement simple, et ses implémentations dépendent chacune d'une bibliothèque de nomres pseudo-aléatoires de qualité pour le hasard. Pour ce module, l'objet de base est le lançable, un objet que l'on peut lancer, opération qui modifie sa valeur, que l'ont peut lire sans le lancer à nouveau.
Il constitue pour l'instant l'intégralité du code source.
Je passe ici sur les détail d'implémentation, et notamment sur tous les types servant uniquement de base à ceux qui seront concrètement utilisés. Pour connaître la hiérarchie de classes complète, UTSL.
Qu'on le lance ou pas, sa valeur est fixe. Il sert essentiellement à construire des séquences de dés.
Sa valeur est un nombre aléatoire compris entre 1 et son nombre de faces, inclus.
Ce dé, si sa valeur lorsqu'il est lancé est un nombre fixé à l'avance (sa valeur de relance), est lancé une seconde fois. On ajoute les valeurs des deux lancers pour obtenir la valeur de ce dé particulier.
Celui-ci fonctionne comme le précédent, à la différence que si un lancé ultérieur est à nouveau la valeur de relance, on continue à relancer, jusqu'à obtenir une valeur différente. On ajoute les valeurs de tous les lancers pour obtenir la valeur de ce dé particulier.
Ce lançable encapsule un autre lançable et un signe (négatif ou positif). Sa valeur est la valeur du lançable encapsulé ajustée par le signe. Quand on le relance, on relance bien entendu le lançable encapsulé.
Ce conteneur est une séquence de lançables. Sa valeur est simplement la somme des valeurs de tous ses lançables. Quand on le relance, on relance individuellement chacun des lançables.
La bibliothèque C++ comprend un analyseur syntaxique pour séquence de dés. Il transforme une expression
du type 1d6+2 ou 2d10+1d4-5 en une séquence de lançables.
La syntaxe EBNF d'une expression de séquence de dés est la suivante :
chiffre = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' ;
entier = { chiffre } ;
dé = entier, ( 'd' | 'D' ), entier ;
fixe = entier ;
atome = dé | fixe ;
atome_signé = ( '+' | '-' ), atome ;
séquence = ( atome | atomé_signé ), { atom_signé } ;
Il resterait à trouver une syntaxe pour les autres types de lançables, c'est-à-dire les dés à relancer. Je pensais utiliser des crochets ou des accolades après le dé, contenant la valeur de relance et le nombre de relances (1 ou inf pour l'infini), séparés par une barre oblique :
d6[6/1]d10[1/inf]On pourrait permettre des valeurs par défaut, notamment en lien avec le code de la bibliothèque. La valeur de relance par défaut serait le nombre de faces du dé, et le nombre de relances par défaut l'infini (parce qu'il me semble que c'est ce qu'on trouve le plus souvent dans les jeux que je connais) :
d6[/1]d10[1]d20[]La bilbiothèque d'analyse syntaxique utilisée, Spirit, permet de construire une grammaire avec des objets C++, ce qui permettrait de modifier dynamiquement la grammaire par des portions de syntaxe fournies par des bibliothèques chargées dynamiquement.
La syntaxe EBNF deviendrait :
chiffre = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' ;
entier = { chiffre } ;
dé = entier, ( 'd' | 'D' ), entier ;
fixe = entier ;
atome = autres_atomes | dé | fixe ;
atome_signé = ( '+' | '-' ), atome ;
séquence = ( atome | atomé_signé ), { atom_signé } ;
où autres_atomes serait une alternative de toutes les syntaxes fournies dynamiquement.
© 2005—2007 Pierre THIERRY