Défis de compétences D&D

14

Dans Dungeons & Dragons , presque tout est décidé en lançant un dé. En règle générale, si le résultat est supérieur ou égal à une valeur spécifiée, votre tentative de faire ce que vous vouliez faire réussit et échoue dans le cas contraire. Le plus souvent, un dé à 20 faces (alias d20) est utilisé pour lancer.

D'autres fois, le système de défi de compétence est utilisé. Il est similaire au système simple décrit ci-dessus, mais le succès est déterminé par le fait que le ou les joueurs réussissent des jets individuels un certain nombre de fois avant d'échouer un certain nombre de fois. Par exemple, le ou les joueurs peuvent essayer de choisir plusieurs serrures sur une porte avec un nombre limité de crochets. Les jets réussis individuels représentent la sélection réussie de l'un des verrous, et les jets échoués individuels représentent la rupture d'un crochet. Un succès global signifierait réussir à choisir toutes les serrures avant de casser toutes les crochets.

De plus, certains jets peuvent être des jets critiques. Sur un d20, lancer un 1 est un échec critique, entraînant l'échec immédiat de l'ensemble du défi (dans l'exemple ci-dessus, le ou les joueurs pourraient alerter accidentellement un garde). Rouler un 20 est un succès critique, résultant en la réussite immédiate de l'ensemble du défi (dans l'exemple ci-dessus, le ou les joueurs pourraient trouver un jeu de clés pour les serrures, supprimant la nécessité de les choisir). Dans le cas d'un jet critique, le défi est immédiatement terminé et le résultat est décidé, quel que soit le nombre de succès et d'échecs précédents.

Dans ce défi, vous aurez une difficulté, le nombre de succès nécessaires et le nombre d'échecs auxquels le défi a échoué. Vous devez simuler un joueur tentant le défi et produire le résultat.

Contribution

3 entiers, représentant la valeur qui doit être atteinte ou dépassée pour réussir un jet individuel, le nombre de succès nécessaires pour réussir le défi et le nombre d'échecs auxquels le défi a échoué. L'ordre et le format des entrées n'ont pas d'importance, tant que vous spécifiez l'ordre que vous utiliserez. La difficulté sera comprise entre 1 et 20 inclus et le nombre de succès et d'échecs sera compris entre 1 et 100 inclus.

Production

Les résultats de chacun des jets d20 (entiers, dans l'ordre), et le résultat global du défi (une valeur véridique / falsey). Le format n'a pas d'importance, tant que les résultats individuels sont en ordre, le résultat global vient avant ou après tous les rouleaux individuels (vous ne pouvez pas sortir le résultat global au milieu des rouleaux, par exemple), et vous spécifiez le format de sortie que vous utilisez et l'utilisez de manière cohérente.

Exemples (les valeurs entre parenthèses sont pour explication et ne doivent pas être incluses):

Contribution:

12 5 3 (difficulty successes failures)

Production:

15 (success, 1-0)
10 (failure, 1-1)
5  (failure, 1-2)
16 (success, 2-2)
12 (success, 3-2)
15 (success, 4-2)
19 (success, 5-2)
True (overall success)

Contribution:

15 2 3 (difficulty failures successes)

Production:

0  (overall failure)
15 (success, 1-0)
12 (failure, 1-1)
13 (failure, 1-2)

Contribution:

5 5 10 (successes failures difficulty)

Production:

11 (success, 1-0)
5  (failure, 1-1)
20 (critical success)
1  (overall success)

Contribution:

3 10 3 (failures difficulty successes)

Production:

12 (success, 1-0)
11 (success, 2-0)
1  (critical failure)
False (overall failure)

Règles

  • C'est le , donc le code le plus court en octets gagne
  • Vous devez choisir au hasard une valeur entière entre 1 et 20 (inclus) pour chaque lancer. Chaque valeur doit avoir une probabilité égale d'être choisie (ou aussi proche que possible de l'égalité).
Mego
la source
@ BradGilbertb2gills the number of successes and failures will both be between 1 and 100, inclusive.Donc, oui, il y a la possibilité qu'un seul échec entraîne l'échec de tout le défi.
Mego
Dois-je supposer que la vraie valeur représentant le succès global doit toujours être la même vraie valeur? Ou pourrait-il simplement être le nombre d'échecs restants?
Brad Gilbert b2gills
@ BradGilbertb2gills Il ne doit pas nécessairement avoir la même valeur réelle; J'utilise le nombre d'échecs restant dans ma réponse Python .
Mego
Ehh, je vais probablement le laisser comme renvoyant un Bool, car ce n'est qu'un octet, et cela aide à améliorer la lisibilité de la sortie.
Brad Gilbert b2gills
@ BradGilbertb2gills La lisibilité est beaucoup moins importante que le score.
Mego

Réponses:

3

JavaScript, 83 78 76 75 octets

F=(d,f,s)=>!s||f&&(r=~(Math.random()*20))+""+F(d,~r&&f-(k=d>-r),r+20&&s-!k)

Ce code décompte récursivement les succès et les échecs à mesure qu'ils se produisent. Lorsque les succès ( s) ou les échecs ( f) ont décompté jusqu'à 0, nous terminons avec la truevaleur !squand sest 0ou avec la valeur fausse de fquand fest 0.

La sortie est de la forme d'expression régulière /^(-\d{1,2})+(0|true)$/(ou, plus strictement, /^(-[1-9]|-1[0-9]|-20)+(0|true)$/). C'est-à-dire que l'entrée a un trait d'union, puis des valeurs de rouleau délimitées par des tirets, et enfin le résultat final ( 0ou true), qui n'est pas délimité du rouleau final. Cependant, c'est toujours une grammaire sans ambiguïté car le résultat utilmate et le rouleau final peuvent toujours être distingués: le dernier caractère de la sortie (soit 0ou e) est toujours indicatif du résultat, et une finale 0est toujours lue séparément du nombre (s) du rôle final.

Exemples de sorties pour F(11,3,4):

-3-14-12-16-16true  // normal success
-2-12-20true        // critical success
-20true             // first-roll critical success
-18-2-8-14-18-90    // normal failure
-18-12-10           // critical failure
-10                 // first-roll critical failure
-4-16-4-100         // normal failure where last roll is a 10

Explication:

Ce code fonctionne en roulant un d20 négatif et (ab) en utilisant les signes négatifs comme délimiteurs.

F=(d,f,s)=>    // define function F(difficulty, fails, successes)

!s||   // if zero more successes needed, return true
f &&   // if zero more failures needed, return 0

    (r=~(Math.random()*20)  // add negative d20 to output, store in `r`
    +""+                    // string concatenation
    F(                      // recursive call to F with changed fail/success
       d,                   //   pass along d      
       ~r                   //   if r is -1, zero more fails needed
          &&f-              //   otherwise, reduce fails needed by
              (k=d>-r),     //   the boolean `d>-r` (and store in k)
       r+20                 //   if r is -20, zero more successes needed
           &&s-!k           //   otherwise, reduce successes needed by
                            //   the opposite of `k` (which indicates a fail)
      )
   ]

Les expressions nombre-moins-booléennes fonctionnent car trueet falsesont transtypées vers 1et 0dans un contexte numérique. Dans ce cas, ce d>-rsera 1si le jet est un échec et 0si c'était un succès.

absides
la source
4

Python, 134 octets

Merci Pietu1998 pour les octets enregistrés

from random import*
def g(a,b,c):
 s,z=[],[c,b]
 while z[0]*z[1]:d=randint(1,20);z[a<d]-=[1,z[a<d]][d in[1,20]];s+=[d]
 return[z[0]]+s

Assez simple, on peut probablement jouer un peu plus au golf, mais nous avions besoin de quelque chose pour démarrer. Essayez-le en ligne .

Mego
la source
Vous pouvez enregistrer quelques octets: modifiez l'importation from random import*et supprimez random., utilisez randint(1,20)plutôt que randrange(20)+1, remplacez and par *. Vous êtes également autorisé à mettre le résultat final au début de la sortie, en économisant de l'espace.
PurkkaKoodari
3

Python 2, 123 121 octets

from random import*
def f(a,b,c):
 while c*b:
    r=randint(1,20);print r;c-=r<a;b-=r>=a
    if r in[1,20]:return r>9
 return c

(Cette réponse mélange les espaces et les tabulations , donc le premier niveau d'indentation est un seul espace, tandis que le second est un seul onglet.)

La fonction f prend les arguments suivants:

a, le seuil de réussite d'un jet de dé individuel,

b, le nombre de succès nécessaires au succès global,

c, le nombre d'échecs nécessaires pour l'échec global.

Sur chaque jet de dé soit bouc est décrémenté (mais pas les deux). Tant que les deux sont positifs, il boucle à nouveau, sauf en cas d'échec critique ou de succès critique.

En supposant qu'aucun succès ou échec critique, lorsque la boucle se termine bou csera nul, mais pas les deux. Dans ce cas, la fonction renvoie simplement la valeur actuelle dec , qui est zéro (Falsey) si nous avons épuisé tous nos échecs, et positive (Truthy) si nous avons réussi.

En bonus, la sortie vous indique le nombre d'échecs qu'il vous restait, ce qui est bien s'il y a (disons) plus de verrous à choisir plus tard. (À moins qu'il ne se termine par un échec ou un succès critique, auquel cas la sortie sera un booléen au lieu d'un int.)

mathmandan
la source
3

Pip , 39 octets

Quelqu'un a dit qu'il voulait voir une solution dans une langue de golf.

Wc&b{Pd:1+RR20d<a?--c--bc*:d>1b*:d<20}c

Je suis sûr que cela n'utilise pas de fonctionnalités de langage plus récentes que la question. Prend les entrées sous forme d'arguments de ligne de commande dans cet ordre: difficulté, succès requis, échecs requis. Sorties 0 pour l'échec global ou différent de zéro pour le succès global.Essayez-le en ligne!

L'approche est une stratégie tout en boucle assez simple, avec une ou deux astuces tirées d'autres solutions. Voici une version avec des commentaires, des espaces et des sorties supplémentaires:

; a,b,c are initialized to the cmdline args
; a = difficulty (roll >=a succeeds, roll <a fails)
; b = required successes to succeed the task
; c = required failures to fail the task
; d = single die roll

; Loop while c and b are both nonzero:
W c&b {
 ; d gets 1+randrange(20); output it
 O d:1+RR20
 ; If d<a, decrement req'd failures, else decrement req'd successes
 d<a ? --c --b
 ; Verbose output for the ungolfed version
 P " (" . (d=1|d=20 ? "critical " "") . (d<a ? "failure" "success") . ")"
 ; If d=1, req'd failures is * by 0 (becomes 0), else * by 1 (unchanged)
 c *: d>1
 ; If d=20, req'd successes is * by 0 (becomes 0), else * by 1 (unchanged)
 b *: d<20
}
; c, remaining failures, is the output: 0 if overall failure, nonzero if overall success
c . " (overall " . (c ? "success" "failure") . ")"
DLosc
la source
2

Ruby 2.2, 75 octets

f=->(v,s,f){p(r=rand(20)+1)<2?f=0:r>19?s=0:r<v ?f-=1:s-=1while s*f>0
p s<1}

Solution itérative de base. Exemple d'exécution:

f[12, 5, 3]

Peut produire:

11
17
8
14
7
false

Vous pouvez le voir fonctionner sur IDEONE ici .

Paul Prestidge
la source
Me rend vraiment jaloux des langues où 0 est falsey!
Paul Prestidge
1

VBA 180 octets

Sub P(d,s,f):k=1
Do While x<s And v<f:r=Int(20*Rnd()+1)
If r=20 Then x=s
If r=1 Then v=f
If r>=d Then: x=x+1: Else: v=v+1
Debug.Print r:Loop:If v>=f Then k=0
Debug.Print k:End Sub

Exemple de sortie

P 12,5,3
 18 
 2 
 19 
 8 
 11 
 0 

Le dernier chiffre de sortie sera un 0pour Falseou un 1pour True. Chaque rouleau est séparé par une nouvelle ligne. Cela utilise VBA construit en RNG rnd()qui est connu pour être pas si aléatoire , mais cela devrait répondre au mieux aux exigences.

Sub P(d,s,f)
k=1
Do While x<s And v<f               'Keep Rolling while Current Successes and Failures are less then the Maximum Allowed
r=Int(20*Rnd()+1)                'Creates a Randomish Number between 1 and 20
If r=20 Then x=s                   'Checks for Crit Success
If r=1 Then v=f                    'Checks for Crit Failure
If r>=d Then: x=x+1: Else: v=v+1   'Increments Current Success or Fails
Debug.Print r                      'Prints (Could us MSGBOX, it is shorter)
Loop
If v>=f Then k=0                   'Checks & Changes Total Outcome to False
Debug.Print k                      'Prints (Could us MSGBOX, it is shorter)
End Sub
JimmyJazzx
la source
1

SpecBAS - 165 octets

1 INPUT d,s,f
2 DIM p(2)
3 DO 
4 r=1+INT(RND*20): ?r
5 IF r IN [1,20] THEN EXIT 
6 INC p((r>=d)+1)
7 LOOP UNTIL p(1)>=f OR p(2)>=s
8  ?IIF$(r=1 OR p(1)>=f,"fail","success")

L'entrée doit être entrée dans l'ordre des difficultés, des succès et des échecs.

La nouvelle version de SpecBAS permet désormais "?" au lieu de PRINTet supprime le besoin deLET devant les affectations de variables, donc c'était une bonne façon de les essayer.

Comme les tableaux sont basés sur 1 par défaut, la ligne 6 renvoie 0/1 si le roulement bat en difficulté et ajoute 1 pour mettre à jour le bon index.

Brian
la source
1

Perl 6 ,  101   99 octets

->$/ {(1..20).roll(*).map({$1*$2||last;$2-=$0>$_;$2=0 when 1;$1-=$_>=$0;$1=0 when 20;$_}).eager,$2}
# 101 bytes
->$/ {
  (1..20).roll(*).map({  # roll an infinite sequence, and map over them
    $1*$2||last;         # stop if either counter is 0
    $2-=$0>$_;           # decrement failure counter when a failure
    $2=0 when 1;         # set failure counter to 0  when a critical failure
    $1-=$_>=$0;          # decrement success counter when a success
    $1=0 when 20;        # set success counter to 0  when a critical success
    $_                   # the rolled value
  }).eager,$2            # the value of failure counter
}

L'entrée est un tableau mutable contenant des difficultés, des succès, des échecs

La sortie est une liste à deux éléments, le premier élément est une liste des valeurs cumulées, le deuxième élément est le nombre d'échecs restants.

Usage:

# give it a name for ease of use
my &code = {...}

for ^10 { say code [12, 5, 3] }
((14 4 15 5 5) 0)
((17 4 16 12 3 8) 0)
((2 14 14 7 14 19 19) 1)
((3 12 13 15 10 1) 0)
((3 17 16 10 11) 0)
((18 11 18 4 6) 0)
((15 13 1) 0)
((13 15 8 2 8) 0)
((16 17 8 10 11) 0)
((9 20) 2)
Brad Gilbert b2gills
la source