Kalkulator HP D&D 5e

11

Mam problem z zapamiętaniem wszystkiego, co muszę zrobić, aby awansować na postać D&D. Z jakiegokolwiek powodu jedną z rzeczy, które przysparzają mi kłopotów, jest ustalenie ich nowej maksymalnej wartości HP. Do tego wyzwania napiszesz program lub funkcję do automatycznego obliczania poprawnej wartości.

Terminologia

Pierwszą rzeczą, którą musisz wiedzieć, aby obliczyć maksymalne HP, jest „modyfikator Konstytucji”. Każda postać DND ma sześć całkowitych wyników umiejętności, w tym jeden za Konstytucję. Jedyną istotną wiedzą wymaganą do tego wyzwania jest to, jak wynik umiejętności Konstytucji wpływa na inną statystykę, która jest modyfikatorem Konstytucji. Krótko mówiąc, modyfikator jest równy floor( (ability_score - 10) / 2 ). Poszukiwacze przygód mogą mieć wyniki od 1 do 20 włącznie. Twój kod nigdy nie będzie musiał obsługiwać wyników poza tym zakresem, co oznacza również, że nigdy nie będzie musiał obsługiwać modyfikatora niższego niż -5 lub większego niż +5. Chociaż modyfikator Konstytucji może się zmieniać wraz ze wzrostem poziomu postaci, jego wpływ na HP jest stosowany z mocą wsteczną, więc tylko jego aktualna wartość jest potrzebna do obliczenia aktualnego maksymalnego HP.

(To jest zupełnie bez znaczenia na to wyzwanie, ale jeśli jesteś ciekaw, jak to wpływa na maksymalną HP: Można założyć, że „Tough” feat dodaje 2 do modyfikatora charakter konstytucji dla celów obliczania HP, ponieważ to skutecznie , co robi To nie jest tekst wyczynu, ale matematyka okazuje się być dokładnie taka sama. Nie musisz radzić sobie z tym wyczynem w swojej odpowiedzi.)

Następnie każda klasa ma przypisany typ „trafienia”, który bierze udział w obliczaniu HP. W poniższej tabeli wymieniono kości trafień dla każdej klasy.

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

Wreszcie poziom postaci. Wszystko to wpływa na to, ile razy należy dodać wartość do bieżącej sumy w poniższej sekcji. Poziom postaci to liczba całkowita od 1 do 20, w tym 1 . Twój kod nigdy nie będzie musiał obsługiwać poziomu spoza tego zakresu. Aby osiągnąć poziom n, postać zaczyna od poziomu 1 i podnosi n-1czasy. Na przykład postać poziomu 3 dotarła do miejsca, w którym się znajduje, będąc postacią poziomu 1 i dwukrotnie podnosząc poziom.

Jak obliczyć maksymalne HP

Maksymalne HP postaci jest równe jej HP na poziomie 1 plus suma wzrostu, jaki otrzymali na każdym poziomie.

Na poziomie 1

Na poziomie 1 HP postaci jest równe najwyższemu możliwemu rzutowi na jej kości trafienia (liczba w nazwie kości, dla tych z was, którzy nie znają kości, które mają więcej niż 6 stron) plus ich modyfikator Konstytucji. Pamiętaj, że obliczając HP na późniejszym poziomie, możesz założyć, że Konstytucja postaci zawsze była taka sama, ponieważ ta część obliczeń jest powtarzana za każdym razem, gdy zmienia się Konstytucja.

Podczas awansowania

Za każdym razem, gdy postać awansuje, mają dwie opcje. Mogą albo rzucić jedną ze swoich trafionych kości, albo wziąć średni wynik tej kości (zaokrąglony w górę). Cokolwiek wybiorą, ich modyfikator Konstytucji zostanie dodany do wyniku. Ta suma to kwota, którą zwiększa ich HP. W przypadku tego wyzwania zawsze wybierany jest średni rzut, więc wynik jest deterministyczny. (Ponownie, jeśli nie jesteś zaznajomiony z> 6-stronnymi kostkami, możesz obliczyć zaokrąglony średni rzut jako (highest_possible_roll / 2) + 1.)

