Calcolatrice HP D&D 5e


11

Ho difficoltà a ricordare tutto ciò che devo fare quando faccio salire di livello un personaggio di D&D. Per qualsiasi motivo, una delle cose che mi dà problemi è capire quale dovrebbe essere il loro nuovo valore massimo di HP. Per questa sfida, dovrai scrivere un programma o una funzione per calcolare automaticamente il valore corretto.

Terminologia

La prima cosa che devi sapere per calcolare i PS massimi è il "modificatore di Costituzione". Ogni personaggio DND ha sei punteggi di abilità interi, incluso uno per Costituzione. L'unica conoscenza rilevante richiesta per questa sfida è come il punteggio di abilità della Costituzione influenza un'altra statistica, che è il modificatore della Costituzione. In breve, il modificatore è uguale a floor( (ability_score - 10) / 2 ). Gli avventurieri possono avere solo punteggi di abilità da 1 a 20, inclusi. Il tuo codice non dovrà mai gestire punteggi al di fuori di tale intervallo, il che significa anche che non dovrà mai gestire un modificatore inferiore a -5 o maggiore di +5. Sebbene il modificatore della Costituzione possa cambiare man mano che il personaggio sale di livello, i suoi effetti su HP sono applicati retroattivamente, quindi è necessario solo il suo valore corrente per calcolare i PS massimi attuali.

(Questo è del tutto irrilevante per la sfida, ma se sei curioso di sapere come influisce sui PS massimi: puoi supporre che l'impresa "Difficile" aggiunga 2 al modificatore di Costituzione di un personaggio ai fini del calcolo dei PS, dato che è effettivamente ciò che fa Questo non è il testo dell'impresa, ma la matematica è esattamente la stessa. Non devi gestire questa impresa nella tua risposta.)

Successivamente, ogni classe ha un tipo "hit die" assegnato, che è coinvolto nel calcolo di HP. La tabella seguente elenca i dadi colpiti per ogni 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

Infine, il livello del personaggio. Tutto ciò influisce su quante volte aggiungere un valore al totale parziale nella sezione seguente. Il livello di un personaggio è un numero intero compreso tra 1 e 20, incluso 1 . Il tuo codice non dovrà mai gestire un livello al di fuori di tale intervallo. Per raggiungere il livello n, un personaggio inizia al livello 1 e sale di livello n-1. Ad esempio, un personaggio di livello 3 è arrivato dove si trova essendo un personaggio di livello 1 e salendo di livello due volte.

Come calcolare HP massimi

I PS massimi di un personaggio sono pari ai loro PS di livello 1 più la somma dell'aumento che hanno ricevuto ad ogni livello.

Al livello 1

Al livello 1, i PS di un personaggio sono pari al tiro più alto possibile sul loro dado per colpire (il numero nel nome del dado, per quelli di voi che non hanno familiarità con i dadi che hanno più di 6 lati) più il loro modificatore di Costituzione. Ricorda che quando calcoli HP in un secondo momento, puoi supporre che la Costituzione di un personaggio sia sempre stata la stessa, poiché questa parte del calcolo viene ripetuta ogni volta che la Costituzione cambia.

Quando si sale di livello

Ogni volta che un personaggio sale di livello, hanno due opzioni. Possono tirare uno dei loro dadi o prendere il tiro medio di quel dado (arrotondato per eccesso). Qualunque cosa scelgano, il loro modificatore di Costituzione viene aggiunto al risultato. Questo totale è l'importo che i loro HP aumentano. Per questa sfida, il tiro medio è sempre preso, quindi l'output è deterministico. (Ancora una volta, se non si ha familiarità con> dadi a 6 facce, è possibile calcolare il tiro medio arrotondato per eccesso come (highest_possible_roll / 2) + 1.)

C'è un'eccezione notevole. I PS massimi di un personaggio aumentano sempre di almeno 1 ogni volta che salgono di livello 2 . Se le istruzioni nel paragrafo precedente comporterebbero un aumento di 0 o inferiore quando si passa di livello, aumenta invece di 1.

La sfida

Il tuo programma o funzione avrà tre input :

  • La classe del personaggio, come una stringa
  • Il livello del personaggio
  • Punteggio abilità Costituzione del personaggio ( non modificatore)

Sarà in uscita solo una cosa: la corrente del personaggio massima HP.

Esempi

Tutte le possibili combinazioni di ingressi e le relative uscite associate sono disponibili a questo link. Per avere qualcosa da guardare in questa pagina, ecco 30 casi di test scelti a caso:

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. A rigor di termini, non penso che ci sia una regola che dice che 20 è il livello massimo. Tuttavia, 21 è il punto in cui non ci sono più tabelle nel libro per dirti quali dovrebbero essere alcuni dei vari numeri delle regole, inclusa la quantità di esperienza che devi ottenere per raggiungerla. Questo è un livello abbastanza buono per me.

2. In realtà non penso che ciò sia vero con RAW. Ho chiesto su rpg.se e una cosa del genere non sembra essere scritta da nessuna parte. Tuttavia, Mike Mearls, lead designer di D&D, lo ha twittato a marzo 2015 . Questo non è autorevole nel modo in cui potresti sostenere un tweet dello sviluppatore di regole principali Jeremy Crawford, ma è la prova che è quello che intendevano, quindi lo userò per questa sfida.


