3 votes

Pour anydice.com, y a-t-il un moyen de fixer un nombre total pour trois lancers ?

Je suis très, très nouveau dans l'écriture de code et la conception d'un RPG. Dans ce cadre, j'essaie de simuler le lancer de trois dés pondérés, allant de 1 à 12 où je fixe la limite de la somme possible des trois lancers. Autrement dit, je veux limiter la somme que peut donner n'importe quel ensemble de trois lancers à 12.

Je m'intéresse aux résultats réels des dés et pas seulement à leur somme, donc 3/3/3 est différent de 4/4/1.

Si la somme des dés dépasse 12, le dé responsable de ce dépassement sera relancé jusqu'à ce que ce ne soit plus le cas.

Par exemple :

  • Si vous avez obtenu 5/5 pour les deux premiers dés, le troisième dé sera relancé jusqu'à obtenir un 1 ou un 2.
  • Si vous avez obtenu 1/1 pour les deux premiers dés, le troisième dé sera relancé jusqu'à obtenir un nombre entre 1 et 10.

Les dés sont pondérés selon les pourcentages dont j'ai besoin. Je ne sais juste pas comment limiter la somme en langage de programmation.

Voici ce que j'ai jusqu'à présent :

W: {
 1:12,
 2:14,
 3:18,
 4:18,
 5:17,
 6:8,
 7:8,
 8:1,
 9:1,
 10:1,
 11:1,
 12:1
}
output dW

Toute aide serait grandement appréciée !

8voto

Ne pas utiliser de dés pour cela

Votre distribution de probabilités est inutilement compliquée. Il n'y a aucun moyen de rendre sa fonction claire via des dés pour le jeu de table - vous aurez besoin d'un ordinateur ou d'un jeu de cartes ou autre chose. Votre distribution de base semble être plus simplement mise en œuvre en faisant quelque chose comme lancer 2d3 et si les deux sont 3 alors vous obtenez un 4+d4 sauf si vous obtenez un 4 alors vous obtenez un 7+d5. Cela prend beaucoup de temps pour quelque chose qui pourrait essentiellement être juste lancer 2d3, les 3 explosent. Si le niveau de précision que vous visez est important, vous devriez déjà connaître la distribution de probabilité car la seule raison d'utiliser un système de génération de nombres aléatoires aussi compliqué, long et difficile à mettre en œuvre est précisément parce qu'il implémente au mieux un ensemble désiré de courbes de probabilité.

Puisque vous ne connaissez pas la distribution de probabilité, vous n'avez pas dû élaborer ce système dans un tel but. Utilisez un système de génération plus simple pour votre jeu. Si vous voulez le limiter à 12 et suivre une courbe similaire, utilisez 2d3 où chaque 3 peut exploser une fois exactement. Cela ressemble à ça. Ou, si le minimum de 3 est également important, lancez 3d2 avec chaque maximum explosant une fois au maximum.

3voto

trjh Points 11

