28 votes

Comment calcule-t-on la distribution des statistiques de roulement à la manière de Matt Colville ?

Plus précisément, la manière Matt Colville de rouler les statistiques es:

  1. Lancez 4d6, laissez tomber le dé de valeur la plus basse pour 1 stat ;
  2. Si ce jet est inférieur à 8, relancez-le ;
  3. Répétez les étapes 1 et 2 jusqu'à ce que vous ayez un ensemble de 6 stats supérieures à 8 ;
  4. S'il n'y a pas au moins 2 valeurs de 15 ou plus dans cet ensemble, laissez tomber et recommencez.

J'ai écrit un code AnyDice pour calculer la distribution de ce processus, mais je suis resté bloqué sur ce point :

function: ROLL:n reroll BAD:s as REROLL:d {
  if ROLL = BAD { result: REROLL }
  result: ROLL
}
function: ROLL:d reroll BAD:s {
  loop I over {1..20} {
    ROLL: [ROLL reroll BAD as ROLL]
  }
  result: ROLL
}
X: [highest 3 of 4d6]
Y: 6 d[dX reroll {3..7}]
loop P over {1..6} {
 output P @ Y named "Ability [P]"
}

Cela me donne les probabilités pour toutes mes capacités individuellement, mais ne prend pas en compte la défausse de la série s'il n'y a pas au moins 2 15. Comment dois-je faire pour que cela soit pris en compte (ou comment calculer cette distribution d'une autre manière) ?

1 votes

Question : Si vous allez dans la vue roller, vous lancez 6 fois '4d6 drop lowest' pour chaque score de capacité, et ensuite vous faites ceci pour chacun des 6 scores de capacité, ce qui vous donne un total de 36 séries de '4d6 drop lowest'. Est-ce voulu ?

0 votes

@JRodge01 Cela ne semble pas garantir que vous vous retrouverez avec tous les scores de 8 et plus.

0 votes

Je ne suis pas sûr que le code fasse ce que le programmeur pense qu'il fait, même sans assurer les 8 et plus.

40voto

Juliet Points 40758

Je me suis lancé et j'ai implémenté ceci dans R. Vous pouvez voir le code ici : https://gist.github.com/DarwinAwardWinner/34dd19f302bd1ef24310f6098dc3218d

Ce code énumère tous les jets possibles de "4d6 drop lowest, reroll 7 or lower" afin de déterminer les probabilités exactes de lancer chaque statistique de 8 à 18. Il les utilise ensuite pour calculer la probabilité exacte de lancer chaque ensemble possible de 6 statistiques, en rejetant les ensembles de statistiques sans au moins 2 statistiques de 15 ou plus. Il est intéressant de noter qu'environ 54% des jets de statistiques avec tous les 8 ou plus n'auront pas 2 statistiques de 15 ou plus, ce qui signifie que pour chaque jet de statistiques, vous avez plus de chances que de chances de devoir relancer à partir de zéro. Selon que vos joueurs aiment ou non lancer des statistiques, cela peut être un avantage ou un inconvénient.

Voici un graphique de la distribution de chaque statistique. A est la statistique la plus élevée, B est la deuxième plus élevée, et ainsi de suite, avec F étant la statistique la plus basse. L'axe Y représente la probabilité d'obtenir un certain nombre de points. Par exemple, votre deuxième valeur la plus élevée a environ 57 % de chances d'être un 15, et 0 % de chances d'être inférieure à ce chiffre (par définition).

Stat distribution plot

Nous pouvons également obtenir quelques statistiques sur les distributions. \$Q_{25}\$ y \$Q_{75}\$ sont les 25ème et 75ème percentiles.

\begin {array}{l|r r r r r r} \textbf {Ability} & \textbf {Min} & \boldsymbol Q_{25} & \textbf {médiane} & \textbf {Mean} & \boldsymbol Q_{75} & \textbf {Max} \\ \hline \text {A} & 15 & 16 & 16 & 16.5 & 17 & 18 \\ \text {B} & 15 & 15 & 15 & 15.5 & 16 & 18 \\ \text {C} & 8 & 13 & 14 & 14.0 & 15 & 18 \\ \text {D} & 8 & 12 & 13 & 12.7 & 14 & 18 \\ \text {E} & 8 & 10 & 11 & 11.3 & 12 & 18 \\ \text {F} & 8 & 9 & 10 & 9.8 & 11 & 18 \\ \end {array}

Bien sûr, mon code calcule la distribution complète pour tous les jets de statistiques possibles, donc si vous êtes curieux de connaître d'autres facettes des données, comme la valeur d'achat des points, n'hésitez pas à exécuter le code et à expérimenter.

0 votes

C'est génial ! Savez-vous comment faire la même chose dans AnyDice ?

4 votes

@BogdanIonica Non, c'est pour cela que je l'ai écrit en R. Je ne suis pas un expert des fonctionnalités avancées d'AnyDice, mais j'ai beaucoup d'expérience dans la réalisation de statistiques en R.

0 votes

J'ai trouvé par une méthode indépendante chaque ensemble individuel de rouleaux qui peut être lancés, en respectant les contraintes de la distribution des statistiques de Colville, ainsi que les probabilités que chacun d'entre eux soit lancé, que j'ai posté aquí . Si vous introduisez ces statistiques dans votre programme, vous pouvez obtenir des probabilités exactes au lieu de faire un Monte-Carlo, et mettre à jour le graphique et le tableau avec ces résultats exacts. Je vais poster ma propre réponse expliquant comment j'ai fait cela.

34voto

Carcer Points 60981

Les éléments suivants programme anydice vous montrera à quoi ressemble la distribution statistique des résultats des scores d'aptitude pour la méthode Colville.

function: roll ROLL:n min MIN:n{
 if ROLL < MIN { result: d{} }
 result: ROLL
}

function: colville ARRAY:s INDEX:n {
  if (ARRAY >= 15) < 2 { result: d{} }
  result: INDEX@ARRAY
}

ROLL: [highest 3 of 4d6]
SCORE: [roll ROLL min 8]
ARRAY: 6dSCORE

output [colville ARRAY 1] named "Score 1"
output [colville ARRAY 2] named "Score 2"
output [colville ARRAY 3] named "Score 3"
output [colville ARRAY 4] named "Score 4"
output [colville ARRAY 5] named "Score 5"
output [colville ARRAY 6] named "Score 6"

L'astuce ici est que nous ne voulons pas avoir à relancer quoi que ce soit, car les fonctions récursives sont coûteuses et prennent une éternité (de plus, il y a une limite à la distance que Anydice peut parcourir). Heureusement, nous disposons d'un raccourci très astucieux que nous pouvons utiliser dans le cas spécifique du relancement jusqu'à ce que nous obtenions un résultat qui se situe dans la fourchette souhaitée ; nous pouvons utiliser une fonction comme filtre pour vérifier que la valeur se situe dans la fourchette souhaitée, et retourner la valeur d'entrée si c'est le cas, ou le soi-disant dé vide, d{} si ce n'est pas le cas.

Le résultat du dé vide est en fait écarté lorsqu'anydice calcule les probabilités, de sorte que les résultats ne sont affichés que sur la base des jets qui répondent à nos paramètres ; puisque nous allions de toute façon relancer le dé jusqu'à ce que nous obtenions un résultat dans notre fourchette, cela est statistiquement identique au fait de relancer le dé (potentiellement pour toujours).

Nous avons donc deux fonctions, l'une qui rejette les résultats des scores d'aptitude individuels sauf s'ils sont égaux ou supérieurs à 8, l'autre qui rejette les tableaux de scores d'aptitude s'il n'y a pas deux scores égaux ou supérieurs à 15.

L'autre astuce est que cette dernière fonction prend également un index pour renvoyer l'un de ces scores de capacité, car malheureusement nous ne pouvons pas faire en sorte qu'anydice renvoie une séquence à partir d'une fonction, seulement un nombre plat, et nous devons donc utiliser l'index pour inspecter les jets individuels ; heureusement la séquence générée est automatiquement triée en ordre décroissant par défaut, donc nous pouvons simplement itérer à travers chaque position pour construire une distribution complète.

Cela nous donne un résultat qui ressemble à ceci lorsqu'il est représenté graphiquement :

Colville stat distribution graph from anydice

Cela semble être en parfait accord avec La réponse de Ryan Thompson basée sur R donc je suis sûr que je n'ai rien gâché dans son fonctionnement.

0 votes

Un problème possible est que, si j'ai bien compris, un seul jet de 8 ou moins élimine tout le tableau de statistiques et recommence au lieu de relancer un seul jet de statistiques. Cependant, d'après la similitude du graphique avec le mien, il semble que les deux procédures soient probablement mathématiquement équivalentes. Mais je ne suis pas encore sûr à 100%.

3 votes

@RyanThompson la meilleure façon d'y penser est que ce que la variable SCORE représente en fait un seul dé qui a les résultats possibles (et leurs probabilités) du relancement de 4d6-droplow jusqu'à ce que vous obteniez un huit ou mieux. Il n'y a pas de perte de tableaux entiers ; nous générons les tableaux en premier lieu en utilisant un dé spécial qui ne peut que générer des valeurs satisfaisantes pour les scores individuels.

1 votes

Ce d{} Le truc est vraiment bien. En fait, il semble que ce soit une meilleure solution pour cette question que j'ai posée plus tôt que le "reroll-in-a-loop" que j'ai inventé moi-même. Voulez-vous poster une réponse à ce sujet ? Je l'accepterais si vous le faisiez. (Sinon, je peux simplement l'éditer dans ma propre réponse).

