Calculatrice D&D 5e HP

11

J'ai du mal à me souvenir de tout ce que je dois faire lors de la montée en niveau d'un personnage D&D. Pour une raison quelconque, l'une des choses qui me pose problème est de déterminer quelle devrait être leur nouvelle valeur maximale en HP. Pour ce défi, vous écrirez un programme ou une fonction pour calculer automatiquement la valeur correcte.

Terminologie

La première chose que vous devez savoir pour calculer les PV max est le "modificateur de Constitution". Chaque personnage du MDN a six scores de capacité entiers, dont un pour la Constitution. La seule connaissance pertinente requise pour ce défi est de savoir comment le score de capacité de Constitution affecte une autre statistique, qui est le modificateur de Constitution. En bref, le modificateur est égal à floor( (ability_score - 10) / 2 ). Les aventuriers ne peuvent avoir que des scores de capacité de 1 à 20 inclus. Votre code n'aura jamais à gérer des scores en dehors de cette plage, ce qui signifie également qu'il n'aura jamais à gérer un modificateur inférieur à -5 ou supérieur à +5. Bien que le modificateur de Constitution puisse changer à mesure qu'un personnage monte de niveau, ses effets sur les PV sont appliqués rétroactivement, donc seule sa valeur actuelle est nécessaire pour calculer les PV max actuels.

(Cela n'a rien à voir avec le défi, mais si vous êtes curieux de savoir comment cela affecte les HP maximum: vous pouvez supposer que l'exploit "Tough" ajoute 2 au modificateur de Constitution d'un personnage aux fins du calcul des HP, car c'est effectivement ce qu'il fait. . Ce n'est pas le texte de l'exploit, mais les calculs sont exactement les mêmes. Vous n'avez pas à gérer cet exploit dans votre réponse.)

Ensuite, chaque classe a un type de "hit die" assigné, qui est impliqué dans le calcul des HP. Le tableau suivant répertorie les dés de succès pour chaque classe.

Sorcerer:  d6
Wizard:    d6
Bard:      d8
Cleric:    d8
Druid:     d8
Monk:      d8
Rogue:     d8
Warlock:   d8
Fighter:   d10
Paladin:   d10
Ranger:    d10
Barbarian: d12

Enfin, le niveau du personnage. Tout cela affecte le nombre de fois où ajouter une valeur au total cumulé dans la section suivante. Le niveau d'un personnage est un entier de 1 à 20, inclus 1 . Votre code n'aura jamais à gérer un niveau en dehors de cette plage. Pour atteindre le niveau n, un personnage commence au niveau 1 et monte dans le n-1temps. Par exemple, un personnage de niveau 3 est arrivé là où il est en étant un personnage de niveau 1 et en montant deux fois.

Comment calculer Max HP

Les PV maximums d'un personnage sont égaux à ses PV au niveau 1 plus la somme de l'augmentation qu'il a reçue à chaque niveau.

Au niveau 1

Au niveau 1, les PV d'un personnage sont égaux au plus haut jet possible sur son dé touché (le nombre au nom du dé, pour ceux d'entre vous qui ne connaissent pas les dés qui ont plus de 6 faces) plus leur modificateur de Constitution. N'oubliez pas que lorsque vous calculez des HP à un niveau ultérieur, vous pouvez supposer que la Constitution d'un personnage a toujours été la même, car cette partie du calcul est refaite chaque fois que la Constitution change.

Lors de la mise à niveau

