D & D 5e Kalkulator HP

11

Saya mengalami kesulitan mengingat semua yang harus saya lakukan ketika menaikkan level karakter D & D. Untuk alasan apa pun, salah satu hal yang membuat saya kesulitan adalah mencari tahu berapa nilai maksimum HP yang seharusnya. Untuk tantangan ini, Anda akan menulis program atau fungsi untuk menghitung nilai yang benar secara otomatis.

Terminologi

Hal pertama yang perlu Anda ketahui tentang menghitung HP maks adalah "pengubah Konstitusi". Setiap karakter DND memiliki enam skor kemampuan integer, termasuk satu untuk Konstitusi. Satu-satunya pengetahuan yang relevan yang diperlukan untuk tantangan ini adalah bagaimana skor kemampuan Konstitusi mempengaruhi stat lain, yang merupakan pengubah Konstitusi. Singkatnya, pengubah sama dengan floor( (ability_score - 10) / 2 ). Petualang hanya dapat memiliki skor kemampuan dari 1 hingga 20, inklusif. Kode Anda tidak akan pernah harus menangani skor di luar rentang itu, yang juga berarti tidak akan pernah menangani pengubah yang lebih rendah dari -5 atau lebih besar dari +5. Meskipun pengubah Konstitusi dapat berubah saat karakter naik level, pengaruhnya terhadap HP diterapkan secara surut, jadi hanya nilai saat ini diperlukan untuk menghitung HP maksimum saat ini.