9voto

Gambrinus Points 1738

Grâce à mes méthodes, j'ai trouvé 5 236 pools de dés différents et uniques qui résultent de la distribution des statistiques de Colville. Je l'ai posté aquí car la longueur du tableau viole la limite stricte de Stack Exchange concernant la longueur des messages. Vous pouvez l'examiner vous-même et lancer un traitement de données si vous souhaitez examiner certaines statistiques qui n'ont pas été fournies ici ou dans d'autres réponses.

Comment cela a-t-il été généré ?

Nous devons d'abord générer un tableau pour le jet de 4d6 drop 1. J'ai détaillé une méthode générale pour générer ce type de tableau. aquí et je vais utiliser le même processus ici, même si je fais un raccourci en passant les détails parce que je ne veux pas passer manuellement par tout le processus. Regardez ce post pour voir comment cela commence.

En bref, nous devons générer un tableau de 4d6 qui préserve également le dé qui était le plus bas pour chaque somme. Cela ressemblera à quelque chose comme ça :

4d6 Chute 1 (pré-chute)

Cotes

[4,1]

1

[5,1]

4

[6,1]

10

[7,1]

20

[8,1]

34

[9,1]

52

[10,1]

70

[11,1]

84

[12,1]

90

[13,1]

88

[14,1]