Chaque fois qu'un personnage monte de niveau, il a deux options. Ils peuvent soit lancer l'un de leurs dés, soit prendre le jet moyen de ce dé (arrondi). Quel que soit leur choix, leur modificateur de Constitution est ajouté au résultat. Ce total est le montant que leur HP augmente. Pour ce défi, le roulement moyen est toujours pris, donc la sortie est déterministe. (Encore une fois, si vous n'êtes pas familier avec les dés> 6 faces, vous pouvez calculer le jet moyen arrondi comme (highest_possible_roll / 2) + 1.)

Il y a une exception notable. Les PV maximums d'un personnage augmentent toujours d'au moins 1 à chaque fois qu'il monte de niveau 2 . Si les instructions du paragraphe ci-dessus entraînent une augmentation de 0 ou moins lors de la montée de niveau, elle augmente de 1 à la place.

Le défi

Votre programme ou fonction prendra trois entrées :

  • La classe du personnage, sous forme de chaîne
  • Le niveau du personnage
  • Score de capacité de constitution du personnage ( pas de modificateur)

Il sera sortie qu'une seule chose: HP maximale actuelle du personnage.

Exemples

Toutes les combinaisons possibles d'entrées et de leurs sorties associées sont disponibles sur ce lien. Pour avoir quelque chose à regarder sur cette page, voici 30 cas de test choisis au hasard:

Barbarian, 15th level, 13 CON: 125
    Rogue, 10th level, 18 CON: 93
   Wizard, 15th level, 18 CON: 122
   Wizard, 16th level,  1 CON: 16
Barbarian, 15th level,  7 CON: 80
  Warlock, 15th level,  3 CON: 18
   Ranger, 14th level,  1 CON: 18
  Warlock,  3rd level, 14 CON: 24
    Druid,  3rd level,  4 CON: 9
   Cleric, 11th level,  5 CON: 25
     Bard, 20th level, 11 CON: 103
Barbarian, 11th level, 13 CON: 93
     Bard,  8th level, 19 CON: 75
     Bard, 16th level, 17 CON: 131
  Fighter, 10th level,  6 CON: 44
     Monk, 10th level,  2 CON: 13
   Cleric, 14th level, 17 CON: 115
   Cleric,  6th level,  5 CON: 15
    Rogue,  7th level, 13 CON: 45
   Cleric,  4th level, 14 CON: 31
    Rogue, 19th level, 15 CON: 136
  Paladin, 13th level, 13 CON: 95
   Cleric, 13th level, 15 CON: 94
     Bard,  8th level,  5 CON: 19
     Monk, 20th level, 11 CON: 103
Barbarian,  8th level, 20 CON: 101
     Monk,  1st level,  4 CON: 5
     Bard,  5th level, 17 CON: 43
     Monk, 18th level,  7 CON: 57
   Wizard, 17th level,  5 CON: 19

1. À strictement parler, je ne pense pas qu'il existe une règle qui dit que 20 est le niveau maximum. Cependant, 21 est le point où il n'y a plus de tableaux dans le livre pour vous dire quels devraient être les différents nombres dans les règles, y compris la quantité d'expérience dont vous avez besoin pour l'atteindre. C'est un niveau suffisant pour moi.

2. En fait, je ne pense pas que ce soit vrai avec RAW. J'ai demandé sur rpg.se et une telle chose ne semble être écrite nulle part. Cependant, Mike Mearls, concepteur principal de D&D, l'a tweeté en mars 2015 . Ce n'est pas la manière dont vous pourriez faire valoir un tweet du développeur principal des règles, Jeremy Crawford, mais c'est la preuve que c'est ce qu'ils voulaient, donc je vais l'utiliser pour ce défi.

métro monorail
la source
La classe doit-elle être donnée sous forme de chaîne, ou peut-elle être indiquée sous la forme du numéro du dé, étant donné que c'est la seule information pertinente pour une classe. Sinon, les gens n'auront besoin que d'un tableau générique de "Si ces classes, alors cette mort, si ces classes, alors cette mort", etc.
Skidsdev
Le niveau et la constitution sont-ils également transmis sous forme d'entiers, ou sous forme de chaînes indiquant "xième niveau" et "y CON"?
Skidsdev
1
Mon Dieu, je suis vieux, je me souviens encore de cette table: ancientscrossroads.com/adnd_tools/con_table.htm
Neil
@Mayube n'aurait probablement pas dû poser de question et immédiatement sortir pour une pizza, hein? : P La classe doit être une chaîne, car je pense qu'il y a suffisamment de données dans ces chaînes pour trouver des modèles pour raccourcir le tableau (ce qui semble être le cas, sur la base des réponses reçues jusqu'à présent). Le niveau et la constitution sont ints.
métro
3
J'ai trouvé assez difficile d'analyser les informations pertinentes de toutes les informations qui me sont lancées.
Jonathan Allan

Réponses:

2

Gelée , 34 octets

OSị“#®Ʋ?[’ṃ6¤ð+‘»1×⁵’¤+⁸Ḥ¤+ð⁹_10:2

Programme complet prenant trois arguments de ligne de commande: classe, score, niveau.

Essayez-le en ligne!

Comment?

Le milieu du code, séparé par ðs, est un lien dyadique qui calcule le résultat à partir de certaines valeurs précédemment calculées:

+‘»1×⁵’¤+⁸Ḥ¤+ - maxHitPoints(halfDieValue, modifier)
+             - add: halfDieValue + modifier
 ‘            - increment
  »1          - maximum of that and 1: this is the level-up delta
       ¤      - nilad followed by links as a nilad:
     ⁵        -   program's 3rd argument, level (5th command line argument)
      ’       -   decrement: this is the number of level-ups
    ×         - multiply: level-ups * level-up delta
           ¤  - nilad followed by links as a nilad:
         ⁸    -   link's left argument: halfDieValue
          Ḥ   -   double: dieValue
        +     - add: level-ups * level-up delta + dieValue
            + - add: level-ups * level-up delta + dieValue + modifier

Le modificateur est calculé à droite:

⁹_10:2 - getModifier(class, score)
⁹      - link's right argument, the 2nd argument, the score
 _10   - minus 10
    :2 - integer divide by 2

La moitié de la valeur du dé est calculée à gauche:

OSị“#®Ʋ?[’ṃ6¤ - getHalfDieValue(class)
O             - cast to ordinals
 S            - sum
            ¤ - nilad followed by link(s) as a nilad:
   “#®Ʋ?[’    -   base 250 literal 140775266092
          ṃ6  -   convert to base 6 but with 6s in place of 0s
  ị           - index into (1-indexed and modular)

En considérant les sommes ordinales des noms de classe modulo mtelles qu'elles msoient minimales tout en empêchant les classifications (par dé) de se heurter aux rendements m=15. Placer les valeurs requises (demi-jet de dé) à ces index dans une liste de longueur 15 permet une recherche à l'aide de l'indexation modulaire de Jelly avec . La compression de la liste en tant que nombre de base 6 avec le seul 6remplacé par un 0est un octet plus court que les alternatives de compression de base 7 ou de compression de base 4 et augmente les valeurs (avec la surcharge d'octets associée à l'utilisation d'un nilad supplémentaire dans la chaîne) . La décompression de base 6, plutôt que 7, est obtenue en utilisant le fait que la décompression de base (plutôt que la conversion de base b) a une construction de plage implicite quand c'est le bon argument,r, est un entier, ce qui signifie que c'est comme convertir en base r, puis changer tout 0en un rtout d'un coup.

C'est:

         class: Sorcerer,Wizard,Bard,Cleric,Druid,Monk,Rogue,Warlock,Fighter,Paladin,Ranger,Barbarian
   Ordinal sum: 837,     625,   377, 594,   504,  405, 514,  723,    713,    697,    607,   898
        mod 15:  12,      10,     2,   9,     9,    0,   4,    3,      8,      7,      7,    13
required value:   3,       3,     4,   4,     4,    4,   4,    4,      5,      5,      5,     6

Réorganisation de la liste, conversion du 6 à l'index 13 en zéro et minimisation en base 6:

mod 15:    2   3   4           7   8   9  10      12  13      0  
 value: 1, 4,  4,  4,  0,  0,  5,  5,  4,  3,  0,  3,  0,  0,  4

Faire le code

                list: [1,4,4,4,0,0,5,5,4,3,0,3,0,0,4]
         from base 6: 140775266092
         to base 250: [36,9,154,64,92]
code page characters:   # ®   Ʋ  ?  [
          final code: “#®Ʋ?[’ṃ6
Jonathan Allan
la source
8

JavaScript (ES6), 81 78 76 74 octets

Prend l'entrée en tant que (classe, niveau, constitution_ability_score) . La classe est insensible à la casse.

(c,l,s,h=(d=parseInt(c,34)*59.9%97%77%6|4)+(s-10>>1))=>(h>0?h*l:h+l-1)+d-2

Cela utilise essentiellement les mêmes calculs que ma version initiale, mais d est maintenant calculé sans aucune table de recherche.

Cas de test


Version initiale, 87 84 octets

(c,l,s,h=(d=+'55654607554506'[parseInt(c,35)%24%15])+(s-10>>1))=>(h>0?h*l:h+l-1)+d-2

Comment ça fonctionne

La partie délicate consiste à convertir la chaîne de classe c en dés correspondants. Plus précisément, la valeur que nous allons stocker est d = dés / 2 + 1 .

Nous utilisons la formule parseInt(c, 35) % 24 % 15qui donne:

Class       | Base 35 -> decimal | MOD 24 | MOD 15 | d
------------+--------------------+--------+--------+---
"Sorcerer"  |      1847055419467 |     19 |      4 | 4
"Wizard"    |               1138 |     10 |     10 | 4
"Bard"      |             484833 |      9 |      9 | 5
"Cleric"    |          662409592 |     16 |      1 | 5
"Druid"     |           20703143 |     23 |      8 | 5
"Monk"      |             973475 |     11 |     11 | 5
"Rogue"     |           41566539 |      3 |      3 | 5
"Warlock"   |        59391165840 |      0 |      0 | 5
"Fighter"   |        28544153042 |      2 |      2 | 6
"Paladin"   |        46513817828 |     20 |      5 | 6
"Ranger"    |         1434103117 |     13 |     13 | 6
"Barbarian" |     25464249364423 |      7 |      7 | 7

En insérant les valeurs de d aux positions correspondantes dans une chaîne et en remplissant les emplacements inutilisés avec des zéros, nous obtenons:

00000000001111
01234567890123
--------------
55654607554506

D'où la formule finale:

d = +'55654607554506'[parseInt(c, 35) % 24 % 15]

Une fois que nous avons d , nous calculons:

h = d + ((s - 10) >> 1))

