From b75d4e6719e705d1cc0ef90411a6c069cc573480 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Mon, 3 Apr 2023 14:07:52 +0200 Subject: [PATCH 01/17] Add difficulty as int, further format fn name --- bin/add_practice_exercise | 2 +- bin/generate_tests | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/bin/add_practice_exercise b/bin/add_practice_exercise index 056bd41b0..a9068e431 100755 --- a/bin/add_practice_exercise +++ b/bin/add_practice_exercise @@ -82,7 +82,7 @@ message "info" "Adding instructions and configuration files..." uuid=$(bin/configlet uuid) # Add exercise-data to global config.json -jq --arg slug "$slug" --arg uuid "$uuid" --arg name "$exercise_name" --arg difficulty "$exercise_difficulty" \ +jq --arg slug "$slug" --arg uuid "$uuid" --arg name "$exercise_name" --argjson difficulty "$exercise_difficulty" \ '.exercises.practice += [{slug: $slug, name: $name, uuid: $uuid, practices: [], prerequisites: [], difficulty: $difficulty}]' \ config.json >config.json.tmp # jq always rounds whole numbers, but average_run_time needs to be a float diff --git a/bin/generate_tests b/bin/generate_tests index fab91d3ce..4d2915ea1 100755 --- a/bin/generate_tests +++ b/bin/generate_tests @@ -1,10 +1,8 @@ #!/usr/bin/env bash - # Exit if anything fails. set -euo pipefail - # see comment in generator-utils/utils.sh # shellcheck source=bin/generator-utils/utils.sh # shellcheck source=./generator-utils/utils.sh @@ -35,7 +33,6 @@ EOT # Flattens canonical json, extracts only the objects with a uuid cases=$(echo "$canonical_json" | jq '[ .. | objects | with_entries(select(.key | IN("uuid", "description", "input", "expected", "property"))) | select(. != {}) | select(has("uuid")) ]') - # Shellcheck doesn't recognize that `case` is not unused # shellcheck disable=SC2034 @@ -45,9 +42,8 @@ jq -c '.[]' <<<"$cases" | while read -r case; do eval_template="$(digest_template | sed -e "s/\$(\(.*\))/\$\(\1\)/g")" eval_template="$(eval "echo \"$eval_template\"")" - # Turn function name into snake_case - formatted_template=$(echo "$eval_template" | sed -e ':loop' -e 's/\(fn[^(]*\)[ -]/\1_/g' -e 't loop' | sed 's/fn_/fn /') + formatted_template=$(echo "$eval_template" | sed -E -e '/^fn/!b' -e 's/[^a-zA-Z0-9_{}()[:space:]]//g' -e 's/([[:upper:]])/ \L\1/g' -e 's/(fn[[:space:]]+)([a-z0-9_]+)/\1\L\2/g' -e 's/ /_/g' -e 's/_\{/\{/g' | sed 's/fn_/fn /' | sed 's/__\+/_/g') # Push to test file echo "$formatted_template" >>"$test_file" @@ -58,4 +54,3 @@ done rustfmt "$test_file" message "success" "Generated tests successfully! Check out ${test_file}" - From 62570bb1763fde5155bd116f09fedf3fe1562a8c Mon Sep 17 00:00:00 2001 From: dem4ron Date: Mon, 3 Apr 2023 16:35:11 +0200 Subject: [PATCH 02/17] Add util fn to escape double quotes --- .gitignore | 1 + bin/generate_tests | 9 +++-- bin/test_template | 5 ++- util/escape_double_quotes/Cargo.lock | 7 ++++ util/escape_double_quotes/Cargo.toml | 8 +++++ util/escape_double_quotes/build | 2 ++ util/escape_double_quotes/src/lib.rs | 2 ++ util/escape_double_quotes/src/main.rs | 30 ++++++++++++++++ .../src/utils/escape_double_quotes.rs | 22 ++++++++++++ util/escape_double_quotes/src/utils/mod.rs | 1 + util/escape_double_quotes/tests/test.rs | 36 +++++++++++++++++++ 11 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 util/escape_double_quotes/Cargo.lock create mode 100644 util/escape_double_quotes/Cargo.toml create mode 100755 util/escape_double_quotes/build create mode 100644 util/escape_double_quotes/src/lib.rs create mode 100644 util/escape_double_quotes/src/main.rs create mode 100644 util/escape_double_quotes/src/utils/escape_double_quotes.rs create mode 100644 util/escape_double_quotes/src/utils/mod.rs create mode 100644 util/escape_double_quotes/tests/test.rs diff --git a/.gitignore b/.gitignore index 8f4f224b4..edfd68168 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ bin/configlet.exe bin/exercise bin/exercise.exe bin/generator-utils/ngram +bin/generator-utils/escape_double_quotes exercises/*/*/Cargo.lock exercises/*/*/clippy.log canonical_data.json diff --git a/bin/generate_tests b/bin/generate_tests index 4d2915ea1..1065148a2 100755 --- a/bin/generate_tests +++ b/bin/generate_tests @@ -8,9 +8,14 @@ set -euo pipefail # shellcheck source=./generator-utils/utils.sh source ./bin/generator-utils/utils.sh +if [ ! -e bin/generator-utils/escape_double_quotes ]; then + message "info" "Building util function" + cd util/escape_double_quotes && ./build && cd ../.. +fi + digest_template() { local template - template=$(cat bin/test_template) + template=$(bin/generator-utils/escape_double_quotes bin/test_template) # Turn every token into a jq command echo "$template" | sed 's/${\([^}]*\)\}\$/$(echo $case | jq -r '\''.\1'\'')/g' @@ -43,7 +48,7 @@ jq -c '.[]' <<<"$cases" | while read -r case; do eval_template="$(eval "echo \"$eval_template\"")" # Turn function name into snake_case - formatted_template=$(echo "$eval_template" | sed -E -e '/^fn/!b' -e 's/[^a-zA-Z0-9_{}()[:space:]]//g' -e 's/([[:upper:]])/ \L\1/g' -e 's/(fn[[:space:]]+)([a-z0-9_]+)/\1\L\2/g' -e 's/ /_/g' -e 's/_\{/\{/g' | sed 's/fn_/fn /' | sed 's/__\+/_/g') + formatted_template=$(echo "$eval_template" | sed -E -e '/^fn/!b' -e 's/[^a-zA-Z0-9_{}()[:space:]-]//g' -e 's/([[:upper:]])/ \L\1/g' -e 's/(fn[[:space:]]+)([a-z0-9_-]+)/\1\L\2/g' -e 's/ /_/g' -e 's/_\{/\{/g' -e 's/-/_/g' | sed 's/fn_/fn /' | sed 's/__\+/_/g') # Push to test file echo "$formatted_template" >>"$test_file" diff --git a/bin/test_template b/bin/test_template index ad458d212..67371d1ec 100644 --- a/bin/test_template +++ b/bin/test_template @@ -1,7 +1,6 @@ #[test] #[ignore] fn ${description}$() { - - assert_eq!(${property}$(${input}$), ${expected}$); +let expected = vec!${expected}$; + assert_eq!(${property}$(${input.startVerse}$, ${input.endVerse}$), expected); } - diff --git a/util/escape_double_quotes/Cargo.lock b/util/escape_double_quotes/Cargo.lock new file mode 100644 index 000000000..54ec08296 --- /dev/null +++ b/util/escape_double_quotes/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "escape_double_quotes" +version = "0.1.0" diff --git a/util/escape_double_quotes/Cargo.toml b/util/escape_double_quotes/Cargo.toml new file mode 100644 index 000000000..c61c6ddbc --- /dev/null +++ b/util/escape_double_quotes/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "escape_double_quotes" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/util/escape_double_quotes/build b/util/escape_double_quotes/build new file mode 100755 index 000000000..b74a56633 --- /dev/null +++ b/util/escape_double_quotes/build @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +cargo build --release --quiet && cp ./target/release/escape_double_quotes ../../bin/generator-utils && rm -rf ./target diff --git a/util/escape_double_quotes/src/lib.rs b/util/escape_double_quotes/src/lib.rs new file mode 100644 index 000000000..e91f3a79b --- /dev/null +++ b/util/escape_double_quotes/src/lib.rs @@ -0,0 +1,2 @@ +pub mod utils; +pub use utils::escape_double_quotes::*; diff --git a/util/escape_double_quotes/src/main.rs b/util/escape_double_quotes/src/main.rs new file mode 100644 index 000000000..3890e92bf --- /dev/null +++ b/util/escape_double_quotes/src/main.rs @@ -0,0 +1,30 @@ +use std::env; +use std::fs::File; +use std::io::{self, BufRead, BufReader, BufWriter, Write}; +mod utils; +use utils::escape_double_quotes::*; + + +fn main() -> io::Result<()> { + let args: Vec = env::args().collect(); + if args.len() != 2 { + eprintln!("Usage: {} ", args[0]); + std::process::exit(1); + } + + let file_path = &args[1]; + let file = File::open(file_path)?; + let reader = BufReader::new(file); + + let stdout = io::stdout(); + let mut writer = BufWriter::new(stdout.lock()); + + for line in reader.lines() { + let input = line?; + let output = escape_double_quotes(&input); + writeln!(writer, "{}", output)?; + } + + Ok(()) +} + diff --git a/util/escape_double_quotes/src/utils/escape_double_quotes.rs b/util/escape_double_quotes/src/utils/escape_double_quotes.rs new file mode 100644 index 000000000..1dbf0b72c --- /dev/null +++ b/util/escape_double_quotes/src/utils/escape_double_quotes.rs @@ -0,0 +1,22 @@ +pub fn escape_double_quotes(input: &str) -> String { + let mut output = String::new(); + let mut brace_type = None; + + let mut chars = input.chars().peekable(); + while let Some(char) = chars.next() { + match char { + '$' if chars.peek() == Some(&'{') => { + brace_type = Some("${"); + output.push(char) + } + '}' if chars.peek() == Some(&'$') => { + brace_type = Some("}$"); + output.push(char) + } + '"' if brace_type == Some("}$") || brace_type == None => output.push_str("\\\""), + _ => output.push(char), + } + } + + output +} diff --git a/util/escape_double_quotes/src/utils/mod.rs b/util/escape_double_quotes/src/utils/mod.rs new file mode 100644 index 000000000..cf976c6d6 --- /dev/null +++ b/util/escape_double_quotes/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod escape_double_quotes; \ No newline at end of file diff --git a/util/escape_double_quotes/tests/test.rs b/util/escape_double_quotes/tests/test.rs new file mode 100644 index 000000000..99e82935e --- /dev/null +++ b/util/escape_double_quotes/tests/test.rs @@ -0,0 +1,36 @@ +use escape_double_quotes::utils::escape_double_quotes::escape_double_quotes; + +#[test] +fn test_no_double_quotes() { + let input = "let x = 5;"; + let expected = "let x = 5;"; + assert_eq!(escape_double_quotes(input), expected); +} + +#[test] +fn test_simple_double_quotes() { + let input = "let something = \"string\";"; + let expected = "let something = \\\"string\\\";"; + assert_eq!(escape_double_quotes(input), expected); +} + +#[test] +fn test_braces_with_double_quotes() { + let input = "let expected = \"${expected | join(\\\"\\n\\\")}$\";"; + let expected = "let expected = \\\"${expected | join(\\\"\\n\\\")}$\\\";"; + assert_eq!(escape_double_quotes(input), expected); +} + +#[test] +fn test_mixed_double_quotes() { + let input = "let a = \"value\"; let b = \"${value | filter(\\\"text\\\")}$\";"; + let expected = "let a = \\\"value\\\"; let b = \\\"${value | filter(\\\"text\\\")}$\\\";"; + assert_eq!(escape_double_quotes(input), expected); +} + +#[test] +fn test_nested_braces() { + let input = "let nested = \"${outer {inner | escape(\\\"\\n\\\")}}$\";"; + let expected = "let nested = \\\"${outer {inner | escape(\\\"\\n\\\")}}$\\\";"; + assert_eq!(escape_double_quotes(input), expected); +} From 88fb1c44c2c83b0cd601ef5a42f943be44e3785e Mon Sep 17 00:00:00 2001 From: dem4ron Date: Mon, 3 Apr 2023 17:40:21 +0200 Subject: [PATCH 03/17] Simplify escape double quotes algo --- bin/test_template | 4 ++-- .../src/utils/escape_double_quotes.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/test_template b/bin/test_template index 67371d1ec..93b513457 100644 --- a/bin/test_template +++ b/bin/test_template @@ -1,6 +1,6 @@ #[test] #[ignore] fn ${description}$() { -let expected = vec!${expected}$; - assert_eq!(${property}$(${input.startVerse}$, ${input.endVerse}$), expected); +let expected = "${expected}$"; + assert_eq!(${property}$(${input}$), expected); } diff --git a/util/escape_double_quotes/src/utils/escape_double_quotes.rs b/util/escape_double_quotes/src/utils/escape_double_quotes.rs index 1dbf0b72c..83fb7b907 100644 --- a/util/escape_double_quotes/src/utils/escape_double_quotes.rs +++ b/util/escape_double_quotes/src/utils/escape_double_quotes.rs @@ -1,19 +1,19 @@ pub fn escape_double_quotes(input: &str) -> String { let mut output = String::new(); - let mut brace_type = None; + let mut escape = true; let mut chars = input.chars().peekable(); while let Some(char) = chars.next() { match char { '$' if chars.peek() == Some(&'{') => { - brace_type = Some("${"); + escape = false; output.push(char) } '}' if chars.peek() == Some(&'$') => { - brace_type = Some("}$"); + escape = true; output.push(char) } - '"' if brace_type == Some("}$") || brace_type == None => output.push_str("\\\""), + '"' if escape => output.push_str("\\\""), _ => output.push(char), } } From a93d31a3a52a0ae2b2b092896db872c935d7369d Mon Sep 17 00:00:00 2001 From: dem4ron Date: Mon, 3 Apr 2023 17:46:30 +0200 Subject: [PATCH 04/17] Add missing end line --- util/escape_double_quotes/src/utils/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/escape_double_quotes/src/utils/mod.rs b/util/escape_double_quotes/src/utils/mod.rs index cf976c6d6..a352b9aaf 100644 --- a/util/escape_double_quotes/src/utils/mod.rs +++ b/util/escape_double_quotes/src/utils/mod.rs @@ -1 +1 @@ -pub mod escape_double_quotes; \ No newline at end of file +pub mod escape_double_quotes; From 912b761cd376426633d9c7297edddaf0f89f008b Mon Sep 17 00:00:00 2001 From: dem4ron Date: Tue, 4 Apr 2023 12:18:29 +0200 Subject: [PATCH 05/17] Add dnd character exercise --- config.json | 9 + .../dnd-character/.docs/instructions.md | 31 +++ exercises/practice/dnd-character/.gitignore | 8 + .../practice/dnd-character/.meta/config.json | 20 ++ .../practice/dnd-character/.meta/example.rs | 75 +++++++ .../practice/dnd-character/.meta/tests.toml | 67 +++++++ exercises/practice/dnd-character/Cargo.toml | 9 + exercises/practice/dnd-character/src/lib.rs | 47 +++++ .../dnd-character/tests/dnd-character.rs | 184 ++++++++++++++++++ 9 files changed, 450 insertions(+) create mode 100644 exercises/practice/dnd-character/.docs/instructions.md create mode 100644 exercises/practice/dnd-character/.gitignore create mode 100644 exercises/practice/dnd-character/.meta/config.json create mode 100644 exercises/practice/dnd-character/.meta/example.rs create mode 100644 exercises/practice/dnd-character/.meta/tests.toml create mode 100644 exercises/practice/dnd-character/Cargo.toml create mode 100644 exercises/practice/dnd-character/src/lib.rs create mode 100644 exercises/practice/dnd-character/tests/dnd-character.rs diff --git a/config.json b/config.json index 63a7dc83a..bb4ea2813 100644 --- a/config.json +++ b/config.json @@ -1507,6 +1507,15 @@ "strings" ], "status": "deprecated" + }, + { + "slug": "dnd-character", + "name": "D&D Character", + "uuid": "8f52127a-ad81-46a2-b734-a76117138aae", + "practices": [], + "prerequisites": [], + "difficulty": 1, + "topics":["structs", "randomness"] } ], "foregone": [ diff --git a/exercises/practice/dnd-character/.docs/instructions.md b/exercises/practice/dnd-character/.docs/instructions.md new file mode 100644 index 000000000..b0a603591 --- /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/.gitignore b/exercises/practice/dnd-character/.gitignore new file mode 100644 index 000000000..e24ae5981 --- /dev/null +++ b/exercises/practice/dnd-character/.gitignore @@ -0,0 +1,8 @@ +# Generated by Cargo +# Will have compiled files and executables +/target/ +**/*.rs.bk + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock +Cargo.lock diff --git a/exercises/practice/dnd-character/.meta/config.json b/exercises/practice/dnd-character/.meta/config.json new file mode 100644 index 000000000..592afd784 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/config.json @@ -0,0 +1,20 @@ +{ + "authors": [ + "dem4ron" + ], + "files": { + "solution": [ + "src/lib.rs", + "Cargo.toml" + ], + "test": [ + "tests/dnd-character.rs" + ], + "example": [ + ".meta/example.rs" + ] + }, + "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.rs b/exercises/practice/dnd-character/.meta/example.rs new file mode 100644 index 000000000..a4ed5976e --- /dev/null +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -0,0 +1,75 @@ +use rand::prelude::*; + +pub fn modifier(ability_score: u8) -> f32 { + ((ability_score as i8 - 10) as f32 / 2.0).floor() +} + +pub struct Character { + strength: u8, + dexterity: u8, + constitution: u8, + intelligence: u8, + wisdom: u8, + charisma: u8, + hitpoints: u8, +} + +impl Character { + pub fn new() -> Self { + let constitution = Character::calculate_ability_score(Character::roll_four_dices()); + Character { + strength: Character::calculate_ability_score(Character::roll_four_dices()), + dexterity: Character::calculate_ability_score(Character::roll_four_dices()), + constitution, + intelligence: Character::calculate_ability_score(Character::roll_four_dices()), + wisdom: Character::calculate_ability_score(Character::roll_four_dices()), + charisma: Character::calculate_ability_score(Character::roll_four_dices()), + hitpoints: 10 + modifier(constitution) as u8, + } + } + + pub fn roll_four_dices() -> [u8; 4] { + let mut rng = thread_rng(); + let mut rolls = [0; 4]; + for i in 0..4 { + rolls[i] = rng.gen_range(1..=4) + } + rolls + } + + pub fn calculate_ability_score(dices: [u8; 4]) -> u8 { + let mut dices = dices; + dices.sort(); + dices[1..].iter().sum() + } + + pub fn strength(&self) -> u8 { + self.strength + } + + pub fn dexterity(&self) -> u8 { + self.dexterity + } + + pub fn constitution(&self) -> u8 { + self.constitution + } + + pub fn intelligence(&self) -> u8 { + self.intelligence + } + + pub fn wisdom(&self) -> u8 { + self.wisdom + } + + pub fn charisma(&self) -> u8 { + self.charisma + } + + pub fn hitpoints(&self) -> u8 { + self.hitpoints + } +} + + diff --git a/exercises/practice/dnd-character/.meta/tests.toml b/exercises/practice/dnd-character/.meta/tests.toml new file mode 100644 index 000000000..2b04dd335 --- /dev/null +++ b/exercises/practice/dnd-character/.meta/tests.toml @@ -0,0 +1,67 @@ +# 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" diff --git a/exercises/practice/dnd-character/Cargo.toml b/exercises/practice/dnd-character/Cargo.toml new file mode 100644 index 000000000..8880f3b60 --- /dev/null +++ b/exercises/practice/dnd-character/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dnd_character" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.5" \ No newline at end of file diff --git a/exercises/practice/dnd-character/src/lib.rs b/exercises/practice/dnd-character/src/lib.rs new file mode 100644 index 000000000..563e4b744 --- /dev/null +++ b/exercises/practice/dnd-character/src/lib.rs @@ -0,0 +1,47 @@ +pub fn modifier(_ability_score: u8) -> f32 { + unimplemented!("Implement a utility function that calculates the ability modifier for a given ability score") +} + +pub struct Character {} + +impl Character { + pub fn new() -> Self { + unimplemented!("Create a function that generates a new random character with the following ability scores and hitpoints") + } + + pub fn roll_four_dices() -> [u8; 4] { + unimplemented!("Create a utility function that rolls four dices") + } + + pub fn calculate_ability_score(_dices: [u8; 4]) -> u8 { + unimplemented!("Calculate the ability score from the given rolled dices") + } + + pub fn strength(&self) -> u8 { + unimplemented!("Return the strength score of the character") + } + + pub fn dexterity(&self) -> u8 { + unimplemented!("Return the dexterity score of the character") + } + + pub fn constitution(&self) -> u8 { + unimplemented!("Return the constitution score of the character") + } + + pub fn intelligence(&self) -> u8 { + unimplemented!("Return the intelligence score of the character") + } + + pub fn wisdom(&self) -> u8 { + unimplemented!("Return the wisdom score of the character") + } + + pub fn charisma(&self) -> u8 { + unimplemented!("Return the charisma score of the character") + } + + pub fn hitpoints(&self) -> u8 { + unimplemented!("Return the hitpoints of the character") + } +} diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs new file mode 100644 index 000000000..5fda338f8 --- /dev/null +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -0,0 +1,184 @@ +use dnd_character::*; + +#[test] +#[ignore] +fn test_ability_modifier_for_score_3_is_4() { + let input = 3; + let expected: f32 = -4.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_4_is_3() { + let input = 4; + let expected: f32 = -3.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_5_is_3() { + let input = 5; + let expected: f32 = -3.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_6_is_2() { + let input = 6; + let expected: f32 = -2.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_7_is_2() { + let input = 7; + let expected: f32 = -2.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_8_is_1() { + let input = 8; + let expected: f32 = -1.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_9_is_1() { + let input = 9; + let expected: f32 = -1.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_10_is_0() { + let input = 10; + let expected: f32 = 0.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_11_is_0() { + let input = 11; + let expected: f32 = 0.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_12_is_1() { + let input = 12; + let expected: f32 = 1.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_13_is_1() { + let input = 13; + let expected: f32 = 1.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_14_is_2() { + let input = 14; + let expected: f32 = 2.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_15_is_2() { + let input = 15; + let expected: f32 = 2.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_16_is_3() { + let input = 16; + let expected: f32 = 3.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_17_is_3() { + let input = 17; + let expected: f32 = 3.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_ability_modifier_for_score_18_is_4() { + let input = 18; + let expected: f32 = 4.0; + assert_eq!(modifier(input), expected); +} + +#[test] +#[ignore] +fn test_random_ability_is_within_range() { + let score = Character::calculate_ability_score(Character::roll_four_dices()); + assert!(score >= 3 && score <= 18); +} + +#[test] +#[ignore] +fn test_random_character_is_valid() { + let character = Character::new(); + assert!(character.strength() >= 3 && character.strength() <= 18); + assert!(character.dexterity() >= 3 && character.dexterity() <= 18); + assert!(character.constitution() >= 3 && character.constitution() <= 18); + assert!(character.intelligence() >= 3 && character.intelligence() <= 18); + assert!(character.wisdom() >= 3 && character.wisdom() <= 18); + assert!(character.charisma() >= 3 && character.charisma() <= 18); + assert_eq!( + character.hitpoints(), + 10 + modifier(character.constitution()) as u8 + ); +} + +#[test] +#[ignore] +fn test_dices_are_rolled_for_each_stat() { + // there is a low chance that this might be equal + let character = Character::new(); + assert_ne!( + ( + character.strength(), + character.dexterity(), + character.constitution(), + character.intelligence(), + character.wisdom(), + character.charisma() + ), + ( + character.strength(), + character.strength(), + character.strength(), + character.strength(), + character.strength(), + character.strength() + ) + ); +} + +#[test] +#[ignore] +fn test_each_ability_is_only_calculated_once() { + let character = Character::new(); + assert!(character.strength() == character.strength()); +} From 23bbd89dd8011a51d2ea385e87e7ed92fe07c095 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 20:28:43 +0200 Subject: [PATCH 06/17] Change wording --- .../practice/dnd-character/.meta/example.rs | 22 +++++++++---------- exercises/practice/dnd-character/src/lib.rs | 8 +++---- .../dnd-character/tests/dnd-character.rs | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index a4ed5976e..7ac355590 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -16,19 +16,19 @@ pub struct Character { impl Character { pub fn new() -> Self { - let constitution = Character::calculate_ability_score(Character::roll_four_dices()); + let constitution = Character::calculate_ability_score(Character::roll_four_dice()); Character { - strength: Character::calculate_ability_score(Character::roll_four_dices()), - dexterity: Character::calculate_ability_score(Character::roll_four_dices()), + strength: Character::calculate_ability_score(Character::roll_four_dice()), + dexterity: Character::calculate_ability_score(Character::roll_four_dice()), constitution, - intelligence: Character::calculate_ability_score(Character::roll_four_dices()), - wisdom: Character::calculate_ability_score(Character::roll_four_dices()), - charisma: Character::calculate_ability_score(Character::roll_four_dices()), + intelligence: Character::calculate_ability_score(Character::roll_four_dice()), + wisdom: Character::calculate_ability_score(Character::roll_four_dice()), + charisma: Character::calculate_ability_score(Character::roll_four_dice()), hitpoints: 10 + modifier(constitution) as u8, } } - pub fn roll_four_dices() -> [u8; 4] { + pub fn roll_four_dice() -> [u8; 4] { let mut rng = thread_rng(); let mut rolls = [0; 4]; for i in 0..4 { @@ -37,10 +37,10 @@ impl Character { rolls } - pub fn calculate_ability_score(dices: [u8; 4]) -> u8 { - let mut dices = dices; - dices.sort(); - dices[1..].iter().sum() + pub fn calculate_ability_score(dice: [u8; 4]) -> u8 { + let mut dice = dice; + dice.sort(); + dice[1..].iter().sum() } pub fn strength(&self) -> u8 { diff --git a/exercises/practice/dnd-character/src/lib.rs b/exercises/practice/dnd-character/src/lib.rs index 563e4b744..6eb1abdab 100644 --- a/exercises/practice/dnd-character/src/lib.rs +++ b/exercises/practice/dnd-character/src/lib.rs @@ -9,12 +9,12 @@ impl Character { unimplemented!("Create a function that generates a new random character with the following ability scores and hitpoints") } - pub fn roll_four_dices() -> [u8; 4] { - unimplemented!("Create a utility function that rolls four dices") + pub fn roll_four_dice() -> [u8; 4] { + unimplemented!("Create a utility function that rolls four dice") } - pub fn calculate_ability_score(_dices: [u8; 4]) -> u8 { - unimplemented!("Calculate the ability score from the given rolled dices") + pub fn calculate_ability_score(_dice: [u8; 4]) -> u8 { + unimplemented!("Calculate the ability score from the given rolled dice") } pub fn strength(&self) -> u8 { diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index 5fda338f8..21882c453 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -131,7 +131,7 @@ fn test_ability_modifier_for_score_18_is_4() { #[test] #[ignore] fn test_random_ability_is_within_range() { - let score = Character::calculate_ability_score(Character::roll_four_dices()); + let score = Character::calculate_ability_score(Character::roll_four_dice()); assert!(score >= 3 && score <= 18); } @@ -153,7 +153,7 @@ fn test_random_character_is_valid() { #[test] #[ignore] -fn test_dices_are_rolled_for_each_stat() { +fn test_dice_are_rolled_for_each_stat() { // there is a low chance that this might be equal let character = Character::new(); assert_ne!( From 81fce76ed17d4c77796b4d47ce05a68cd4b4b921 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 20:32:25 +0200 Subject: [PATCH 07/17] Remove first ignore --- exercises/practice/dnd-character/tests/dnd-character.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index 21882c453..a9fb26253 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -1,7 +1,6 @@ use dnd_character::*; #[test] -#[ignore] fn test_ability_modifier_for_score_3_is_4() { let input = 3; let expected: f32 = -4.0; From f49433e4ae10f532d47a76abcf0ccbf39a75964d Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 20:34:34 +0200 Subject: [PATCH 08/17] Format example, improve one test --- exercises/practice/dnd-character/.meta/example.rs | 2 -- exercises/practice/dnd-character/tests/dnd-character.rs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index 7ac355590..d00b6de69 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -71,5 +71,3 @@ impl Character { self.hitpoints } } - - diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index a9fb26253..ae75923f1 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -131,7 +131,7 @@ fn test_ability_modifier_for_score_18_is_4() { #[ignore] fn test_random_ability_is_within_range() { let score = Character::calculate_ability_score(Character::roll_four_dice()); - assert!(score >= 3 && score <= 18); + assert!((3..=18).contains(&score)); } #[test] From 20f9f838185c4fe866d7b3becf2d0ba05a912bec Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 21:51:48 +0200 Subject: [PATCH 09/17] Better parameters --- exercises/practice/dnd-character/.meta/example.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index d00b6de69..a7cddab9b 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -37,10 +37,10 @@ impl Character { rolls } - pub fn calculate_ability_score(dice: [u8; 4]) -> u8 { - let mut dice = dice; - dice.sort(); - dice[1..].iter().sum() + pub fn calculate_ability_score(ability_dice_rolls: [u8; 4]) -> u8 { + let mut ability_dice_rolls = ability_dice_rolls; + ability_dice_rolls.sort(); + ability_dice_rolls[1..].iter().sum() } pub fn strength(&self) -> u8 { From 004db4609f5b8b41c9e2a3c9e766c73193090b2f Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 21:56:57 +0200 Subject: [PATCH 10/17] Same for stub file --- exercises/practice/dnd-character/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/dnd-character/src/lib.rs b/exercises/practice/dnd-character/src/lib.rs index 6eb1abdab..27af25a88 100644 --- a/exercises/practice/dnd-character/src/lib.rs +++ b/exercises/practice/dnd-character/src/lib.rs @@ -13,7 +13,7 @@ impl Character { unimplemented!("Create a utility function that rolls four dice") } - pub fn calculate_ability_score(_dice: [u8; 4]) -> u8 { + pub fn calculate_ability_score(_ability_dice_rolls: [u8; 4]) -> u8 { unimplemented!("Calculate the ability score from the given rolled dice") } From 2e25f85d2aa35408378541d57a4e2bc51936b5e8 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Wed, 5 Apr 2023 22:04:24 +0200 Subject: [PATCH 11/17] Improve valid char test case --- .../practice/dnd-character/tests/dnd-character.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index ae75923f1..ccb8ec6c8 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -138,12 +138,12 @@ fn test_random_ability_is_within_range() { #[ignore] fn test_random_character_is_valid() { let character = Character::new(); - assert!(character.strength() >= 3 && character.strength() <= 18); - assert!(character.dexterity() >= 3 && character.dexterity() <= 18); - assert!(character.constitution() >= 3 && character.constitution() <= 18); - assert!(character.intelligence() >= 3 && character.intelligence() <= 18); - assert!(character.wisdom() >= 3 && character.wisdom() <= 18); - assert!(character.charisma() >= 3 && character.charisma() <= 18); + assert!((3..=18).contains(&character.strength())); + assert!((3..=18).contains(&character.dexterity())); + assert!((3..=18).contains(&character.constitution())); + assert!((3..=18).contains(&character.intelligence())); + assert!((3..=18).contains(&character.wisdom())); + assert!((3..=18).contains(&character.charisma())); assert_eq!( character.hitpoints(), 10 + modifier(character.constitution()) as u8 From c2bdc3b95e38f4f78c741f7d728b7c27d5811b2b Mon Sep 17 00:00:00 2001 From: dem4ron Date: Fri, 7 Apr 2023 14:07:38 +0200 Subject: [PATCH 12/17] Improve exemplar solution --- .../practice/dnd-character/.meta/example.rs | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index a7cddab9b..e4ed1d2e2 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -14,6 +14,14 @@ pub struct Character { hitpoints: u8, } +macro_rules! get_attribute { + ($name:ident) => { + pub fn $name(&self) -> u8 { + self.$name + } + }; +} + impl Character { pub fn new() -> Self { let constitution = Character::calculate_ability_score(Character::roll_four_dice()); @@ -43,31 +51,11 @@ impl Character { ability_dice_rolls[1..].iter().sum() } - pub fn strength(&self) -> u8 { - self.strength - } - - pub fn dexterity(&self) -> u8 { - self.dexterity - } - - pub fn constitution(&self) -> u8 { - self.constitution - } - - pub fn intelligence(&self) -> u8 { - self.intelligence - } - - pub fn wisdom(&self) -> u8 { - self.wisdom - } - - pub fn charisma(&self) -> u8 { - self.charisma - } - - pub fn hitpoints(&self) -> u8 { - self.hitpoints - } + get_attribute!(strength); + get_attribute!(dexterity); + get_attribute!(constitution); + get_attribute!(intelligence); + get_attribute!(wisdom); + get_attribute!(charisma); + get_attribute!(hitpoints); } From 2d994776d64accd91a20ffda3fd17465bfd77d13 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Fri, 7 Apr 2023 14:35:16 +0200 Subject: [PATCH 13/17] Rename macro --- .../practice/dnd-character/.meta/example.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index e4ed1d2e2..7e4c08b84 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -14,7 +14,7 @@ pub struct Character { hitpoints: u8, } -macro_rules! get_attribute { +macro_rules! create_getter_for { ($name:ident) => { pub fn $name(&self) -> u8 { self.$name @@ -51,11 +51,11 @@ impl Character { ability_dice_rolls[1..].iter().sum() } - get_attribute!(strength); - get_attribute!(dexterity); - get_attribute!(constitution); - get_attribute!(intelligence); - get_attribute!(wisdom); - get_attribute!(charisma); - get_attribute!(hitpoints); + create_getter_for!(strength); + create_getter_for!(dexterity); + create_getter_for!(constitution); + create_getter_for!(intelligence); + create_getter_for!(wisdom); + create_getter_for!(charisma); + create_getter_for!(hitpoints); } From 5ac82f2cf2a4216f34e11afc4b927b081415fa3a Mon Sep 17 00:00:00 2001 From: dem4ron Date: Fri, 7 Apr 2023 14:39:00 +0200 Subject: [PATCH 14/17] Improve last test, add missing end line --- exercises/practice/dnd-character/Cargo.toml | 2 +- exercises/practice/dnd-character/tests/dnd-character.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/practice/dnd-character/Cargo.toml b/exercises/practice/dnd-character/Cargo.toml index 8880f3b60..cd42fb7c2 100644 --- a/exercises/practice/dnd-character/Cargo.toml +++ b/exercises/practice/dnd-character/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index ccb8ec6c8..6e5c4fd6f 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -179,5 +179,5 @@ fn test_dice_are_rolled_for_each_stat() { #[ignore] fn test_each_ability_is_only_calculated_once() { let character = Character::new(); - assert!(character.strength() == character.strength()); + assert_eq!(character.strength(), character.strength()); } From 5ec087e97410ba45b35d4f29caa070ba6e161a77 Mon Sep 17 00:00:00 2001 From: dem4ron Date: Fri, 7 Apr 2023 22:35:20 +0200 Subject: [PATCH 15/17] Simplify exercise --- .../practice/dnd-character/.meta/example.rs | 16 ------- exercises/practice/dnd-character/src/lib.rs | 28 ------------- .../dnd-character/tests/dnd-character.rs | 42 +++++++++---------- 3 files changed, 21 insertions(+), 65 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index 7e4c08b84..f9bcc62e0 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -14,14 +14,6 @@ pub struct Character { hitpoints: u8, } -macro_rules! create_getter_for { - ($name:ident) => { - pub fn $name(&self) -> u8 { - self.$name - } - }; -} - impl Character { pub fn new() -> Self { let constitution = Character::calculate_ability_score(Character::roll_four_dice()); @@ -50,12 +42,4 @@ impl Character { ability_dice_rolls.sort(); ability_dice_rolls[1..].iter().sum() } - - create_getter_for!(strength); - create_getter_for!(dexterity); - create_getter_for!(constitution); - create_getter_for!(intelligence); - create_getter_for!(wisdom); - create_getter_for!(charisma); - create_getter_for!(hitpoints); } diff --git a/exercises/practice/dnd-character/src/lib.rs b/exercises/practice/dnd-character/src/lib.rs index 27af25a88..ee729216f 100644 --- a/exercises/practice/dnd-character/src/lib.rs +++ b/exercises/practice/dnd-character/src/lib.rs @@ -16,32 +16,4 @@ impl Character { pub fn calculate_ability_score(_ability_dice_rolls: [u8; 4]) -> u8 { unimplemented!("Calculate the ability score from the given rolled dice") } - - pub fn strength(&self) -> u8 { - unimplemented!("Return the strength score of the character") - } - - pub fn dexterity(&self) -> u8 { - unimplemented!("Return the dexterity score of the character") - } - - pub fn constitution(&self) -> u8 { - unimplemented!("Return the constitution score of the character") - } - - pub fn intelligence(&self) -> u8 { - unimplemented!("Return the intelligence score of the character") - } - - pub fn wisdom(&self) -> u8 { - unimplemented!("Return the wisdom score of the character") - } - - pub fn charisma(&self) -> u8 { - unimplemented!("Return the charisma score of the character") - } - - pub fn hitpoints(&self) -> u8 { - unimplemented!("Return the hitpoints of the character") - } } diff --git a/exercises/practice/dnd-character/tests/dnd-character.rs b/exercises/practice/dnd-character/tests/dnd-character.rs index 6e5c4fd6f..9248c1df6 100644 --- a/exercises/practice/dnd-character/tests/dnd-character.rs +++ b/exercises/practice/dnd-character/tests/dnd-character.rs @@ -138,15 +138,15 @@ fn test_random_ability_is_within_range() { #[ignore] fn test_random_character_is_valid() { let character = Character::new(); - assert!((3..=18).contains(&character.strength())); - assert!((3..=18).contains(&character.dexterity())); - assert!((3..=18).contains(&character.constitution())); - assert!((3..=18).contains(&character.intelligence())); - assert!((3..=18).contains(&character.wisdom())); - assert!((3..=18).contains(&character.charisma())); + assert!((3..=18).contains(&character.strength)); + assert!((3..=18).contains(&character.dexterity)); + assert!((3..=18).contains(&character.constitution)); + assert!((3..=18).contains(&character.intelligence)); + assert!((3..=18).contains(&character.wisdom)); + assert!((3..=18).contains(&character.charisma)); assert_eq!( - character.hitpoints(), - 10 + modifier(character.constitution()) as u8 + character.hitpoints, + 10 + modifier(character.constitution) as u8 ); } @@ -157,20 +157,20 @@ fn test_dice_are_rolled_for_each_stat() { let character = Character::new(); assert_ne!( ( - character.strength(), - character.dexterity(), - character.constitution(), - character.intelligence(), - character.wisdom(), - character.charisma() + character.strength, + character.dexterity, + character.constitution, + character.intelligence, + character.wisdom, + character.charisma ), ( - character.strength(), - character.strength(), - character.strength(), - character.strength(), - character.strength(), - character.strength() + character.strength, + character.strength, + character.strength, + character.strength, + character.strength, + character.strength ) ); } @@ -179,5 +179,5 @@ fn test_dice_are_rolled_for_each_stat() { #[ignore] fn test_each_ability_is_only_calculated_once() { let character = Character::new(); - assert_eq!(character.strength(), character.strength()); + assert_eq!(character.strength, character.strength); } From 82e2081eb2ae187d733d854f70b58255a49a0a5f Mon Sep 17 00:00:00 2001 From: dem4ron Date: Fri, 7 Apr 2023 23:03:39 +0200 Subject: [PATCH 16/17] Fill in struct details in stub file --- exercises/practice/dnd-character/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/exercises/practice/dnd-character/src/lib.rs b/exercises/practice/dnd-character/src/lib.rs index ee729216f..e3bd995ac 100644 --- a/exercises/practice/dnd-character/src/lib.rs +++ b/exercises/practice/dnd-character/src/lib.rs @@ -2,7 +2,15 @@ pub fn modifier(_ability_score: u8) -> f32 { unimplemented!("Implement a utility function that calculates the ability modifier for a given ability score") } -pub struct Character {} +pub struct Character { + pub strength: u8, + pub dexterity: u8, + pub constitution: u8, + pub intelligence: u8, + pub wisdom: u8, + pub charisma: u8, + pub hitpoints: u8, +} impl Character { pub fn new() -> Self { From 133617048280ae14603dcaaf631f2a73512d684d Mon Sep 17 00:00:00 2001 From: dem4ron Date: Sat, 8 Apr 2023 13:39:57 +0200 Subject: [PATCH 17/17] Fix exemplar's struct --- exercises/practice/dnd-character/.meta/example.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exercises/practice/dnd-character/.meta/example.rs b/exercises/practice/dnd-character/.meta/example.rs index f9bcc62e0..6c1ce8909 100644 --- a/exercises/practice/dnd-character/.meta/example.rs +++ b/exercises/practice/dnd-character/.meta/example.rs @@ -5,13 +5,13 @@ pub fn modifier(ability_score: u8) -> f32 { } pub struct Character { - strength: u8, - dexterity: u8, - constitution: u8, - intelligence: u8, - wisdom: u8, - charisma: u8, - hitpoints: u8, + pub strength: u8, + pub dexterity: u8, + pub constitution: u8, + pub intelligence: u8, + pub wisdom: u8, + pub charisma: u8, + pub hitpoints: u8, } impl Character {