From b50d6ccd8faa59d6251af2b1455595bb57ebee26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Thu, 15 Feb 2024 06:52:53 -0800 Subject: [PATCH] add dnd-character (#264) * Add dnd-character * Bump up difficulty --- config.json | 8 ++ .../dnd-character/.docs/instructions.md | 31 +++++++ .../practice/dnd-character/.meta/config.json | 19 +++++ .../dnd-character/.meta/example.coffee | 20 +++++ .../practice/dnd-character/.meta/tests.toml | 72 ++++++++++++++++ .../dnd-character/dnd-character.coffee | 8 ++ .../dnd-character/dnd-character.spec.coffee | 83 +++++++++++++++++++ 7 files changed, 241 insertions(+) create mode 100644 exercises/practice/dnd-character/.docs/instructions.md create mode 100644 exercises/practice/dnd-character/.meta/config.json create mode 100644 exercises/practice/dnd-character/.meta/example.coffee create mode 100644 exercises/practice/dnd-character/.meta/tests.toml create mode 100644 exercises/practice/dnd-character/dnd-character.coffee create mode 100644 exercises/practice/dnd-character/dnd-character.spec.coffee diff --git a/config.json b/config.json index 56891356..b4de36f3 100644 --- a/config.json +++ b/config.json @@ -486,6 +486,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "dnd-character", + "name": "D&D Character", + "uuid": "6f421414-3668-450d-a7ea-bba6d4e0d75f", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/dnd-character/.docs/instructions.md b/exercises/practice/dnd-character/.docs/instructions.md new file mode 100644 index 00000000..b0a60359 --- /dev/null +++ b/exercises/practice/dnd-character/.docs/instructions.md @@ -0,0 +1,31 @@ +# Instructions + +For a game of [Dungeons & Dragons][dnd], 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][troll]. + +[dnd]: https://en.wikipedia.org/wiki/Dungeons_%26_Dragons +[troll]: https://di.ku.dk/Ansatte/?pure=da%2Fpublications%2Ftroll-a-language-for-specifying-dicerolls(84a45ff0-068b-11df-825d-000ea68e967b)%2Fexport.html diff --git a/exercises/practice/dnd-character/.meta/config.json b/exercises/practice/dnd-character/.meta/config.json new file mode 100644 index 00000000..f3c0a197 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "dnd-character.coffee" + ], + "test": [ + "dnd-character.spec.coffee" + ], + "example": [ + ".meta/example.coffee" + ] + }, + "blurb": "Randomly generate Dungeons & Dragons characters.", + "source": "Simon Shine, Erik Schierboom", + "source_url": "https://github.com/exercism/problem-specifications/issues/616#issuecomment-437358945" +} diff --git a/exercises/practice/dnd-character/.meta/example.coffee b/exercises/practice/dnd-character/.meta/example.coffee new file mode 100644 index 00000000..f01bc40b --- /dev/null +++ b/exercises/practice/dnd-character/.meta/example.coffee @@ -0,0 +1,20 @@ +class DndCharacter + constructor: () -> + @strength = @ability() + @dexterity = @ability() + @constitution = @ability() + @intelligence = @ability() + @wisdom = @ability() + @charisma = @ability() + @hitpoints = 10 + @modifier @constitution + + modifier: (score) -> + (score - 10) // 2 + + ability: () -> + rolls = [0,0,0,0] + .map((a) -> Math.floor(Math.random() * 6) + 1) + .sort((a, b) -> a - b)[1..] + .reduce((a, b) -> a + b) + +module.exports = DndCharacter diff --git a/exercises/practice/dnd-character/.meta/tests.toml b/exercises/practice/dnd-character/.meta/tests.toml new file mode 100644 index 00000000..719043b2 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/tests.toml @@ -0,0 +1,72 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[1e9ae1dc-35bd-43ba-aa08-e4b94c20fa37] +description = "ability modifier -> ability modifier for score 3 is -4" + +[cc9bb24e-56b8-4e9e-989d-a0d1a29ebb9c] +description = "ability modifier -> ability modifier for score 4 is -3" + +[5b519fcd-6946-41ee-91fe-34b4f9808326] +description = "ability modifier -> ability modifier for score 5 is -3" + +[dc2913bd-6d7a-402e-b1e2-6d568b1cbe21] +description = "ability modifier -> ability modifier for score 6 is -2" + +[099440f5-0d66-4b1a-8a10-8f3a03cc499f] +description = "ability modifier -> ability modifier for score 7 is -2" + +[cfda6e5c-3489-42f0-b22b-4acb47084df0] +description = "ability modifier -> ability modifier for score 8 is -1" + +[c70f0507-fa7e-4228-8463-858bfbba1754] +description = "ability modifier -> ability modifier for score 9 is -1" + +[6f4e6c88-1cd9-46a0-92b8-db4a99b372f7] +description = "ability modifier -> ability modifier for score 10 is 0" + +[e00d9e5c-63c8-413f-879d-cd9be9697097] +description = "ability modifier -> ability modifier for score 11 is 0" + +[eea06f3c-8de0-45e7-9d9d-b8cab4179715] +description = "ability modifier -> ability modifier for score 12 is +1" + +[9c51f6be-db72-4af7-92ac-b293a02c0dcd] +description = "ability modifier -> ability modifier for score 13 is +1" + +[94053a5d-53b6-4efc-b669-a8b5098f7762] +description = "ability modifier -> ability modifier for score 14 is +2" + +[8c33e7ca-3f9f-4820-8ab3-65f2c9e2f0e2] +description = "ability modifier -> ability modifier for score 15 is +2" + +[c3ec871e-1791-44d0-b3cc-77e5fb4cd33d] +description = "ability modifier -> ability modifier for score 16 is +3" + +[3d053cee-2888-4616-b9fd-602a3b1efff4] +description = "ability modifier -> ability modifier for score 17 is +3" + +[bafd997a-e852-4e56-9f65-14b60261faee] +description = "ability modifier -> ability modifier for score 18 is +4" + +[4f28f19c-2e47-4453-a46a-c0d365259c14] +description = "random ability is within range" + +[385d7e72-864f-4e88-8279-81a7d75b04ad] +description = "random character is valid" + +[2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe] +description = "each ability is only calculated once" +include = false + +[dca2b2ec-f729-4551-84b9-078876bb4808] +description = "each ability is only calculated once" +reimplements = "2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe" diff --git a/exercises/practice/dnd-character/dnd-character.coffee b/exercises/practice/dnd-character/dnd-character.coffee new file mode 100644 index 00000000..94926d5a --- /dev/null +++ b/exercises/practice/dnd-character/dnd-character.coffee @@ -0,0 +1,8 @@ +class DndCharacter + constructor: -> + + modifier: (score) -> + + ability: -> + +module.exports = DndCharacter diff --git a/exercises/practice/dnd-character/dnd-character.spec.coffee b/exercises/practice/dnd-character/dnd-character.spec.coffee new file mode 100644 index 00000000..e1e35e78 --- /dev/null +++ b/exercises/practice/dnd-character/dnd-character.spec.coffee @@ -0,0 +1,83 @@ +DndCharacter = require './dnd-character' + +describe 'D&D Character', -> + character = new DndCharacter() + + describe 'ability modifier ->', -> + it 'ability modifier for score 3 is -4', -> + expect(character.modifier 3).toEqual -4 + + xit 'ability modifier for score 4 is -3', -> + expect(character.modifier 4).toEqual -3 + + xit 'ability modifier for score 5 is -3', -> + expect(character.modifier 5).toEqual -3 + + xit 'ability modifier for score 6 is -2', -> + expect(character.modifier 6).toEqual -2 + + xit 'ability modifier for score 7 is -2', -> + expect(character.modifier 7).toEqual -2 + + xit 'ability modifier for score 8 is -1', -> + expect(character.modifier 8).toEqual -1 + + xit 'ability modifier for score 9 is -1', -> + expect(character.modifier 9).toEqual -1 + + xit 'ability modifier for score 10 is 0', -> + expect(character.modifier 10).toEqual 0 + + xit 'ability modifier for score 11 is 0', -> + expect(character.modifier 11).toEqual 0 + + xit 'ability modifier for score 12 is +1', -> + expect(character.modifier 12).toEqual 1 + + xit 'ability modifier for score 13 is +1', -> + expect(character.modifier 13).toEqual 1 + + xit 'ability modifier for score 14 is +2', -> + expect(character.modifier 14).toEqual 2 + + xit 'ability modifier for score 15 is +2', -> + expect(character.modifier 15).toEqual 2 + + xit 'ability modifier for score 16 is +3', -> + expect(character.modifier 16).toEqual 3 + + xit 'ability modifier for score 17 is +3', -> + expect(character.modifier 17).toEqual 3 + + xit 'ability modifier for score 18 is +4', -> + expect(character.modifier 18).toEqual 4 + + describe 'ability ->', -> + xit 'random ability is within range', -> + score = character.ability() + expect(score in [3..18]).toBeTrue + + xit 'random character is valid', -> + abilities = [ + character.strength + character.dexterity + character.constitution + character.intelligence + character.wisdom + character.charisma + ] + for ability in abilities + expect(ability in [3..18]).toBeTrue + expect(character.hitpoints).toEqual (10 + character.modifier(character.constitution)) + + xit 'each ability is only calculated once', -> + abilities = [ + character.strength + character.dexterity + character.constitution + character.intelligence + character.wisdom + character.charisma + ] + for ability in abilities + expect(ability).toEqual ability \ No newline at end of file