11
2
I have trouble remembering everything I have to do when leveling up a D&D character. For whatever reason, one of the things that gives me trouble is figuring out what their new maximum HP value should be. For this challenge, you will write a program or function to calculate the correct value automatically.
Terminology
The first thing you need to know about to calculate max HP is the "Constitution modifier". Each DND character has six integer ability scores, including one for Constitution. The only relevant knowledge required for this challenge is how the Constitution ability score affects another stat, which is the Constitution modifier. In short, the modifier is equal to floor( (ability_score - 10) / 2 )
. Adventurers can only have ability scores from 1 to 20, inclusive. Your code will never have to handle scores outside that range, which also means it will never have to handle a modifier lower than -5 or greater than +5. Though the Constitution modifier can change as a character levels up, its effects on HP are applied retroactively, so only its current value is needed to calculate current max HP.
(This is entirely irrelevant to the challenge, but if you're curious about how it affects maximum HP: You can assume the "Tough" feat adds 2 to a character's Constitution modifier for the purposes of HP calculation, since that's effectively what it does. That's not the text of the feat but the math works out to be exactly the same. You don't have to handle this feat in your answer.)
Next, every class has an assigned "hit die" type, which is involved in calculating HP. The following table lists the hit dice for each class.
Sorcerer: d6
Wizard: d6
Bard: d8
Cleric: d8
Druid: d8
Monk: d8
Rogue: d8
Warlock: d8
Fighter: d10
Paladin: d10
Ranger: d10
Barbarian: d12
Finally, the character's level. All that this affects is how many times to add a value to the running total in the following section. A character's level is an integer from 1 to 20, inclusive1. Your code will never have to handle a level outside that range. To reach level n
, a character starts at level 1 and levels up n-1
times. For example, a level 3 character got to where they are by being a level 1 character and levelling up twice.
How to Calculate Max HP
A character's maximum HP is equal to their HP at level 1 plus the sum of the increase they received at each level.
At level 1
At level 1, a character's HP is equal to the highest possible roll on their hit die (the number in the name of the die, for those of you unfamiliar with dice that have more than 6 sides) plus their Constitution modifier. Remember that when calculating HP at a later level, you may assume a character's Constitution has always been the same, as this part of the calculation is re-done every time Constitution changes.
When levelling up
Every time a character levels up, they have two options. They may either roll one of their hit dice or take the average roll of that die (rounded up). Whichever they choose, their Constitution modifier is added to the result. This total is the amount that their HP increases. For this challenge, the average roll is always taken, so output is deterministic. (Again, if you're not familiar with >6 sided dice, you can calculate the rounded-up average roll as (highest_possible_roll / 2) + 1
.)
There is one notable exception. A character's maximum HP always increases by at least 1 each time they level up2. If the instructions in the above paragraph would result in an increase of 0 or less when leveling up, it increases by 1 instead.
The Challenge
Your program or function will take three inputs:
- The character's class, as a string
- The character's level
- The character's Constitution ability score (not modifier)
It will output only one thing: The character's current maximum HP.
Examples
Every possible combination of inputs and their associated outputs can be found at this link. For the sake of having something to look at on this page, here are 30 test cases chosen at random:
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. Strictly speaking, I don't think there's a rule that says 20 is the maximum level. However, 21 is the point where there stop being tables in the book to tell you what some of the various numbers in the rules should be, including the amount of experience you need to obtain to reach it. That's a good enough level cap for me.
2. I actually don't think this is true with RAW. I asked on rpg.se and such a thing doesn't appear to be written down anywhere. However, Mike Mearls, lead designer of D&D, tweeted it in March 2015. This is not authoritative the way that you could argue a tweet from lead rules developer Jeremy Crawford would be, but it is evidence that it's what they intended, so I'll use it for this challenge.
Does class have to be given as a string, or can it be given as the number of the hit die, given that's the only relevant information for a class. Otherwise people will just need a generic table of "If these classes then this die, if these classes then this die" etc. – Skidsdev – 2017-05-03T15:48:00.413
Also are level and constitution passed as integers, or as strings saying "xth level" and "y CON"? – Skidsdev – 2017-05-03T15:48:24.407
1
Gosh, I'm old, I still remember this table: http://www.ancientscrossroads.com/adnd_tools/con_table.htm
– Neil – 2017-05-03T15:58:39.827@Mayube Probably shouldn't have asked a question and immediately gone out for pizza, huh? :P The class has to be a string, because I think there's enough data in those strings to find patterns to shorten the table (which appears to be the case, based on the answers that have come in so far). Level and constitution are ints. – undergroundmonorail – 2017-05-03T16:26:50.663
I don't think you have enough edge cases in your sample test cases. – Neil – 2017-05-03T16:32:33.790
3I found it pretty hard to parse out the relevant information from all the info being thrown at me. – Jonathan Allan – 2017-05-03T16:33:12.670
@undergroundmonorail In that case I'm gunna post a non-competing answer, because my language can't handle string parsing :( – Skidsdev – 2017-05-03T16:33:50.427
Here is a verbose (i.e. non-golfed) reference implementation with the listed test cases. (It's a tinyurl as the TIO link itself was too long for a comment). – Jonathan Allan – 2017-05-03T17:07:46.353
<Fondly remembers his 6 con, 6 hp kobold> Oh wait, he's still alive. It was the rest of the party that died a horrific death. – Draco18s no longer trusts SE – 2017-05-03T20:26:25.620