(Hal ini sepenuhnya tidak relevan dengan tantangan, tetapi jika Anda sedang ingin tahu tentang bagaimana hal itu mempengaruhi HP maksimum: Anda dapat mengasumsikan "Tough" feat menambahkan 2 ke karakter Konstitusi pengubah untuk tujuan perhitungan HP, karena itulah efektif apa yang dilakukannya (Itu bukan teks dari feat, tetapi perhitungan matematika persis sama. Anda tidak harus menangani feat ini dalam jawaban Anda.)

Selanjutnya, setiap kelas memiliki tipe "hit die" yang ditetapkan, yang terlibat dalam menghitung HP. Tabel berikut mencantumkan dadu hit untuk setiap kelas.

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

Akhirnya, level karakter. Semua yang mempengaruhi ini adalah berapa kali menambahkan nilai ke total berjalan di bagian berikut. Level karakter adalah bilangan bulat dari 1 hingga 20, inklusif 1 . Kode Anda tidak akan pernah harus menangani level di luar rentang itu. Untuk mencapai level n, karakter dimulai pada level 1 dan naik level n-1kali. Misalnya, karakter level 3 sampai di tempat mereka berada dengan menjadi karakter level 1 dan naik level dua kali.

Cara Menghitung Max HP

HP maksimum karakter sama dengan HP mereka di level 1 ditambah jumlah kenaikan yang mereka terima di setiap level.

Di level 1

Pada level 1, HP karakter sama dengan gulungan tertinggi yang mungkin ada pada die hit mereka (nomor atas nama die, bagi Anda yang tidak terbiasa dengan dadu yang memiliki lebih dari 6 sisi) ditambah pengubah Konstitusi mereka. Ingatlah bahwa ketika menghitung HP di tingkat selanjutnya, Anda dapat menganggap Konstitusi karakter selalu sama, karena bagian perhitungan ini dilakukan kembali setiap kali Konstitusi berubah.

Saat naik level

Setiap kali karakter naik level, mereka memiliki dua opsi. Mereka dapat menggulung salah satu dadu hit mereka atau mengambil rata-rata dadu yang mati (dibulatkan) Apa pun yang mereka pilih, pengubah Konstitusi mereka ditambahkan ke hasilnya. Total ini adalah jumlah yang meningkat HP mereka. Untuk tantangan ini, roll rata-rata selalu diambil, sehingga output bersifat deterministik. (Sekali lagi, jika Anda tidak terbiasa dengan> 6 sisi dadu, Anda dapat menghitung roll rata-rata dibulatkan sebagai (highest_possible_roll / 2) + 1.)

Ada satu pengecualian penting. HP maksimum karakter selalu meningkat setidaknya 1 setiap kali mereka naik level 2 . Jika instruksi dalam paragraf di atas akan menghasilkan peningkatan 0 atau kurang saat naik level, itu meningkat 1 sebagai gantinya.

Tantangan

Program atau fungsi Anda akan mengambil tiga input :

  • Kelas karakter, sebagai string
  • Level karakter
  • Skor kemampuan Konstitusi karakter ( bukan pengubah)

Ini hanya akan menghasilkan satu hal: Karakter maksimum HP saat ini.

Contohnya

Setiap kombinasi input yang mungkin dan output terkaitnya dapat ditemukan di tautan ini. Demi memiliki sesuatu untuk dilihat di halaman ini, berikut adalah 30 kasus uji yang dipilih secara acak:

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. Sebenarnya, saya tidak berpikir ada aturan yang mengatakan 20 adalah level maksimum. Namun, 21 adalah titik di mana ada berhenti menjadi tabel dalam buku untuk memberi tahu Anda apa yang harus dari beberapa angka dalam aturan, termasuk jumlah pengalaman yang Anda butuhkan untuk mencapainya. Itu batas level yang cukup baik untuk saya.

2. Saya sebenarnya tidak berpikir ini benar dengan RAW. Saya bertanya pada rpg.se dan hal seperti itu sepertinya tidak ditulis di mana pun. Namun, Mike Mearls, desainer utama D&D, mentweetnya pada bulan Maret 2015 . Ini tidak otoritatif seperti yang Anda bisa berargumen tentang tweet dari pengembang peraturan utama Jeremy Crawford, tetapi itu adalah bukti bahwa itulah yang mereka maksudkan, jadi saya akan menggunakannya untuk tantangan ini.

monmon bawah tanah
sumber
Apakah kelas harus diberikan sebagai string, atau dapatkah itu diberikan sebagai jumlah hit die, mengingat itulah satu-satunya informasi yang relevan untuk suatu kelas. Kalau tidak, orang hanya akan membutuhkan tabel umum "Jika kelas-kelas ini maka ini mati, jika kelas-kelas ini maka ini mati" dll.
Skidsdev
Juga apakah level dan konstitusi disahkan sebagai bilangan bulat, atau sebagai string yang mengatakan "level xth" dan "y CON"?
Skidsdev
1
Astaga, saya sudah tua, saya masih ingat tabel ini: ancientscrossroads.com/adnd_tools/con_table.htm
Neil
@ Mayube Mungkin seharusnya tidak mengajukan pertanyaan dan segera keluar untuk pizza, ya? : P Kelas harus berupa string, karena saya pikir ada cukup data dalam string tersebut untuk menemukan pola untuk memperpendek tabel (yang tampaknya menjadi kasusnya, berdasarkan jawaban yang telah datang sejauh ini). Level dan konstitusi adalah int.
undergroundmonorail
3
Saya merasa sangat sulit untuk mengurai informasi yang relevan dari semua info yang dilemparkan kepada saya.
Jonathan Allan

Jawaban:

2

Jelly , 34 byte

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

Program lengkap mengambil tiga argumen baris perintah: kelas, skor, level.

Cobalah online!

Bagaimana?

Bagian tengah kode, dipisahkan oleh ðs adalah tautan diad yang menghitung hasil dari beberapa nilai yang dihitung sebelumnya:

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

Pengubah dihitung di sisi kanan:

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

Setengah dari nilai die dihitung di sebelah kiri:

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)

