Skip to content

Commit

Permalink
fix: improve tests and example for dnd character exercise (#813)
Browse files Browse the repository at this point in the history
[no important files changed]
  • Loading branch information
vaeng authored Feb 23, 2024
1 parent 425a050 commit 6342754
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 21 deletions.
10 changes: 7 additions & 3 deletions exercises/practice/dnd-character/.meta/example.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "dnd_character.h"

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <numeric>

namespace dnd_character {
int modifier(int score) {
Expand All @@ -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
2 changes: 2 additions & 0 deletions exercises/practice/dnd-character/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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++"
44 changes: 26 additions & 18 deletions exercises/practice/dnd-character/dnd_character_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
#include "test/catch.hpp"
#endif

#include <sstream>

template <typename T>
class IsBetweenMatcher : public Catch::MatcherBase<T> {
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));
}
Expand Down Expand Up @@ -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

0 comments on commit 6342754

Please sign in to comment.