La classe deve essere data come una stringa o può essere data come il numero del dado del colpo, dato che è l'unica informazione rilevante per una classe. Altrimenti le persone avranno solo bisogno di una tabella generica di "Se queste classi poi muoiono, se queste classi poi muoiono" ecc.
Skidsdev,

Inoltre il livello e la costituzione sono passati come numeri interi o come stringhe che dicono "xth level" e "y CON"?
Skidsdev,

1
Accidenti, sono vecchio, ricordo ancora questo tavolo: ancientscrossroads.com/adnd_tools/con_table.htm
Neil

@Mayube Probabilmente non avrei dovuto fare una domanda e andare subito a mangiare una pizza, eh? : P La classe deve essere una stringa, perché penso che ci siano abbastanza dati in quelle stringhe per trovare schemi per accorciare la tabella (che sembra essere il caso, in base alle risposte che sono arrivate finora). Livello e costituzione sono ints.
undergroundmonorail,

3
Ho trovato piuttosto difficile analizzare le informazioni rilevanti da tutte le informazioni che mi vengono lanciate.
Jonathan Allan,

Risposte:


2

Gelatina , 34 byte

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

Programma completo che accetta tre argomenti della riga di comando: classe, punteggio, livello.

Provalo online!

Come?

Il centro del codice, separato da ðs è un collegamento diadico che calcola il risultato da alcuni valori precedentemente calcolati:

+‘»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

Il modificatore viene calcolato sul lato destro:

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

La metà del valore della matrice viene calcolata sul lato sinistro:

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)

Considerando le somme ordinali dei nomi delle classi modulo mtali che msono minime, pur mantenendo le classificazioni (per die) dalle collisioni dei rendimenti m=15. Posizionare i valori richiesti (mezzo tiro di dado) in quegli indici in un elenco di lunghezza 15 consente la ricerca usando l'indicizzazione modulare di Jelly con . La compressione dell'elenco come numero di base 6 con il solitario 6sostituito da a 0è un byte più breve delle alternative di compressione base 7 o compressione base 4 e aumenta i valori (con l'overhead del byte associato all'utilizzo di un nilad extra nella catena) . La decompressione di base 6, anziché 7, si ottiene utilizzando il fatto che la decompressione di base (anziché la conversione di base b), ha una costruzione di intervallo implicita quando è l'argomento giusto,r, è un numero intero, il che significa che è come convertire in base re poi cambiarne 0uno rtutto in una volta.

Questo è:

         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

Riorganizzando l'elenco, convertendo il 6 all'indice 13 in zero e rendendolo minimo nella 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

Creare il codice

                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

8

JavaScript (ES6), 81 78 76 74 byte

Accetta input come (classe, livello, constitution_ability_score) . La classe non fa distinzione tra maiuscole e minuscole.

(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

Questo sta essenzialmente usando la stessa matematica della mia versione iniziale, ma d viene ora calcolato senza alcuna tabella di ricerca.

Casi test


Versione iniziale, 87 84 byte

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

Come funziona

La parte difficile è convertire la stringa di classe c nel dado corrispondente. Più precisamente, il valore che memorizzeremo è d = dice / 2 + 1 .

Usiamo la formula parseInt(c, 35) % 24 % 15che dà:

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

Inserendo i valori di d nelle posizioni corrispondenti in una stringa e riempiendo gli slot inutilizzati con zeri, otteniamo:

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

Da qui la formula finale:

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

Una volta che abbiamo d , calcoliamo:

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

che è il numero teorico di punti ottenuti ad ogni livello.

Se h è positivo, calcoliamo semplicemente:

h * l

In caso contrario, dobbiamo tenere conto del fatto che almeno 1 punto viene guadagnato ad ogni livello. Quindi calcoliamo invece:

h + l - 1

In entrambi i casi, regoliamo il risultato aggiungendo d - 2 , in modo che il numero iniziale di punti sia integrato correttamente.

Casi test


Qualcosa sembra essere sbagliato nel tuo codice; I bardi con un CON di 1 o i maghi con un CON di 2 o 3 ottengono lo stesso numero di punti ferita qualunque sia il loro livello.
Neil,

1
@Neil Grazie per averlo notato. Penso che questo sia risolto.
Arnauld,

3

Lotto, 172 byte

@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

Prende classe, livello e costituzione come argomenti della riga di comando. Spiegazione: L'HP può essere calcolato come (HP al livello 1) + (livello - 1) + min (ulteriori HP per livello, 0) * (livello - 1). I PV aggiuntivi per livello sono la metà del dado per colpire più il modificatore di costituzione. La maggior parte delle classi usa d8 quindi questo diventa uno meno della metà della costituzione ( %3/2-1), mentre gli HP al livello 1 sono 3 in più. Gli ulteriori HP per livello e HP al livello 1 vengono quindi adeguati per le sei classi che non usano d8. Gli ulteriori HP per livello sono quindi limitati a 0 (questo utilizza effettivamente il valore negativo poiché è leggermente più golfista in questo modo.)


2

R, 181 163 byte

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)}

Funzione anonima. Funziona come f(class, level, CON).

Spiegazione: Crea vettori per la classe sal massimo numero di dadi d, usando la terza e la quarta lettera nel nome della classe (la più piccola mappatura unica che ho trovato).

La mod CON mè direttamente dalla specifica e HP = primo livello (d + m ) + il resto dei livelli ( (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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.