Skip to content

Commit 9fc903a

Browse files
authored
Merge pull request #116 from SimaDovakin/dnd-character-exercise
Dnd character exercise
2 parents 943216a + b79cc5e commit 9fc903a

11 files changed

+411
-0
lines changed

config.json

+8
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,14 @@
374374
"practices": [],
375375
"prerequisites": [],
376376
"difficulty": 1
377+
},
378+
{
379+
"slug": "dnd-character",
380+
"name": "D&D Character",
381+
"uuid": "206aa747-6c85-4438-a509-174febabb01a",
382+
"practices": [],
383+
"prerequisites": [],
384+
"difficulty": 1
377385
}
378386
]
379387
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Hints
2+
3+
There are some important concepts that are necessary for this task:
4+
5+
- [Abilities](https://www.unison-lang.org/docs/fundamentals/abilities/) in Unison.
6+
- [Delayed computations](https://www.unison-lang.org/docs/fundamentals/values-and-functions/delayed-computations/).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Instructions
2+
3+
For a game of [Dungeons & Dragons][dnd], each player starts by generating a character they can play with.
4+
This character has, among other things, six abilities; strength, dexterity, constitution, intelligence, wisdom and charisma.
5+
These six abilities have scores that are determined randomly.
6+
You do this by rolling four 6-sided dice and recording the sum of the largest three dice.
7+
You do this six times, once for each ability.
8+
9+
Your character's initial hitpoints are 10 + your character's constitution modifier.
10+
You find your character's constitution modifier by subtracting 10 from your character's constitution, divide by 2 and round down.
11+
12+
Write a random character generator that follows the above rules.
13+
14+
For example, the six throws of four dice may look like:
15+
16+
- 5, 3, 1, 6: You discard the 1 and sum 5 + 3 + 6 = 14, which you assign to strength.
17+
- 3, 2, 5, 3: You discard the 2 and sum 3 + 5 + 3 = 11, which you assign to dexterity.
18+
- 1, 1, 1, 1: You discard the 1 and sum 1 + 1 + 1 = 3, which you assign to constitution.
19+
- 2, 1, 6, 6: You discard the 1 and sum 2 + 6 + 6 = 14, which you assign to intelligence.
20+
- 3, 5, 3, 4: You discard the 3 and sum 5 + 3 + 4 = 12, which you assign to wisdom.
21+
- 6, 6, 6, 6: You discard the 6 and sum 6 + 6 + 6 = 18, which you assign to charisma.
22+
23+
Because constitution is 3, the constitution modifier is -4 and the hitpoints are 6.
24+
25+
~~~~exercism/note
26+
Most programming languages feature (pseudo-)random generators, but few programming languages are designed to roll dice.
27+
One such language is [Troll][troll].
28+
29+
[troll]: https://di.ku.dk/Ansatte/?pure=da%2Fpublications%2Ftroll-a-language-for-specifying-dicerolls(84a45ff0-068b-11df-825d-000ea68e967b)%2Fexport.html
30+
~~~~
31+
32+
[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Introduction
2+
3+
After weeks of anticipation, you and your friends get together for your very first game of [Dungeons & Dragons][dnd] (D&D).
4+
Since this is the first session of the game, each player has to generate a character to play with.
5+
The character's abilities are determined by rolling 6-sided dice, but where _are_ the dice?
6+
With a shock, you realize that your friends are waiting for _you_ to produce the dice; after all it was your idea to play D&D!
7+
Panicking, you realize you forgot to bring the dice, which would mean no D&D game.
8+
As you have some basic coding skills, you quickly come up with a solution: you'll write a program to simulate dice rolls.
9+
10+
[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"authors": [
3+
"SimaDovakin"
4+
],
5+
"contributors": [
6+
"rlmark"
7+
],
8+
"files": {
9+
"solution": [
10+
"dndCharacter.u"
11+
],
12+
"test": [
13+
"dndCharacter.test.u"
14+
],
15+
"example": [
16+
".meta/examples/dndCharacter.example.u"
17+
]
18+
},
19+
"blurb": "Randomly generate Dungeons & Dragons characters.",
20+
"source": "Simon Shine, Erik Schierboom",
21+
"source_url": "https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945"
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
unique type dndCharacter.Character = { strength : Nat
2+
, dexterity : Nat
3+
, constitution : Nat
4+
, intelligence : Nat
5+
, wisdom : Nat
6+
, charisma : Nat
7+
, hitpoints : Nat
8+
}
9+
10+
dndCharacter.modifier : Nat -> Int
11+
dndCharacter.modifier score =
12+
use Int - div
13+
score
14+
|> Nat.toInt
15+
|> (c -> c - +10)
16+
|> (c -> div c +2)
17+
18+
dndCharacter.ability_ : '{Random} Nat
19+
dndCharacter.ability_ = do
20+
'(Random.natIn 1 7)
21+
|> List.replicate 4
22+
|> List.sort
23+
|> List.slice 1 4
24+
|> Nat.sum
25+
26+
dndCharacter.character : '{Random} Character
27+
dndCharacter.character = do
28+
strength = !ability_
29+
dexterity = !ability_
30+
constitution = !ability_
31+
intelligence = !ability_
32+
wisdom = !ability_
33+
charisma = !ability_
34+
mod = modifier constitution
35+
hitpoints = Int.abs (+10 Int.+ mod)
36+
Character
37+
strength
38+
dexterity
39+
constitution
40+
intelligence
41+
wisdom
42+
charisma
43+
hitpoints
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
[
2+
{
3+
"test_code": "input = 18\n expected = 4\n label \"computes the modifier for 18 to be 4\" <| expect (expected == modifier input)",
4+
"name": "dndCharacter.test.testModifier.ex1"
5+
},
6+
{
7+
"test_code": "input = 17\n expected = 3\n label \"computes the modifier for 17 to be 3\" <| expect (expected == modifier input)",
8+
"name": "dndCharacter.test.testModifier.ex2"
9+
},
10+
{
11+
"test_code": "input = 16\n expected = 3\n label \"computes the modifier for 16 to be 3\" <| expect (expected == modifier input)",
12+
"name": "dndCharacter.test.testModifier.ex3"
13+
},
14+
{
15+
"test_code": "input = 15\n expected = 2\n label \"computes the modifier for 15 to be 2\" <| expect (expected == modifier input)",
16+
"name": "dndCharacter.test.testModifier.ex4"
17+
},
18+
{
19+
"test_code": "input = 14\n expected = 2\n label \"computes the modifier for 14 to be 2\" <| expect (expected == modifier input)",
20+
"name": "dndCharacter.test.testModifier.ex5"
21+
},
22+
{
23+
"test_code": "input = 13\n expected = 1\n label \"computes the modifier for 13 to be 1\" <| expect (expected == modifier input)",
24+
"name": "dndCharacter.test.testModifier.ex6"
25+
},
26+
{
27+
"test_code": "input = 12\n expected = 1\n label \"computes the modifier for 12 to be 1\" <| expect (expected == modifier input)",
28+
"name": "dndCharacter.test.testModifier.ex7"
29+
},
30+
{
31+
"test_code": "input = 11\n expected = 0\n label \"computes the modifier for 11 to be 0\" <| expect (expected == modifier input)",
32+
"name": "dndCharacter.test.testModifier.ex8"
33+
},
34+
{
35+
"test_code": "input = 10\n expected = 0\n label \"computes the modifier for 10 to be 0\" <| expect (expected == modifier input)",
36+
"name": "dndCharacter.test.testModifier.ex9"
37+
},
38+
{
39+
"test_code": "input = 9\n expected = -1\n label \"computes the modifier for 9 to be -1\" <| expect (expected == modifier input)",
40+
"name": "dndCharacter.test.testModifier.ex10"
41+
},
42+
{
43+
"test_code": "input = 8\n expected = -1\n label \"computes the modifier for 8 to be -1\" <| expect (expected == modifier input)",
44+
"name": "dndCharacter.test.testModifier.ex11"
45+
},
46+
{
47+
"test_code": "input = 7\n expected = -2\n label \"computes the modifier for 7 to be -2\" <| expect (expected == modifier input)",
48+
"name": "dndCharacter.test.testModifier.ex12"
49+
},
50+
{
51+
"test_code": "input = 6\n expected = -2\n label \"computes the modifier for 6 to be -2\" <| expect (expected == modifier input)",
52+
"name": "dndCharacter.test.testModifier.ex13"
53+
},
54+
{
55+
"test_code": "input = 5\n expected = -3\n label \"computes the modifier for 5 to be -3\" <| expect (expected == modifier input)",
56+
"name": "dndCharacter.test.testModifier.ex14"
57+
},
58+
{
59+
"test_code": "input = 4\n expected = -3\n label \"computes the modifier for 4 to be -3\" <| expect (expected == modifier input)",
60+
"name": "dndCharacter.test.testModifier.ex15"
61+
},
62+
{
63+
"test_code": "input = 3\n expected = -4\n label \"computes the modifier for 3 to be -4\" <| expect (expected == modifier input)",
64+
"name": "dndCharacter.test.testModifier.ex16"
65+
},
66+
{
67+
"test_code": "do\n seed = !nat\n calculatedAbility = Random.lcg seed ability_\n label \"generates value within range\" <| expect (Nat.inRange 3 19 calculatedAbility)\n",
68+
"name": "dndCharacter.test.testAbility"
69+
},
70+
{
71+
"test_code": "do\n seed = !nat\n (Character strength dexterity constitution intelligence wisdom charisma hitpoints) = Random.lcg seed character\n expectedHitpoints = Int.abs (+10 Int.+ modifier constitution)\n expect ((Nat.inRange 3 19 strength) && (Nat.inRange 3 19 dexterity) && (Nat.inRange 3 19 constitution) && (Nat.inRange 3 19 intelligence) && (Nat.inRange 3 19 wisdom) && (Nat.inRange 3 19 charisma) && (hitpoints == expectedHitpoints)\n ) |> label \"generates valid character\"",
72+
"name": "dndCharacter.test.testCharacter"
73+
}
74+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Testing transcript
2+
3+
```ucm
4+
.> load ./dndCharacter.u
5+
.> add
6+
.> load ./dndCharacter.test.u
7+
.> add
8+
.> move.term dndCharacter.tests tests
9+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[1e9ae1dc-35bd-43ba-aa08-e4b94c20fa37]
13+
description = "ability modifier -> ability modifier for score 3 is -4"
14+
15+
[cc9bb24e-56b8-4e9e-989d-a0d1a29ebb9c]
16+
description = "ability modifier -> ability modifier for score 4 is -3"
17+
18+
[5b519fcd-6946-41ee-91fe-34b4f9808326]
19+
description = "ability modifier -> ability modifier for score 5 is -3"
20+
21+
[dc2913bd-6d7a-402e-b1e2-6d568b1cbe21]
22+
description = "ability modifier -> ability modifier for score 6 is -2"
23+
24+
[099440f5-0d66-4b1a-8a10-8f3a03cc499f]
25+
description = "ability modifier -> ability modifier for score 7 is -2"
26+
27+
[cfda6e5c-3489-42f0-b22b-4acb47084df0]
28+
description = "ability modifier -> ability modifier for score 8 is -1"
29+
30+
[c70f0507-fa7e-4228-8463-858bfbba1754]
31+
description = "ability modifier -> ability modifier for score 9 is -1"
32+
33+
[6f4e6c88-1cd9-46a0-92b8-db4a99b372f7]
34+
description = "ability modifier -> ability modifier for score 10 is 0"
35+
36+
[e00d9e5c-63c8-413f-879d-cd9be9697097]
37+
description = "ability modifier -> ability modifier for score 11 is 0"
38+
39+
[eea06f3c-8de0-45e7-9d9d-b8cab4179715]
40+
description = "ability modifier -> ability modifier for score 12 is +1"
41+
42+
[9c51f6be-db72-4af7-92ac-b293a02c0dcd]
43+
description = "ability modifier -> ability modifier for score 13 is +1"
44+
45+
[94053a5d-53b6-4efc-b669-a8b5098f7762]
46+
description = "ability modifier -> ability modifier for score 14 is +2"
47+
48+
[8c33e7ca-3f9f-4820-8ab3-65f2c9e2f0e2]
49+
description = "ability modifier -> ability modifier for score 15 is +2"
50+
51+
[c3ec871e-1791-44d0-b3cc-77e5fb4cd33d]
52+
description = "ability modifier -> ability modifier for score 16 is +3"
53+
54+
[3d053cee-2888-4616-b9fd-602a3b1efff4]
55+
description = "ability modifier -> ability modifier for score 17 is +3"
56+
57+
[bafd997a-e852-4e56-9f65-14b60261faee]
58+
description = "ability modifier -> ability modifier for score 18 is +4"
59+
60+
[4f28f19c-2e47-4453-a46a-c0d365259c14]
61+
description = "random ability is within range"
62+
63+
[385d7e72-864f-4e88-8279-81a7d75b04ad]
64+
description = "random character is valid"
65+
66+
[2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe]
67+
description = "each ability is only calculated once"
68+
include = false
69+
70+
[dca2b2ec-f729-4551-84b9-078876bb4808]
71+
description = "each ability is only calculated once"
72+
reimplements = "2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe"

0 commit comments

Comments
 (0)