qui est le nombre théorique de points gagnés à chaque niveau.

Si h est positif, nous calculons simplement:

h * l

Sinon, nous devons prendre en compte le fait qu'au moins 1 point est gagné à chaque niveau. Nous calculons donc à la place:

h + l - 1

Dans les deux cas, nous ajustons le résultat en ajoutant d - 2 , afin que le nombre initial de points soit correctement intégré.

Cas de test

Arnauld
la source
Quelque chose semble mal avec votre code; Les bardes avec un CON de 1 ou les magiciens avec un CON de 2 ou 3 obtiennent le même nombre de points de vie quel que soit leur niveau.
Neil
1
@Neil Merci d'avoir remarqué. Je pense que c'est corrigé.
Arnauld
3

Lot, 172 octets

@set/aa=1-%3/2,h=4-a
@for %%c in (-1.Sorcerer -1.Wizard 1.Fighter 1.Paladin 1.Ranger 2.Barbarian)do @if %%~xc==.%1 set/aa-=c=%%~nc,h+=c*2
@cmd/cset/a"a*=(a>>9),-~a*~-%2+h

Prend la classe, le niveau et la constitution comme arguments de ligne de commande. Explication: Les HP peuvent être calculés comme (HP au niveau 1) + (niveau - 1) + min (HP supplémentaire par niveau, 0) * (niveau - 1). Les PV supplémentaires par niveau représentent la moitié du dé touché plus le modificateur de constitution. La plupart des classes utilisent d8, ce qui représente un moins de la moitié de la constitution ( %3/2-1), tandis que les HP au niveau 1 sont 3 de plus que cela. Les HP supplémentaires par niveau et HP au niveau 1 sont ensuite ajustés pour les six classes qui n'utilisent pas d8. Les HP supplémentaires par niveau sont alors limités à 0 (cela utilise en fait la valeur négative car il est légèrement plus golfique de cette façon.)

Neil
la source
2

R, 181 163 octets

function(s,n,t){a=Hmisc::Cs(rc,za,rd,er,ui,mk,gu,rl,gh,la,ng,rb)
b=c(6,6,rep(8,6),rep(10,3),12)
d=b[a == substr(s,3,4)]
m=floor((t-10)/2)
d+m+(n-1)*max(d/2+1+m,1)}

Fonction anonyme. Fonctionne comme f(class, level, CON).

Explication: crée des vecteurs pour la classe sau maximum de dés d, en utilisant les 3e et 4e lettres du nom de la classe (la plus petite correspondance unique que j'ai trouvée).

Le mod CON mest directement issu de la spécification, et HP = premier niveau ( d + m) + le reste des niveaux ( (n-1) * max(average_die + m, 1).

> f("Barbarian", 15, 13)
[1] 125
> f("Rogue", 10, 18)
[1] 93
> f("Wizard", 15, 18)
[1] 122
> f("Wizard", 16, 1)
[1] 16
> f("Barbarian", 15, 7)
[1] 80
> f("Warlock", 15, 3)
[1] 18
> f("Ranger", 14, 1)
[1] 18
BLT
la source