8 votes

Probabilité d'un jeu de dés avec des dés explosifs

Je suis en train de concevoir un jeu de table avec une mécanique de pool de dés pour la résolution des combats. Vous lancez des d6 et chaque dé qui obtient au moins 3 compte comme un SUCCÈS :

  • Si vous obtenez plus de 1 que de 6, c'est un échec.
  • Un ou deux SUCCÈS est une blessure légère.
  • Trois SUCCÈS en un seul jet est une blessure grave.
  • Six SUCCES est une blessure critique
  • Pour chaque 6 obtenu, vous obtenez un SUCCÈS. Ajoutez également un autre d6 à la réserve pour chaque 6 obtenu. Comptez chacun de ces dés comme un SUCCÈS. quel que soit le nombre de lancers . Chacun d'entre eux peut également exploser sur 6.

J'ai couvert tous les points sauf le dernier dans la fonction ci-dessous ( lien direct vers la fonction AnyDice ). Mais j'ai du mal avec la dernière partie, la mécanique des dés explosifs.

C'est un élément essentiel pour évaluer le système, car sans les dés explosifs, les chances de perdre le ballon augmentent et atteignent presque 1/3, ce qui est beaucoup trop élevé. L'explosion des dés limitera la probabilité des fausses notes. [edit : no, it won't]

Une idée sur la manière d'écrire cette fonction ?

FUMBLE: -1
MISS: 0
WOUND: 1
SEVERE: 2
CRITICAL: 3

function: evaluate ROLL:s {
 SUCCESSES: ROLL >= 3
 if [count 1 in ROLL] > [count 6 in ROLL] { result: FUMBLE }
 if SUCCESSES = 0 { result: MISS }
 if SUCCESSES = {1..2} { result: WOUND }
 if SUCCESSES = {3..5} { result: SEVERE }
 if SUCCESSES >= 6 { result: CRITICAL }
}

loop DICE over {1..6} {
 output [evaluate DICE d6] named "[DICE]d6"
}

2voto

Sofan Points 76

J'ai tenté de le faire en Python (je sais que ce n'est pas anydice. Peu importe). Il s'avère que, même si on exclut les explosés du calcul du fumble, les fumbles sont toujours beaucoup trop fréquents dans n'importe quel groupe de dés de taille raisonnable (mon groupe de test de 8d6 donnait toujours des fumbles environ la moitié du temps). Voici mon script Python qui exclut les explosés :

# This is exploding D6s.
# Basically, you start with a single roll with x dice.
# A result of 4 or higher is a success.
# A result of 3 or lesser is a failure.
# If a 6 is rolled, you roll another die. It will always be a success.
# If that die is a 6, you roll yet another, and so on. This is the "exploding" part.
# However, if more 1's are rolled than 6's, there's a FUMBLE.
# Exploded dice don't count towards 1's when rolled, but do count toward 6's.
# Let's... rationalize that.

import random

def explodeD6(x, xcount=0, explodes=0, explodecount=0, successes=0, ones=0): #x is the number of dice initially rolled.
  if xcount < x: #This means not all the dice in the initial pool have been rolled yet.
    roll = random.randint(1,6)
    if roll == 1:
      ones = ones + 1
    elif roll == 2 or roll == 3:
      successes = successes #Just demonstrating that nothing happens.
    elif roll == 4 or roll == 5:
      successes = successes + 1
    elif roll == 6:
      successes = successes + 1
      explodes = explodes + 1
    else: #Whoops! The randint wasn't between one and six. That's not right.
      print("Oops. Wrong die.")
    print(str(roll)) #Report.
    xcount = xcount + 1 #Indicate one more die has been rolled.
    explodeD6(x,xcount,explodes,explodecount,successes,ones) #And again.
  elif xcount == x: #This means all the initial dice have been rolled, but not necessarily the explosions.
    if explodecount < explodes: #This is an explosion roll. There are no failures, but it can explode again!.
      roll = random.randint(1,6)
      if roll == 1 or roll == 2 or roll == 3 or roll == 4 or roll == 5:
        explodes = explodes #Again, demonstrating nothing happens.
      elif roll == 6:
        explodes = explodes + 1
      else: #D'oh. randint still not working.
        print("Oops. Wrong die.")
      successes = successes + 1
      explodecount = explodecount + 1
      print(str(roll) + "(Explosion)") #Report.
      explodeD6(x,xcount,explodes,explodecount,successes,ones)
    elif explodecount == explodes: #All dice have been rolled and all manner of bonus dice shall have been rolled.
      totalRolls = x + explodes
      if ones > explodes: #Fumble.
        print("With %s ones, but only %s sixes, the result is a fumble, despite %s successes.") % (ones,explodes,successes)
        print("%s rolls total, from a starting pool of %sd6, due to %s explosions.") % (totalRolls,x,explodes)
      elif ones <= explodes:
        if successes > 0: #Success!
          print("There were %s ones, but %s sixes, allowing the %s successes to shine through.") % (ones,explodes,successes)
          print("%s rolls total, from a starting pool of %sd6, due to %s explosions.") % (totalRolls,x,explodes)
        elif successes == 0: #Miss.
          print("There were %s ones, but %s sixes, yet there were %s successes, resulting in a miss.") % (ones,explodes,successes)
          print("%s rolls total, from a starting pool of %sd6, due to %s explosions.") % (totalRolls,x,explodes)
        else: #Oops. Successes are negative.
          print("Something's wrong.")
    else:
      print("Something's wrong.")
  else:
    print("Something's wrong.")

