La solution habituelle à la question "Comment puis-je compter les lancers de dés d'une manière spéciale dans AnyDice ?" est de :
- écrire une fonction qui prend un paramètre de séquence (c'est-à-dire un paramètre avec
:s
ajouté au nom du paramètre), et
- fournir votre pool de dés lancés en tant que paramètre à cette fonction.
AnyDice appellera alors automatiquement la fonction pour chaque combinaison possible (triée) obtenue lors du lancer des dés et collectera les résultats de la fonction dans un dé personnalisé, pondéré par la probabilité de lancer chaque combinaison. À l'intérieur de la fonction, la valeur du paramètre sera simplement une séquence fixe, et vous pourrez donc l'inspecter et la manipuler de la manière dont vous manipuleriez normalement une séquence, y compris en utilisant des conditions if
basées sur celle-ci.
Voici un exemple rapide qui devrait faire ce que vous voulez :
function: evaluate ROLL:s {
if [count 6 in ROLL] >= 2 {
result: ROLL + [explode d6]
} else {
result: ROLL
}
}
output [evaluate 3d6]
Qu'est-ce qui n'allait pas avec votre code, alors ?
Le problème principal était que, dans votre code, vous aviez if [select 2 from X] = 6
en dehors d'une fonction, où X
est un pool de dés (plus précisément 3d6
), pas une séquence.
La fonction select INDICES from SEQUENCE
(qui semble familière) est censée renvoyer une séquence, mais elle ne peut le faire que si les deux paramètres qui lui sont donnés sont des séquences réelles (ou des nombres, que AnyDice convertira volontiers en séquences à un seul élément). Comme je l'ai noté dans la réponse liée ci-dessus :
Si [un des paramètres est] un pool de dés, la fonction fonctionnera techniquement toujours, mais les résultats seront automatiquement ajoutés avant d'être collectés en tant que nombre dans un dé[.]
Ainsi, dans votre code, puisque X
est un dé (ou, plutôt, un pool de dés - la terminologie AnyDice est parfois un peu confuse ici), [select 2 from X]
sera également un dé. Par conséquent, [select 2 from X] = 6
sera aussi un dé - spécifiquement, un dé qui affiche 1 si le deuxième plus grand résultat de 3d6 est un 6, et 0 sinon. Et vous ne pouvez pas passer un dé à un if
dans AnyDice.
Comment auriez-vous pu corriger votre code, alors ?
La manière la plus simple (dans le sens où cela nécessite le moins de modifications à votre code) aurait été d'encadrer simplement l'instruction if
dans une fonction qui prend X
comme paramètre de séquence, comme ceci :
function: select INDICES:s from SEQUENCE:s {
RESULT: {}
loop INDEX over INDICES {
RESULT: {RESULT, INDEX@SEQUENCE}
}
result: RESULT
}
function: evaluate X:s {
if [select 2 from X] = 6 {
result: X + [explode d6]
} else {
result: X
}
}
output [evaluate 3d6]
(J'ai également corrigé un petit bug dans votre code où vous aviez [explode 6]
au lieu de [explode d6]
. Avec ce changement, ce code donne exactement le même résultat que mon premier exemple de programme ci-dessus.)
Ps. Il existe en fait une méthode pour en quelque sorte faire en sorte qu'AnyDice supporte les conditions if
basées sur les dés, en utilisant une fonction auxiliaire comme ceci :
function: if CONDITION:n then A else B {
if CONDITION { result: A } else { result: B }
}
Cependant, si vous essayez de réécrire votre code en utilisant cette astuce, quelque chose comme ceci :
output [if [select 2 from X] = 6 then X + [explode d6] else X]
ou même comme ceci :
output X + [if [select 2 from X] = 6 then [explode d6] else 0]
vous constaterez que ces programmes donnent des résultats subtilement incorrects : la moyenne sera en fait correcte, mais l'écart-type et la forme du graphique de distribution seront légèrement incorrects :
Les utilisateurs expérimentés d'AnyDice, bien sûr, réaliseront rapidement quel est le problème : dans les expressions ci-dessus, chaque X
représente un lancer de 3d6 indépendant séparé. Ainsi, le mécanisme réel de jet de dés qui finit par être modélisé ici n'est pas "lancer 3d6, puis ajouter un d6 explosif si vous avez roulé au moins deux six", mais plutôt "lancer 3d6, puis lancer à nouveau 3d6 et ajouter un d6 explosif si vous avez roulé au moins deux six lors du premier lancer de 3d6".
Bien sûr, encadrer le code ci-dessus dans une fonction, de sorte que X
devienne une séquence au lieu d'un dé, le fait fonctionner comme prévu :
function: evaluate X:s {
result: [if [select 2 from X] = 6 then X + [explode d6] else X]
}
output [evaluate 3d6]
Essentiellement, chaque fois que vous voulez implémenter un mécanisme dans AnyDice où vous lancez des dés et utilisez le résultat du lancer plus d'une fois, vous devez écrire une fonction et passer le lancer en tant que paramètre de séquence. C'est la seule façon dans AnyDice de "figer" le résultat d'un lancer de dés dans une séquence fixe (ou un nombre).
0 votes
Salut Aralkis, bienvenue sur RPG Stack Exchange ! Fais le tour si ce n'est pas déjà fait, et consulte le centre d'aide pour plus d'informations.
1 votes
Il semble que vous ayez trouvé une solution, mais vous n'êtes pas censé l'ajouter dans votre question. Au lieu de cela, postez-la en tant que réponse et acceptez cette réponse. Cela marque la question comme résolue et montre aux gens quelle est la solution.
0 votes
D'accord, merci. C'est mon premier message à la bourse.