Ce que vous pourriez chercher est le tour du dé vide pour rejeter les résultats "impossibles" (c'est-à-dire les résultats pour lesquels vous relancerez toujours jusqu'à ce qu'ils ne se produisent pas).

Par exemple, voici comment modéliser un mécanisme où vous lancez 3d12 et les relancez tous s'ils dépassent 12:

function: test ROLL:s si le total est MAX:n ou moins {
  SOMME: 0 + ROLL
  if SOMME > MAX { result: d{} } \ ignorer les lancés qui donnent un total supérieur à MAX! \

  \ faites maintenant quelque chose avec ROLL (et/ou SOMME) ici... \
  result: SOMME
}

output [test 3d12 si le total est de 12 ou moins]

La magie se produit à la ligne if SOMME > MAX { result: d{} }; si cette condition est vraie, la fonction s'arrête et renvoie le "dé vide" d{}, que AnyDice ignorera complètement lors de la collecte des résultats. Le résultat final est exactement comme si vous deviez relancer les lancés qui correspondent à la condition jusqu'à ce qu'ils ne le fassent plus.

Dans le reste de la fonction, vous pouvez alors calculer n'importe quel résultat que vous souhaitez en fonction de l'entrée ROLL et le renvoyer. Notez que la valeur de retour doit être un nombre (ou un dé); si on essayait de renvoyer une séquence (comme ROLL lui-même), AnyDice la sommerait automatiquement. Dans le programme d'exemple ci-dessus, je renvoie simplement la somme, mais une alternative possible (si vous souhaitiez examiner les valeurs des dés individuels) serait d'encoder la séquence ROLL en un nombre base-10 ou base-100, par exemple comme ceci:

  result: 10000 * 1@ROLL + 100 * 2@ROLL + 3@ROLL

(Voici une fonction d'aide plus générique pour cela si vous en voulez une.)

J'ai utilisé un dé d12 normal pour l'exemple ci-dessus, mais vous pourriez bien sûr également utiliser un dé biaisé personnalisé si vous le souhaitez. Et vous pourriez également implémenter quelque chose comme un mécanisme où vous "lancez un dé à la fois et relancez le dernier s'il dépasse 12", mais cela serait simplement plus compliqué et/ou fastidieux.

En gros, vous auriez besoin d'une série de fonctions qui s'appellent mutuellement ou d'une seule fonction qui s'appelle récursivement pour modéliser le lancer étape par étape, quelque chose comme ça:

function: test BASE:n plus ROLL:n plus N:n fois DIE:d max MAX:n {
  if BASE + ROLL + N > MAX { result: d{} }
  if N = 0 { result: BASE + ROLL }
  result: [test BASE + ROLL plus DIE plus N-1 fois DIE max MAX] 
}

output [test 0 plus d12 plus 2 fois d12 max 12]

Remarquez que, dans cet exemple, je relance le dé le plus récent si le lancer plus le total de base jusqu'à présent plus le nombre de dés restants à lancer dépasse le maximum. C'est parce que nous savons que les dés restants rouleront toujours au moins un chacun de toute façon. Ainsi, par exemple, si nous avons obtenu un 11 sur le premier d12 des trois lorsque le maximum était de 12, nous le relancerions car nous saurions que les deux lancers suivants devraient chacun augmenter le total d'au moins 1, le faisant atteindre au moins 11 + 1 + 1 = 13.

2voto

Cameron Booth Points 3037

Vous devrez peut-être ajouter une fonction définie par l'utilisateur.

function: minimum of X:n and Y:n {
  if X > Y {
    result: Y
  } else {
    result: X
  }
}

W: {
 1:12,
 2:14,
 3:18,
 4:18,
 5:17,
 6:8,
 7:8,
 8:1,
 9:1,
 10:1,
 11:1,
 12:1
}

output [minimum of 3dW and 12]

Lien AnyDice : https://anydice.com/program/1bd45

2voto

Someone_Evil Points 42173

Ne pas utiliser anydice pour cela

Une fois que vous vous lancez dans certains types de jets, en particulier ceux où vous pourriez (théoriquement) avoir des rerolls infinies et/ou où ce qu'il faut faire avec un jet dépend fortement d'autres jets, Anydice n'est pas adapté pour le travail. Les simulations Monte-Carlo seront l'outil le plus largement applicable pour résoudre les distributions de jets étranges comme celui-ci. Ce n'est pas trop compliqué non plus, tout ce que vous avez vraiment besoin de faire est de convertir votre algorithme en code. Les étapes de base :

  1. Créer une fonction qui peut faire un jet pour vous.

  2. Exécutez cette fonction \$N\$ fois, enregistrant les résultats.

  3. Analyser ce résultat comme s'il s'agissait de données expérimentales.

Dans ce cas, je l'ai fait en python (code ci-dessous), avec 100 000 jets et j'ai tracé la fréquence de chaque résultat pour chaque jet :

graphique de la distribution des dés

Ici, la série 1 est la distribution du premier dé qui est simplement la distribution du dé pondéré, la série 2 est le deuxième dé qui est principalement le même, et la série 3 est le troisième dé qui est souvent relancé et a une distribution assez biaisée.

Si vous le souhaitez, vous pouvez modifier la distribution ci-dessous pour mesurer combien de fois vous devriez relancer, etc.

import _random
import math

#Generate random integers
rnd = _random.Random()
def getrandint(m):
    return math.ceil(rnd.random()*m)

w = [1]*12+[2]*14+[3]*18+[4]*18+[5]*17+[6]*8+[7]*8+[8]*1+[9]*1+[10]*1+[11]*1+[12]*1

def rollW(): #Fait un jet de notre dé pondéré
    return w[getrandint(len(w))-1]

def AdairRoll(): #Chaque fonction génère un ensemble de jets pour nous
    roll = [rollW(), rollW(), rollW()] #un tableau pour nos jets, avec des jets initiaux

    if roll[0] == 12: #Si le premier jet est 12, le suivant doit être 0
        roll[1] = 0

    while roll[0]+roll[1] > 12: #Sinon, continuer à lancer le deuxième jusqu'à ce que la somme des deux premiers soit de 12 ou moins
        roll[1] = rollW()

    if roll[0]+roll[1] == 12: #Si les deux premiers sont = 12, le troisième doit être 0
        roll[2] = 0

    while roll[0]+roll[1]+roll[2] > 12: #sinon, continuer à lancer le troisième jusqu'à ce que la somme soit de 12 ou moins
        roll[2] = rollW()

    return roll

f = open('Adair/output.txt', 'a+')
for i in range(100000): #Lancer l'algorithme N fois, et écrire les résultats dans le fichier
    roll = AdairRoll()
    f.write('{}\t{}\t{}\n'.format(*roll))
f.close()

1voto

Dale M Points 183702

Oui

Comme ceci.

Le premier montre le total des dés comme un nombre de 2 à 12. Le deuxième divise chaque dé pour donner un résultat de XYZ où X est le dé le plus élevé, Y est le milieu et Z est le plus bas - la gamme du dé le plus bas dépend des valeurs des deux autres.

function: weighted A:s total{
  result: 1*1@A + 1*2@A + 1*[highest of 0 and [lowest of 3@A and 12-1@A-2@A]]
}

output [weighted 3d6 total] named "Total Results"

function: weighted A:s individual {
  result: 100*1@A + 10*2@A + 1*[highest of 0 and [lowest of 3@A and 12-1@A-2@A]]
}

output [weighted 3d6 individual] named "Sequence Results"

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