Jest jeden znaczący wyjątek. Maksymalne HP postaci zawsze wzrasta o co najmniej 1 za każdym razem, gdy awansuje o 2 . Jeśli instrukcje w powyższym akapicie spowodowałyby wzrost o 0 lub mniej podczas podwyższania, zamiast tego wzrosłyby o 1.

Wyzwanie

Twój program lub funkcja przyjmie trzy dane wejściowe :

  • Klasa postaci jako ciąg
  • Poziom postaci
  • Wynik zdolności Konstytucji postaci ( bez modyfikatora)

Będzie wyjście tylko jedno: postać za prąd maksymalny HP.

Przykłady

Każda możliwa kombinacja wejść i powiązanych z nimi wyjść można znaleźć pod tym linkiem. Aby mieć na co spojrzeć na tej stronie, tutaj losowo wybieranych jest 30 przypadków testowych:

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. Ściśle mówiąc, nie sądzę, żeby istniała reguła, która mówi, że 20 to maksymalny poziom. Jednak 21 jest punktem, w którym przestają być tabele w książce, które mówią ci, jakie powinny być różne liczby w regułach, w tym ilość doświadczenia, które musisz zdobyć, aby je osiągnąć. To dla mnie wystarczający limit poziomu.

2. Właściwie nie sądzę, że tak jest w przypadku RAW. Zapytałem na rpg.se i nic takiego nie wydaje się być nigdzie zapisane. Jednak Mike Mearls, główny projektant D&D, napisał na Twitterze w marcu 2015 r . Nie jest to autorytatywny sposób, w jaki można argumentować tweeta od twórcy reguł wiodących, Jeremy'ego Crawforda, ale jest to dowód na to, że tak zamierzali, więc wykorzystam go do tego wyzwania.

podziemny monorail
źródło
Czy klasa musi być podana jako ciąg, czy może być podana jako liczba kości trafienia, pod warunkiem, że jest to jedyna istotna informacja dla klasy. W przeciwnym razie ludzie będą potrzebować tylko ogólnej tabeli „Jeśli te klasy to umrą, jeśli te klasy to umrą” itp.
Skidsdev
Czy poziom i konstytucja są również przekazywane jako liczby całkowite, czy jako ciągi znaków z napisem „xth level” i „y CON”?
Skidsdev
1
Rany, jestem stary, wciąż pamiętam ten stół: ancientscrossroads.com/adnd_tools/con_table.htm
Neil
@Mayube Prawdopodobnie nie powinienem był zadawać pytań i natychmiast wyszedł na pizzę, co? : P Klasa musi być ciągiem, ponieważ myślę, że w tych ciągach jest wystarczająca ilość danych, aby znaleźć wzorce, aby skrócić tabelę (co wydaje się, że tak jest, w oparciu o dotychczasowe odpowiedzi). Poziom i konstytucja to ints.
metro
3
Trudno mi było oddzielić odpowiednie informacje od wszystkich rzuconych na mnie informacji.
Jonathan Allan

Odpowiedzi:

2

Galaretka , 34 bajty

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

Pełny program z trzema argumentami wiersza poleceń: klasa, wynik, poziom.

Wypróbuj online!

W jaki sposób?

Środek kodu, oddzielony ðs, to diademiczne łącze, które oblicza wynik na podstawie niektórych wcześniej obliczonych wartości:

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

Modyfikator jest obliczany po prawej stronie:

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

Połowę wartości matrycy oblicza się po lewej stronie:

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)