Mempertimbangkan jumlah ordinal dari nama-nama modulo msedemikian rupa sehingga mminimal sambil menjaga klasifikasi (dengan mati) dari hasil bertabrakan m=15. Menempatkan nilai yang diperlukan (half-die roll) pada indeks tersebut dalam daftar panjang 15 memungkinkan pencarian menggunakan pengindeksan modular Jelly dengan . Mengompresi daftar sebagai nomor basis 6 dengan satu-satunya yang 6diganti oleh 0adalah satu byte lebih pendek daripada alternatif kompresi basis-7 atau kompresi basis-4 & meningkatkan nilai (dengan overhead byte yang terkait dengan menggunakan nilad tambahan dalam rantai) . Basis 6, daripada 7, dekompresi dicapai dengan menggunakan fakta bahwa dekompresi basis, (daripada konversi basis, b), memiliki konstruksi rentang implisit ketika argumen yang tepat,r, Adalah bilangan bulat, yang artinya adalah seperti mengkonversi ke basis rdan kemudian mengubah apa saja 0menjadi rsemua sekaligus.

Itu adalah:

         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

Menyusun ulang daftar, mengonversi 6 pada indeks 13 menjadi nol dan menjadikannya minimal di basis 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

Membuat kodenya

                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
sumber
8

JavaScript (ES6), 81 78 76 74 byte

Mengambil input sebagai (kelas, level, constution_ability_score) . Kelas tidak peka huruf besar-kecil.

(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

Ini pada dasarnya menggunakan matematika yang sama dengan versi awal saya, tetapi d sekarang dihitung tanpa tabel pencarian.

Uji kasus


Versi awal, 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

Bagaimana itu bekerja

Bagian yang sulit adalah mengubah string kelas c menjadi hit dadu yang sesuai. Lebih tepatnya, nilai yang akan kita simpan adalah d = dadu / 2 + 1 .

Kami menggunakan rumus parseInt(c, 35) % 24 % 15yang memberikan:

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

Dengan memasukkan nilai d pada posisi yang sesuai ke dalam string dan mengisi slot yang tidak digunakan dengan nol, kita mendapatkan:

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

Maka rumus terakhir:

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

Setelah kami memiliki d , kami menghitung:

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

yang merupakan jumlah poin teoritis yang diperoleh pada setiap level-up.

Jika h positif, kami cukup menghitung:

h * l

Jika tidak, kita perlu memperhitungkan fakta bahwa setidaknya 1 poin diperoleh pada setiap level-up. Jadi sebagai gantinya kami menghitung:

h + l - 1

Dalam kedua kasus, kami menyesuaikan hasilnya dengan menambahkan d - 2 , sehingga jumlah poin awal terintegrasi dengan benar.

Uji kasus

Arnauld
sumber
Tampaknya ada yang salah dengan kode Anda; Bards dengan CON 1 atau Wizards dengan CON 2 atau 3 mendapatkan jumlah poin hit yang sama berapa pun level mereka.
Neil
1
@Neil Terima kasih telah memperhatikan. Saya pikir ini sudah diperbaiki.
Arnauld
3

Batch, 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

Mengambil kelas, level, dan konstitusi sebagai argumen baris perintah. Penjelasan: HP dapat dihitung sebagai (HP pada level 1) + (level - 1) + min (selanjutnya HP per level, 0) * (level - 1). HP per level selanjutnya adalah setengah hit die plus pengubah konstitusi. Sebagian besar kelas menggunakan d8 sehingga ini menjadi kurang dari setengah konstitusi ( %3/2-1), sedangkan HP pada level 1 adalah 3 lebih dari itu. Selanjutnya HP per level dan HP di level 1 kemudian disesuaikan untuk enam kelas yang tidak menggunakan d8. HP per level selanjutnya dibatasi hingga 0 (ini sebenarnya menggunakan nilai negatif karena sedikit lebih golf dengan cara ini.)

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

Fungsi anonim. Berjalan sebagai f(class, level, CON).

Penjelasan: Membuat vektor untuk kelas smenjadi dadu maks d, menggunakan huruf ke-3 dan ke-4 dalam nama kelas (pemetaan unik terkecil yang saya temukan).

CON mod mlangsung dari spec, dan HP = level pertama ( d + m) + level selanjutnya ( (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
sumber