8 votes

ANYDICE: Comment lancer 3d6 et, dans le cas où 2 d'entre eux sont un 6, ajouter un 1d6 explosé au résultat?

À peu près la question. J'ai essayé ce qui suit :

function: select INDICES:s from SEQUENCE:s {
  RESULT: {}
  loop INDEX over INDICES {
    RESULT: {RESULT, INDEX@SEQUENCE}
  }
  result: RESULT
}
X:3d6

if [select 2 from X] = 6 {
    output X + [explode 6]
}
else {
    output X
}

Mais j'obtiens ce qui suit :

Erreur de calcul :

Les valeurs booléennes ne peuvent être que des nombres, mais vous avez fourni "d{?}".
Selon ce que vous voulez, vous devrez peut-être créer une fonction.

Qu'est-ce que je fais de mal ?

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.

11voto

trjh Points 11

La solution habituelle à la question "Comment puis-je compter les lancers de dés d'une manière spéciale dans AnyDice ?" est de :

  1. é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
  2. 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 :

Capture d'écran AnyDice montrant les résultats corrects et incorrects calculés en utilisant les méthodes décrites ci-dessus

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

Merci, ça marche. Ouais, j'ai trouvé ce select quelque part dans la séquence ici. J'ai fini par trouver un post avec une fonction conditionnelle personnalisée. De cette façon, elle accepte les dés en entrée.

0 votes

@Aralkis: Oui, cette fonction d'aide semble également familière. :) Tu n'en as pas vraiment besoin, cependant - si tu essaies de l'utiliser en dehors d'une fonction, où X est un dé, cela donne des résultats légèrement incorrects, car chaque X dans l'expression représente un jet de 3d6 séparé. Et bien qu'il fonctionne correctement à l'intérieur d'une fonction, où X est une séquence, une instruction normale if fonctionnera également là. Voir le post-scriptum que j'ai ajouté à ma réponse ci-dessus pour plus de détails.

0 votes

Oui, j'ai compris ça. Merci pour l'aide et d'avoir été minutieux. Maintenant, je comprends un peu mieux anydice.

2voto

Aralkis Points 91

Merci pour l'aide. Comme suggéré, ici et ailleurs, si vous écrivez votre propre fonction conditionnelle, cela fonctionne comme on pourrait s'y attendre :

function: if CONDITION:n then A else B {
  if CONDITION { result: A } else { result: B }
}

J'ai fini par écrire le code suivant :

function: if CONDITION:n then A else B {
  if CONDITION { result: A } else { result: B }
}
function: roll DICE:s {
   ROLL:[if (2@DICE = 6) then (DICE + [explode 1d6]) else DICE]
   result: ROLL
}
output [roll 3d6]

AlleGamers.com

AlleGamers est une communauté de gamers qui cherche à élargir la connaissance des jeux vidéo.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X