Biorąc pod uwagę sumy porządkowe nazw klas modulo, mtakie jakm są minimalne, przy jednoczesnym utrzymywaniu klasyfikacji (według matrycy) przed kolidującymi wydajnościami m=15. Umieszczenie wymaganych wartości (rzut pół-matrycą) przy tych indeksach na liście o długości 15 pozwala na wyszukiwanie przy użyciu modułowego indeksowania Jelly za pomocą . Kompresowanie listy jako liczby podstawowej 6 z pojedynczym 6zastąpionym przez a 0jest bajtem krótszym niż alternatywy kompresji base-7 lub kompresji base-4 i zwiększenie wartości (z narzutem związanym z użyciem dodatkowej wartości nilad w łańcuchu) . Dekompresję podstawy 6 zamiast 7 uzyskuje się, wykorzystując fakt, że dekompresja bazy (zamiast konwersji bazowej b) ma domyślną konstrukcję zakresu, gdy jest to właściwy argument,r, jest liczbą całkowitą, co oznacza, że ​​jest jak konwersja do bazy, ra następnie zamiana dowolnej wartości 0na „ rwszystko za jednym razem”.

To jest:

         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

Zmiana kolejności na liście, konwersja wartości 6 przy indeksie 13 na zero i minimalizacja w bazie 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

Tworzenie kodu

                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
źródło
8

JavaScript (ES6), 81 78 76 74 bajtów

Pobiera dane wejściowe jako (klasa, poziom, Constitution_ability_score) . Klasa nie rozróżnia wielkości liter.

(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

Zasadniczo używa się tej samej matematyki, co moja początkowa wersja, ale d jest teraz obliczane bez żadnej tabeli odnośników.

Przypadki testowe


Pierwsza wersja, 87 84 bajtów

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

Jak to działa

Trudną częścią jest konwersja ciągu klasy c na odpowiednie kości trafienia. Dokładniej, wartość, którą będziemy przechowywać, to d = kości / 2 + 1 .

Używamy formuły, parseInt(c, 35) % 24 % 15która daje:

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

Wstawiając wartości d w odpowiednich pozycjach do łańcucha i dopełniając nieużywane miejsca zerami, otrzymujemy:

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

Stąd ostateczna formuła:

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

Kiedy mamy d , obliczamy:

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

czyli teoretyczna liczba punktów zdobytych na każdym poziomie.

Jeśli h jest dodatnie, po prostu obliczamy:

h * l

Jeśli nie, musimy wziąć pod uwagę fakt, że na każdym poziomie zdobywa się co najmniej 1 punkt. Zamiast tego obliczamy:

h + l - 1

W obu przypadkach korygujemy wynik, dodając d - 2 , tak aby początkowa liczba punktów była poprawnie zintegrowana.

Przypadki testowe

Arnauld
źródło
Wydaje się, że coś jest nie tak z twoim kodem; Bardowie z CON 1 lub Wizards z CON 2 lub 3 otrzymują taką samą liczbę punktów wytrzymałości niezależnie od ich poziomu.
Neil
1
@Neil Dzięki za zauważenie. Myślę, że to naprawiono.
Arnauld
3

Partia, 172 bajty

@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

Bierze klasę, poziom i konstytucję jako argumenty wiersza poleceń. Objaśnienie: HP można obliczyć jako (HP na poziomie 1) + (poziom - 1) + min (kolejne HP na poziom, 0) * (poziom - 1). Dalsze HP na poziom to połowa trafionej kości plus modyfikator konstytucji. Większość klas używa d8, więc staje się to o mniej niż połowa konstytucji ( %3/2-1), podczas gdy HP na poziomie 1 wynosi 3 więcej. Dalsze HP na poziom i HP na poziomie 1 są następnie korygowane dla sześciu klas, które nie używają d8. Dalsze HP na poziom jest następnie ograniczone do 0 (w rzeczywistości wykorzystuje to wartość ujemną, ponieważ w ten sposób jest nieco bardziej golfowy).

Neil
źródło
2

R 181 163 bajtów

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

Funkcja anonimowa. Działa jako f(class, level, CON).

Objaśnienie: Tworzy wektory dla klasy sdo kostki maks. d, Używając 3 i 4 liter w nazwie klasy (najmniejsze unikalne mapowanie, jakie znalazłem).

CON mod mjest prosto ze specyfikacji, a HP = pierwszy poziom ( d + m) + pozostałe poziomy ( (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
źródło