diff --git a/exercises/practice/dnd-character/.meta/example.cpp b/exercises/practice/dnd-character/.meta/example.cpp index a5e76d6e6..1ea2761a3 100644 --- a/exercises/practice/dnd-character/.meta/example.cpp +++ b/exercises/practice/dnd-character/.meta/example.cpp @@ -1,7 +1,9 @@ #include "dnd_character.h" +#include #include #include +#include namespace dnd_character { int modifier(int score) { @@ -10,8 +12,10 @@ int modifier(int score) { int dice_roll() { return 1 + std::rand() / ((RAND_MAX + 1u) / 6); } -// Throwing three dice is not the same as selecting a random number between 3 -// and 18. -int ability() { return dice_roll() + dice_roll() + dice_roll(); } +int ability() { + auto rolls = {dice_roll(), dice_roll(), dice_roll(), dice_roll()}; + auto discard = std::min(rolls); + return std::accumulate(rolls.begin(), rolls.end(), 0) - discard; +} } // namespace dnd_character diff --git a/exercises/practice/dnd-character/.meta/tests.toml b/exercises/practice/dnd-character/.meta/tests.toml index 719043b25..baa4d985a 100644 --- a/exercises/practice/dnd-character/.meta/tests.toml +++ b/exercises/practice/dnd-character/.meta/tests.toml @@ -70,3 +70,5 @@ include = false [dca2b2ec-f729-4551-84b9-078876bb4808] description = "each ability is only calculated once" reimplements = "2ca77b9b-c099-46c3-a02c-0d0f68ffa0fe" +include = false +comment = "changes for member variable test not suitable for C++" diff --git a/exercises/practice/dnd-character/dnd_character_test.cpp b/exercises/practice/dnd-character/dnd_character_test.cpp index 2358e110d..44d136d5f 100644 --- a/exercises/practice/dnd-character/dnd_character_test.cpp +++ b/exercises/practice/dnd-character/dnd_character_test.cpp @@ -5,6 +5,25 @@ #include "test/catch.hpp" #endif +#include + +template +class IsBetweenMatcher : public Catch::MatcherBase { + T m_begin, m_end; +public: + IsBetweenMatcher(T begin, T end) : + m_begin(begin), m_end(end) { + } + bool match(T const& in) const override { + return in >= m_begin && in <= m_end; + } + std::string describe() const override { + std::ostringstream ss; + ss << "should be between " << m_begin << " and " << m_end; + return ss.str(); + } +}; + TEST_CASE("ability modifier for score 3 is -4", "[1e9ae1dc-35bd-43ba-aa08-e4b94c20fa37]") { REQUIRE(-4 == dnd_character::modifier(3)); } @@ -73,29 +92,18 @@ TEST_CASE("ability modifier for score 18 is +4", "[bafd997a-e852-4e56-9f65-14b60 TEST_CASE("random ability is within range", "[4f28f19c-2e47-4453-a46a-c0d365259c14]") { int result{dnd_character::ability()}; - //REQUIRE("score >= 3 && score <= 18" == dnd_character::ability()); - REQUIRE((result >= 3 && result <= 18)); + CHECK_THAT(result, IsBetweenMatcher(3, 18)); } TEST_CASE("random character is valid", "[385d7e72-864f-4e88-8279-81a7d75b04ad]") { dnd_character::Character character; - REQUIRE((character.strength >= 3 && character.strength <= 18)); - REQUIRE((character.dexterity >= 3 && character.dexterity <= 18)); - REQUIRE((character.constitution >= 3 && character.constitution <= 18)); - REQUIRE((character.intelligence >= 3 && character.intelligence <= 18)); - REQUIRE((character.wisdom >= 3 && character.wisdom <= 18)); - REQUIRE((character.charisma >= 3 && character.charisma <= 18)); + CHECK_THAT(character.strength, IsBetweenMatcher(3, 18)); + CHECK_THAT(character.dexterity, IsBetweenMatcher(3, 18)); + CHECK_THAT(character.constitution, IsBetweenMatcher(3, 18)); + CHECK_THAT(character.intelligence, IsBetweenMatcher(3, 18)); + CHECK_THAT(character.wisdom, IsBetweenMatcher(3, 18)); + CHECK_THAT(character.charisma, IsBetweenMatcher(3, 18)); REQUIRE(character.hitpoints == 10 + dnd_character::modifier(character.constitution)); } -TEST_CASE("each ability is only calculated once", "[dca2b2ec-f729-4551-84b9-078876bb4808]") { - dnd_character::Character character; - REQUIRE(character.strength == character.strength); - REQUIRE(character.dexterity == character.dexterity); - REQUIRE(character.constitution == character.constitution); - REQUIRE(character.intelligence == character.intelligence); - REQUIRE(character.wisdom == character.wisdom); - REQUIRE(character.charisma == character.charisma); -} - #endif