# rootulp's solution

## to D&D Character in the Java Track

Published at May 20 2020 · 0 comments
Instructions
Test suite
Solution

For a game of Dungeons & Dragons, each player starts by generating a character they can play with. This character has, among other things, six abilities; strength, dexterity, constitution, intelligence, wisdom and charisma. These six abilities have scores that are determined randomly. You do this by rolling four 6-sided dice and record the sum of the largest three dice. You do this six times, once for each ability.

Your character's initial hitpoints are 10 + your character's constitution modifier. You find your character's constitution modifier by subtracting 10 from your character's constitution, divide by 2 and round down.

Write a random character generator that follows the rules above.

For example, the six throws of four dice may look like:

• 5, 3, 1, 6: You discard the 1 and sum 5 + 3 + 6 = 14, which you assign to strength.
• 3, 2, 5, 3: You discard the 2 and sum 3 + 5 + 3 = 11, which you assign to dexterity.
• 1, 1, 1, 1: You discard the 1 and sum 1 + 1 + 1 = 3, which you assign to constitution.
• 2, 1, 6, 6: You discard the 1 and sum 2 + 6 + 6 = 14, which you assign to intelligence.
• 3, 5, 3, 4: You discard the 3 and sum 5 + 3 + 4 = 12, which you assign to wisdom.
• 6, 6, 6, 6: You discard the 6 and sum 6 + 6 + 6 = 18, which you assign to charisma.

Because constitution is 3, the constitution modifier is -4 and the hitpoints are 6.

## Notes

Most programming languages feature (pseudo-)random generators, but few programming languages are designed to roll dice. One such language is Troll.

## Setup

Go through the setup instructions for Java to install the necessary dependencies:

https://exercism.io/tracks/java/installation

# Running the tests

You can run all the tests for an exercise by entering the following in your terminal:

``````\$ gradle test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by removing the `@Ignore("Remove to run test")` annotation.

## Source

Simon Shine, Erik Schierboom https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### DnDCharacterTest.java

``````import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.*;

public class DnDCharacterTest {

private DnDCharacter dndCharacter = new DnDCharacter();

@Test
public void testAbilityModifierForScore3IsNegative4() {
assertEquals(-4, dndCharacter.modifier(3));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore4IsNegative3() {
assertEquals(-3, dndCharacter.modifier(4));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore5IsNegative3() {
assertEquals(-3, dndCharacter.modifier(5));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore6IsNegative2() {
assertEquals(-2, dndCharacter.modifier(6));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore7IsNegative2() {
assertEquals(-2, dndCharacter.modifier(7));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore8IsNegative1() {
assertEquals(-1, dndCharacter.modifier(8));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore9IsNegative1() {
assertEquals(-1, dndCharacter.modifier(9));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore10Is0() {
assertEquals(0, dndCharacter.modifier(10));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore11Is0() {
assertEquals(0, dndCharacter.modifier(11));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore12Is1() {
assertEquals(1, dndCharacter.modifier(12));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore13Is1() {
assertEquals(1, dndCharacter.modifier(13));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore14Is2() {
assertEquals(2, dndCharacter.modifier(14));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore15Is2() {
assertEquals(2, dndCharacter.modifier(15));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore16Is3() {
assertEquals(3, dndCharacter.modifier(16));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore17Is3() {
assertEquals(3, dndCharacter.modifier(17));
}

@Ignore("Remove to run test")
@Test
public void testAbilityModifierForScore18Is4() {
assertEquals(4, dndCharacter.modifier(18));
}

@Ignore("Remove to run test")
@Test
public void testRandomAbilityIsWithinRange() {
int score = dndCharacter.ability();
assertTrue(score > 2 && score < 19);
}

@Ignore("Remove to run test")
@Test
public void testRandomCharacterIsValid() {
for (int i = 0; i < 1000; i++) {
DnDCharacter character = new DnDCharacter();
assertTrue(character.getStrength() > 2 && character.getStrength() < 19);
assertTrue(character.getDexterity() > 2 && character.getDexterity() < 19);
assertTrue(character.getConstitution() > 2 && character.getConstitution() < 19);
assertTrue(character.getIntelligence() > 2 && character.getIntelligence() < 19);
assertTrue(character.getWisdom() > 2 && character.getWisdom() < 19);
assertTrue(character.getCharisma() > 2 && character.getCharisma() < 19);
assertEquals(character.getHitpoints(),
10 + character.modifier(character.getConstitution()));
}
}

@Ignore("Remove to run test")
@Test
public void testEachAbilityIsOnlyCalculatedOnce() {
assertEquals(dndCharacter.getStrength(), dndCharacter.getStrength());
}

}``````
``````import java.util.Arrays;

class DnDCharacter {

public static int generateAbility() {
int[] rolls = { roll(), roll(), roll(), roll() };
Arrays.sort(rolls);
int[] topThreeRolls = Arrays.copyOf(rolls, 3);
return Arrays.stream(topThreeRolls).sum();
}

public static int calculateModifier(int constitution) {
return (int) Math.floor((constitution - 10) / 2.0);
}

/**
*
* @return a random number between 1 and 6 inclusive.
*/
private static int roll() {
return (int) Math.floor(Math.random() * 6) + 1;
}

private final int strength;
private final int dexterity;
private final int constituion;
private final int intelligence;
private final int wisdom;
private final int charisma;
private final int hitpoints;

public DnDCharacter() {
this.strength = generateAbility();
this.dexterity = generateAbility();
this.constituion = generateAbility();
this.intelligence = generateAbility();
this.wisdom = generateAbility();
this.charisma = generateAbility();
this.hitpoints = 10 + this.modifier(this.constituion);
}

/**
* This method is strictly exported because unit tests for this class expect an instance method.
*/
int ability() {
return generateAbility();
}

/**
* This method is strictly exported because unit tests for this class expect an instance method.
*/
int modifier(int constitution) {
return calculateModifier(constitution);
}

int getStrength() {
return this.strength;
}

int getDexterity() {
return this.dexterity;
}

int getConstitution() {
return this.constituion;
}

int getIntelligence() {
return this.intelligence;
}

int getWisdom() {
return this.wisdom;
}

int getCharisma() {
return this.charisma;
}

int getHitpoints() {
return this.hitpoints;
}

}``````