D&D 5e HP Калькулятор


11

У мене виникають труднощі з запам'ятовуванням всього, що я маю робити, коли вирівнювати характер науково-дослідної роботи. З будь-якої причини однією з речей, яка доставляє мені клопоту, є з'ясування того, яким має бути їх новий максимальний показник HP. Для цього завдання ви напишете програму або функцію для автоматичного обчислення правильного значення.

Термінологія

Перше, про що потрібно знати, щоб розрахувати максимум HP, - це "модифікатор конституції". У кожного символу DND є шість цілочисельних балів здібностей, включаючи одне для Конституції. Єдині відповідні знання, необхідні для цього завдання, - це те, як оцінка здатності Конституції впливає на інший статистичний стан, який є модифікатором Конституції. Коротше кажучи, модифікатор дорівнює floor( (ability_score - 10) / 2 ). Авантюристи можуть мати лише оцінки балів від 1 до 20 включно. Ваш код ніколи не повинен обробляти бали за межами цього діапазону, що також означає, що йому ніколи не доведеться обробляти модифікатор нижче -5 або більше +5. Хоча модифікатор Конституції може змінюватися в міру збільшення символів, його вплив на HP застосовується заднім числом, тому для розрахунку поточного максимуму HP потрібно лише його поточне значення.

(Це зовсім не має значення для виклику, але якщо вам цікаво, як це впливає на максимальний рівень HP: Ви можете припустити, що подвиг "Жорсткий" додає 2 до модифікатора конституції персонажа для розрахунку HP, оскільки це ефективно те, що він робить . Це не текст подвигу, але математика виходить точно такою ж. Вам не потрібно обробляти цей подвиг у своїй відповіді.)

Далі, кожному класу присвоєний тип "hit die", який бере участь у обчисленні HP. У наступній таблиці перераховані кістки для кожного класу.

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

Нарешті, рівень персонажа. Все, на що це впливає, це скільки разів додати значення до поточної суми в наступному розділі. Рівень символу - ціле число від 1 до 20, включно 1 . Ваш код ніколи не повинен обробляти рівень за межами цього діапазону. Щоб досягти рівня n, персонаж починається з рівня 1 і збільшується в n-1рази. Наприклад, символ 3 рівня дістався до місця, де вони знаходяться, будучи символом першого рівня та зростаючи вдвічі.

Як розрахувати Макс. HP

Максимальна кількість символів HP дорівнює їх HP на рівні 1 плюс сума збільшення, яке вони отримували на кожному рівні.

На рівні 1

На рівні 1 HP-персонаж персонажа дорівнює максимально можливій котушці їх ударної матриці (число в назві штампу, для тих, хто вам не знайомий з кістками, які мають більше 6 сторін) плюс їх модифікатор конституції. Пам’ятайте, що під час обчислення HP на більш пізньому рівні, ви можете припустити, що Конституція персонажа завжди була однаковою, оскільки ця частина розрахунку повторюється щоразу, коли зміниться Конституція.

При вирівнюванні

Кожен раз, коли персонаж зростає, у них є два варіанти. Вони можуть або закатати одну зі своїх вбитих кісток, або взяти середній рулон, що гине (округлений). Що б вони не вибрали, до результату додається їх модифікатор конституції. Це загальна сума, яку збільшує їх HP. За цей виклик завжди приймається середній перелік, тому вихід є детермінованим. (Знову ж таки, якщо ви не знайомі з> двосторонніми кістками, ви можете обчислити округлий середній рулон як (highest_possible_roll / 2) + 1.)

Є один помітний виняток. Максимум HP символів завжди збільшується щонайменше на 1 щоразу, коли вони вирівнюють 2 . Якщо вказівки у наведеному вище пункті призвели до збільшення 0 або менше при вирівнюванні, він збільшується на 1.

Змагання

Ваша програма або функція потребуватиме трьох входів :

  • Клас персонажа, як рядок
  • Рівень персонажа
  • Оцінка здатності до конституції персонажа ( не модифікатор)

Це буде вихід тільки один: поточний максимум HP персонажа.

Приклади

Кожне можливе поєднання входів та пов'язаних з ними результатів можна знайти за цим посиланням. Для того, щоб подивитися на цій сторінці, ось 30 тестових випадків, вибраних навмання:

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. Строго кажучи, я не думаю, що існує правило, яке говорить, що 20 - це максимальний рівень. Однак 21 - це пункт, коли у книзі перестають бути таблицями, щоб розповісти, якими мають бути деякі з різних чисел у правилах, включаючи кількість досвіду, необхідного для його досягнення. Це досить хороший рівень шапки для мене.

2. Я насправді не думаю, що це стосується RAW. Я запитав на rpg.se, і таке, схоже, ніде не записується. Однак Майк Мерлз, головний дизайнер D&D, написав твіт у березні 2015 року . Це не є авторитетним способом, яким ви могли б стверджувати твіт від головного розробника правил Джеремі Крофорда, але це свідчення того, що це те, що вони задумали, тому я використаю це для цього завдання.