78

[15,1]

60

[16,1]

40

[17,1]

24

[18,1]

12

[19,1]

4

[8,2]

1

[9,2]

4

[10,2]

10

--Snip--

--Snip--

[23,5]

4

[24,6]

1

Et pour chacun d'entre eux, nous soustrayons le rouleau le plus bas, ce qui nous donne le rouleau final.

4d6 Chute 1

Cotes

[3]

1

[4]

4

[5]

10

[6]

21

[7]

38

[8]

62

[9]

91

[10]

122

[11]

148

[12]

167

[13]

172

[14]

160

[15]

131

[16]

94

[17]

54

[18]

21

Nous coupons simplement les résultats inférieurs à 8. Nous relançons toujours lorsque nous les rencontrons, de sorte que les chances des autres résultats ne sont pas affectées.

4d6 Drop 1 (8 seulement)

Cotes

[8]

62

[9]

91

[10]

122

[11]

148

[12]

167

[13]

172

[14]

160

[15]

131

[16]

94

[17]

54

[18]

21

Puis nous commençons à multiplier ce tableau contre lui-même. Ma méthode consiste à multiplexer ces chiffres, mais quelle que soit la façon dont vous le faites, vous obtiendrez quelque chose comme ceci (après avoir supprimé les ensembles qui ne contiennent pas au moins deux rouleaux 15) :

6x(4d6D18)

Cotes

[15, 15, 8, 8, 8, 8]

3803650531440

[16, 15, 8, 8, 8, 8]

5458674045120

[17, 15, 8, 8, 8, 8]

3135834025920

[18, 15, 8, 8, 8, 8]

1219491010080

[16, 16, 8, 8, 8, 8]

1958455573440

[17, 16, 8, 8, 8, 8]

2250140446080

[18, 16, 8, 8, 8, 8]

875054617920

... Vous voyez l'idée. Il y a 5236 rangées de ça.

Regardez le lien que j'ai posté ci-dessus pour le jeu complet

Voilà, enfin, toute la distribution des jets que l'on peut obtenir avec cette méthode de calcul des stats.

Que pouvons-nous en apprendre ?

Nous pourrions comparer la distribution totale des points de stats, par rapport à une distribution normale de 6x(4d6D1) stats :

Posted as an image because I was overloading Mathjax