#Holy shit. That's really long. Let's test it.

explodeD6(8)

Copiez-collez-le ici pour le voir en action.

1voto

user17995 Points 5132

Il y a un système intégré explode mais vous devez l'utiliser avant d'effectuer vos autres traitements. Plus précisément, utilisez FOOdBAR d'avoir BAR évaluées comme une séquence et utilisées pour générer FOO des "dés" avec un nombre de faces et des valeurs arbitraires. Ici, DICEd([explode d6]) fait le travail, en transformant un d6 éclaté en base pour le jet réel. ( explode ne sépare pas les dés que vous lui donnez - vous devez le faire, ou vous obtiendrez un jet de 5d6 qui n'explosera qu'une fois, sur 30).

Vous ne pouvez pas comparer des séquences à un seuil pour obtenir une liste ou une somme de valeurs par rapport à ce seuil - vous obtiendrez simplement la somme de la séquence et sa vérification par rapport au seuil. À la place, utilisez [count VALUES in SEQUENCE] pour chacune des valeurs valides (3-6). Et il s'avère que, puisque chaque 6 déclenche un nouveau dé et que tous ces dés comptent, il suffit de compter deux fois les 6 une fois éclatés. Donc, en réalité, cela devrait être [count {3..6, 6} in ROLL] .

Les résultats, du mieux que je peux, ne sont pas jolis. Chaque explosion donnera lieu soit à un fumble plus important (1), soit à une absence de progrès contre le fumble (2-5), soit à un équilibre et à une nouvelle chance de faire la même chose (6), et plus on commence avec de dés, plus les chances d'explosions sont grandes. Il n'est pas prévu que les tâtonnements se transforment en explosions, comme on pourrait l'attendre d'un grand succès ; la seule question est de savoir si la chaîne se termine par un 1 ou non.

0voto

117Halo Points 13

On dirait que j'avais tort et que j'ai appris quelque chose. Vous pouvez faire cela sur AnyDice :-) J'ai modifié ce code dans le premier lien dans les commentaires pour ajouter la logique pour diminuer les succès quand les 1 se produisent. Il semble qu'avec un jet de 3d6, vous obtiendrez un score de -1 ou moins dans ~8,5% des cas. 0 ~12%, 1 ~22% 2 ~22% et 3 ou plus ~35% du temps en fonction des résultats.

Pour clarifier ce que cela fait : Les fonctions en bas utilisent des 1 pour indiquer qu'elles devraient permettre cette chose (dés explosifs, relances, échecs de soustraction) et des 0 pour indiquer qu'elles ne devraient pas. Le seuil est le jet de dé (ou plus) qui compte comme un succès. Donc si c'est 3 alors 3-6 sont des succès. Je n'ai ajouté que la fonction bef, mais vous pouvez facilement modifier les fonctions pour changer le seuil, si elles explosent ou non, etc. La part du lion du crédit va à @Magician qui a répondu cette question . Donc pour votre question, vous pouvez simplement modifier la dernière ligne bef 3 part pour bef [#d6 à lancer initialement].

function: roll ROLL:n threshold T {
  if ROLL >=T {result: 1}
  result: 0
}

function: rollexploding ROLL:n threshold T{
  if ROLL =6 {result: 1+[rollexploding 1d6 threshold T]}
  result: [roll ROLL threshold T]
}

function: rerollfailures ROLL:n threshold T{
  if ROLL < T {result: [roll 1d6 threshold T]}
  result: [roll ROLL threshold T]
}

function: subtractfailureexplode ROLL:n threshold T{
  if ROLL =6 {result: 1+[subtractfailureexplode 1d6 threshold T]}
  if ROLL =1 {result: -1+[roll ROLL threshold T]}
  result: [roll ROLL threshold T]
}

function: rerollthenexplode ROLL: n threshold T {
  if ROLL < T {result: [rollexploding 1d6 threshold T]}
  result: [rollexploding ROLL threshold T]
}

function: wrapper DICE:n threshold T explode E reroll R fail F{
  RES:0
  loop N over {1..DICE} {
    if E & F {RES:RES+[subtractfailureexplode 1d6 threshold T]}
      else {if E & R {RES:RES+[rerollthenexplode 1d6 threshold T]}
        else {if E {RES:RES+[rollexploding 1d6 threshold T]}
          else {if R {RES:RES+[rerollfailures 1d6 threshold T]}
            else {RES:RES+[roll 1d6 threshold T]}
        }
      }
    }
  }
  result:RES
}

function: b DICE:n{
  result:[wrapper DICE threshold 4 explode 0 reroll 0 fail 0]
}

function: be DICE:n{
  result:[wrapper DICE threshold 4 explode 1 reroll 0 fail 0]
}

function: gr DICE:n{
  result:[wrapper DICE threshold 3 explode 0 reroll 1 fail 0]
}

function: bef DICE:n{
  result:[wrapper DICE threshold 3 explode 1 reroll 0 fail 1]
}

output [bef 3]

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