Чи потрібно клас класу задавати як рядок, чи він може бути вказаний як номер звернутого штампу, враховуючи, що це єдина відповідна інформація для класу. Інакше людям просто знадобиться загальна таблиця "Якщо ці класи, то це помре, якщо ці класи, то це помре" і т. Д.
Skidsdev

Також рівень чи конституція передаються як цілі числа, або як рядки, що говорять про "xth level" та "y CON"?
Скидсдев

1
Боже, я старий, я все ще пам’ятаю цю таблицю: ancientscrossroads.com/adnd_tools/con_table.htm
Ніл

@Mayube Напевно, не варто було ставити запитання і негайно пішли на піцу, так? : P Клас повинен бути рядком, тому що я думаю, що в цих рядках є достатньо даних, щоб знайти шаблони, щоб скоротити таблицю (що, здається, так, виходячи з відповідей, що надійшли поки що). Рівень та конституція - це вклад.
підземниймонорельс

3
Мені було досить важко розібрати відповідну інформацію з усієї інформації, яка кидається на мене.
Джонатан Аллан

Відповіді:


2

Желе , 34 байти

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

Повна програма, що бере три аргументи командного рядка: клас, оцінка, рівень.

Спробуйте в Інтернеті!

Як?

Середина коду, розділена ðs, - це діадичне посилання, яке обчислює результат за деякими раніше обчисленими значеннями:

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

Модифікатор обчислюється праворуч:

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

Половина значення штампу обчислюється в лівій частині:

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)

Враховуючи порядкові суми найменувань класів за модулем mтакі, що mє мінімальними при збереженні класифікацій (за вимиранням) від збіжжя врожайності m=15. Розміщення необхідних значень (напівмертний рулон) у цих індексах у списку довжиною 15 дозволяє шукати, використовуючи модульну індексацію Jelly з . Стиснення списку у вигляді базового 6 числа з одиночним, 6заміненим на a, 0- байт коротший, ніж альтернативи стиснення base-7 або base-4 і збільшення значень (з байтовим накладним покриттям, пов'язаним із використанням додаткового nilad у ланцюзі) . Декомпресія бази 6, а не 7 досягається використанням того факту, що декомпресія бази (а не перетворення бази b) має неявну побудову діапазону, коли це правильний аргумент,r, являє собою ціле число, а значить, це як перетворення на базу, rа потім зміна будь-якого 0на " rall" за один раз.

Це:

         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

Перестановка до списку, перетворення 6 в індексі 13 в нуль і мінімізація в базі 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

Складання коду

                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 байт

Приймає дані як (клас, рівень, конституція_ability_score) . Клас нечутливий до регістру.

(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

Це по суті, використовуючи ту саму математику, що і в моїй початковій версії, але d тепер обчислюється без будь-якої таблиці пошуку.

Тестові справи


Початкова версія, 87 84 байт

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

Як це працює

Хитра частина полягає в перетворенні рядка класу c у відповідні хіти-кістки. Точніше, значення, яке ми збираємося зберігати, - d = кістки / 2 + 1 .

Ми використовуємо формулу, parseInt(c, 35) % 24 % 15яка дає:

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

Вставляючи значення d у відповідних позиціях у рядок і додаючи невикористані слоти з нулями, отримуємо:

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

Звідси остаточна формула:

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

Після того як ми отримаємо d , обчислимо:

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

яка є теоретичною кількістю балів, які набираються на кожному рівні вгору.

Якщо h додатний, ми просто обчислюємо:

h * l

Якщо ні, ми повинні враховувати той факт, що принаймні 1 бал набирається на кожному рівні. Тому ми обчислюємо замість цього:

h + l - 1

В обох випадках коригуємо результат, додаючи d - 2 , щоб початкова кількість балів була правильно інтегрована.

Тестові справи


З вашим кодом щось здається не так; Барди з CON 1 або Wizards з CON 2 або 3 отримують однакову кількість точок ударів незалежно від рівня.
Ніл

1
@Neil Дякую за те, що помітили. Я думаю, що це виправлено.
Арнольд

3

Пакетна, 172 байти

@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

Вважає клас, рівень та конституцію аргументами командного рядка. Пояснення: HP можна обчислити як (HP на рівні 1) + (рівень - 1) + хв (далі HP на рівні, 0) * (рівень - 1). Далі HP на рівні - це половина ударної матриці плюс модифікатор конституції. Більшість класів використовують d8, тому це стає менше, ніж половина конституції ( %3/2-1), тоді як HP на рівні 1 на 3 більше, ніж це. Далі HP на рівні та HP на рівні 1 потім налаштовуються на шість класів, у яких не використовується d8. Подальший рівень HP за рівнем обмежується 0 (для цього фактично використовується негативне значення, оскільки таким чином він трохи гольфує.


2

R, 181 163 байт

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

Анонімна функція. Виконує як f(class, level, CON).

Пояснення: Створює вектори для класу, sщоб нарізати максимум d, використовуючи 3 та 4 літери в назві класу (найменше знайдене я унікальне відображення).

CON mod mпрямо від специфікації, а HP = перший рівень ( d + m) + решта рівнів ( (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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.