Il s'avère donc que la méthode Colville donne un coup de pouce assez considérable à la somme globale, faisant passer la moyenne de 73,468 à 79,867. Ce n'est pas surprenant : toutes les données sur lesquelles elle agit (les résultats individuels inférieurs à 8, tout ensemble qui ne comporte pas au moins deux résultats de 15) sont des résultats spécifiquement mauvais, et elle tend donc naturellement vers des résultats plus élevés.

Si vous utilisez l'ensemble de données que j'ai posté ci-dessus, vous êtes invités à faire votre propre analyse. Je recommande lourd utilisation de Microsoft Excel ou d'un autre logiciel de tableur.

3voto

Ignorez l'ordre réel des choses, utilisez un ordre plus facile à calculer et n'ayez pas peur de faire des approximations.

Au lieu de lancer d'abord des stats et de relancer s'il n'y a pas deux 15+, nous pouvons obtenir exactement le même résultat en lançant d'abord deux stats qui doit être 15+ et ensuite lancer le reste "normalement".

Pour faire cela dans anydice, il faut prendre la collection des résultats possibles, ce que signifie 'le plus haut 3 sur 4d6', et enlever toutes les parties qui sont inférieures à 15.

La façon la plus simple de procéder est de le faire manuellement. En examinant les résultats de la distribution susmentionnée, nous constatons que '15' a 10,11 % de chances de se produire, '16' 7,25 %, '17' 4,17 % et '18' 1,62 %. Ces probabilités sont tronquées à la centième place, mais nous allons considérer ce niveau d'erreur comme acceptable. Une séquence comportant 1011 '15', 725 '16', 417 '17' et 162 '18' peut donc fonctionner comme un dé qui nous donne nos deux meilleures valeurs.

En utilisant la répétition, nous pouvons remplir une séquence en utilisant le code suivant :

output {15:1011,16:725,17:417,18:162}

Ensuite, nous devons corriger votre code. Il ne vous permet pas vraiment d'obtenir ce que vous cherchez, je pense, puisqu'il a une chance approximativement infinitésimale de produire des nombres inférieurs à 8. Cela peut vous convenir, mais nous pouvons également utiliser la troncature pour obtenir un système (à mon avis) beaucoup plus propre et à peu près aussi précis pour les 4 scores de capacité restants :

output {8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162}

Vous pouvez faire quelque chose comme output [highest 1 of 6d {8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162}] pour confirmer qu'il donne les mêmes résultats.

Pour examiner chaque score de capacité, il suffit de tirer le nombre approprié d'une série de jets, en se rappelant que les jets supérieurs à 8 au lieu de 15 ne sont pas non plus meilleurs que le troisième jet le plus élevé d'une telle séquence. Nous nous retrouvons donc avec :

output [highest 1 of 2d{15:1011,16:725,17:417,18:162}] named "highest stat"
output 2 @ 2d{15:1011,16:725,17:417,18:162} named "2nd highest stat"

output 3@6d{8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162} named "highest non-forced stat"
output 4@6d{8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162} named "2nd highest non-forced stat"
output 5@6d{8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162} named "2nd lowest stat"
output 6@6d{8:478,9:702,10:941,11:1142,12:1289,13:1327,14:1235,15:1011,16:725,17:417,18:162} named "lowest stat"

Ce qui donne résultats à moins d'un point de pourcentage de la valeur analytique 1 (erreur d'environ 10 %).


  1. grâce à @Carcer pour le programme de valeur analytique.

6 votes

Il convient de noter que cette approche est quelque peu dangereuse en général, et que les humains ont des intuitions terribles pour ce genre de choses. Considérez flip two coins, redo unless there is at least 1 head vs force the first coin to be a head, flip the second . Le premier a 2/3 de chance d'avoir 1 tête ( HH|HT|TH , baisse TT ), le second a 1/2 chance d'avoir 1 tête ( HH|HT ).

0 votes

@Cireo Il faut juste se souvenir des conséquences de ce que l'on fait, et ne pas utiliser une approximation qui n'est pas bonne pour votre modèle. De plus, votre exemple applique une approximation différente de celle utilisée ici - la partie de cette approximation qui consiste à lancer les 8 après les 15 reviendrait plutôt à lancer deux pièces de monnaie pour le deuxième contrôle et à n'ajouter une tête que si les deux se révèlent être des têtes (3/4 de chance d'une tête), mais le cas TT est aussi le genre de chose pour lequel la troncature est faite. L'étape précédente où l'on tronque les possibilités utilisées et où l'on passe à une échelle de 100% est précise à 100%, sauf erreur préexistante dans les chiffres.

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