diff options
| author | 2020-04-15 22:42:55 +0200 | |
|---|---|---|
| committer | 2020-04-15 22:42:55 +0200 | |
| commit | c987c9b501083b1995958d62c3e07fb236bc9410 (patch) | |
| tree | 5a88935be195e39522d9e3f4336d314b7cbf0bb8 | |
| parent | c4ae3b2555fad261b21b285a0845238ad3b7e3e5 (diff) | |
| download | OneRoll-c987c9b501083b1995958d62c3e07fb236bc9410.tar.gz OneRoll-c987c9b501083b1995958d62c3e07fb236bc9410.zip | |
Dice: fix #77 from github
| -rw-r--r-- | booleancondition.h | 1 | ||||
| -rw-r--r-- | tests/dice/tst_dice.cpp | 69 | ||||
| -rw-r--r-- | validatorlist.cpp | 164 | ||||
| -rw-r--r-- | validatorlist.h | 23 |
4 files changed, 183 insertions, 74 deletions
diff --git a/booleancondition.h b/booleancondition.h index 466de80..f420adf 100644 --- a/booleancondition.h +++ b/booleancondition.h @@ -41,6 +41,7 @@ public: LesserOrEqual, Different }; + BooleanCondition(); virtual ~BooleanCondition() override; diff --git a/tests/dice/tst_dice.cpp b/tests/dice/tst_dice.cpp index 7675615..cc156dc 100644 --- a/tests/dice/tst_dice.cpp +++ b/tests/dice/tst_dice.cpp @@ -83,16 +83,23 @@ void makeResultExplode(DiceResult& result, const QVector<int>& values) result.insertResult(die); } -ValidatorList* makeValidator(int number, BooleanCondition::LogicOperator op) +ValidatorList* makeValidator(QVector<int> number, BooleanCondition::LogicOperator op, + QVector<ValidatorList::LogicOperation> vector= QVector<ValidatorList::LogicOperation>()) { - BooleanCondition* validator= new BooleanCondition(); - NumberNode* node= new NumberNode(); - node->setNumber(number); - validator->setValueNode(node); - validator->setOperator(op); - ValidatorList* list= new ValidatorList(); - list->setValidators(QList<Validator*>() << validator); + QList<Validator*> validList; + for(auto num : number) + { + BooleanCondition* validator= new BooleanCondition(); + NumberNode* node= new NumberNode(); + node->setNumber(num); + validator->setValueNode(node); + validator->setOperator(op); + validList.append(validator); + } + list->setValidators(validList); + if(!vector.isEmpty()) + list->setOperationList(vector); return list; } @@ -247,6 +254,7 @@ void TestDice::validatorListTest_data() QTest::addRow("cmd1") << "2d[6..6]c6" << 2; QTest::addRow("cmd2") << "[6,2]c[:>6&%2=0]" << 2; + QTest::addRow("cmd3") << "[6,1,1]c[=6|=1]" << 3; } void TestDice::diceRollD10Test() @@ -688,14 +696,29 @@ void TestDice::sortTest_data() void TestDice::countTest() { QFETCH(QVector<int>, values); - QFETCH(int, condition); + QFETCH(QVector<int>, condition); QFETCH(int, score); QFETCH(QVector<int>, subvalues); + QFETCH(int, boolOp); TestNode node; CountExecuteNode countN; - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + QVector<ValidatorList::LogicOperation> vector; + + bool first= true; + for(auto i : condition) + { + if(!first) + { + first= !first; + continue; + } + + vector.push_back(ValidatorList::OR); + } + + auto validator= makeValidator(condition, static_cast<BooleanCondition::LogicOperator>(boolOp), vector); countN.setValidatorList(validator); DiceResult result; @@ -714,13 +737,17 @@ void TestDice::countTest() void TestDice::countTest_data() { QTest::addColumn<QVector<int>>("values"); - QTest::addColumn<int>("condition"); + QTest::addColumn<QVector<int>>("condition"); QTest::addColumn<int>("score"); QTest::addColumn<QVector<int>>("subvalues"); - - QTest::addRow("cmd1") << QVector<int>({10, 9, 2}) << 3 << 2 << QVector<int>(); - QTest::addRow("cmd2") << QVector<int>({1, 2, 3}) << 3 << 0 << QVector<int>(); - QTest::addRow("cmd3") << QVector<int>({10, 7, 4}) << 7 << 3 << QVector<int>({10, 10, 2}); + QTest::addColumn<int>("boolOp"); + + // clang-format off + QTest::addRow("cmd1") << QVector<int>({10, 9, 2}) << QVector<int>({3}) << 2 << QVector<int>() << static_cast<int>(BooleanCondition::GreaterThan); + QTest::addRow("cmd2") << QVector<int>({1, 2, 3}) << QVector<int>({3}) << 0 << QVector<int>() << static_cast<int>(BooleanCondition::GreaterThan); + QTest::addRow("cmd3") << QVector<int>({10, 7, 4}) << QVector<int>({7}) << 3 << QVector<int>({10, 10, 2}) << static_cast<int>(BooleanCondition::GreaterThan); + QTest::addRow("cmd4") << QVector<int>({1, 1, 6}) << QVector<int>({1,6}) << 3 << QVector<int>() << static_cast<int>(BooleanCondition::Equal); + // clang-format on } void TestDice::rerollTest() @@ -736,7 +763,7 @@ void TestDice::rerollTest() makeResult(result, values); node.setResult(&result); - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + auto validator= makeValidator(QVector<int>() << condition, BooleanCondition::GreaterThan); reroll.setValidatorList(validator); node.setNextNode(&reroll); @@ -780,7 +807,7 @@ void TestDice::explodeTest() makeResult(result, values); node.setResult(&result); - auto validator= makeValidator(condition, BooleanCondition::Equal); + auto validator= makeValidator(QVector<int>() << condition, BooleanCondition::Equal); explode.setValidatorList(validator); node.setNextNode(&explode); @@ -824,7 +851,7 @@ void TestDice::rerollUntilTest() makeResult(result, values, QVector<int>(), 0); node.setResult(&result); - auto validator= makeValidator(condition, BooleanCondition::Equal); + auto validator= makeValidator(QVector<int>() << condition, BooleanCondition::Equal); reroll.setValidatorList(validator); node.setNextNode(&reroll); @@ -866,7 +893,7 @@ void TestDice::rerollAddTest() makeResult(result, values); node.setResult(&result); - auto validator= makeValidator(condition, BooleanCondition::Equal); + auto validator= makeValidator(QVector<int>() << condition, BooleanCondition::Equal); reroll.setValidatorList(validator); node.setNextNode(&reroll); @@ -924,7 +951,7 @@ void TestDice::ifTest() ifNode.setInstructionTrue(&trueNode); ifNode.setInstructionFalse(&falseNode); - auto validator= makeValidator(valCondition, BooleanCondition::Equal); + auto validator= makeValidator(QVector<int>() << valCondition, BooleanCondition::Equal); ifNode.setValidatorList(validator); node.setNextNode(&ifNode); @@ -1077,7 +1104,7 @@ void TestDice::occurenceTest() makeResult(result, values); node.setResult(&result); - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + auto validator= makeValidator(QVector<int>() << condition, BooleanCondition::GreaterThan); count.setValidatorList(validator); node.setNextNode(&count); diff --git a/validatorlist.cpp b/validatorlist.cpp index 0d0abb5..5dfaae0 100644 --- a/validatorlist.cpp +++ b/validatorlist.cpp @@ -26,29 +26,28 @@ #include "validator.h" #include <utility> -bool isValid(Die* die, const ValidatorResult& diceList, ValidatorList::LogicOperation op) +void mergeResultsAsAND(const ValidatorResult& diceList, ValidatorResult& result) { - if(op == ValidatorList::OR) - return true; - - bool newResult= false; - - if(diceList.m_allTrue) + ValidatorResult val; + for(auto dice : diceList.validDice()) { - newResult= true; + if(result.contains(dice.first) || diceList.allTrue()) + val.appendValidDice(dice.first, dice.second); } - else + result= val; + result.setAllTrue(diceList.allTrue() & result.allTrue()); +} + +void mergeResultsAsExeclusiveOR(const ValidatorResult& diceList, ValidatorResult& result) +{ + ValidatorResult val; + for(auto dice : diceList.validDice()) { - auto it= std::find_if(diceList.m_validDice.begin(), diceList.m_validDice.end(), - [die](const std::pair<Die*, qint64>& pair) { return die == pair.first; }); - if(it != diceList.m_validDice.end()) - newResult= true; + if(!result.contains(dice.first)) + val.appendValidDice(dice.first, dice.second); } - - if(op == ValidatorList::EXCLUSIVE_OR) - return !newResult; - - return newResult; + result= val; + result.setAllTrue(diceList.allTrue() ^ result.allTrue()); } DiceResult* getDiceResult(Result* result) @@ -62,6 +61,53 @@ DiceResult* getDiceResult(Result* result) return dice; } +////////////////////////////////// +/// \brief ValidatorResult::ValidatorResult +/// +/// +/// +/// //////////////////////////////// +ValidatorResult::ValidatorResult() {} + +const std::vector<std::pair<Die*, qint64>>& ValidatorResult::validDice() const +{ + return m_validDice; +} + +std::vector<std::pair<Die*, qint64>>& ValidatorResult::validDiceRef() +{ + return m_validDice; +} + +void ValidatorResult::appendValidDice(Die* die, qint64 sum) +{ + m_validDice.push_back(std::make_pair(die, sum)); +} + +void ValidatorResult::setAllTrue(bool allTrue) +{ + m_allTrue= allTrue; +} + +bool ValidatorResult::allTrue() const +{ + return m_allTrue; +} + +bool ValidatorResult::contains(Die* die) +{ + auto it= std::find_if(m_validDice.begin(), m_validDice.end(), + [die](const std::pair<Die*, qint64>& pair) { return pair.first == die; }); + + return it != m_validDice.end(); +} + +//////////////////////////////////// +/// \brief ValidatorList::ValidatorList +///*** +/// +//////////////////////////////////// + ValidatorList::ValidatorList() {} ValidatorList::~ValidatorList() @@ -234,7 +280,7 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, std::vector<ValidatorResult> validityData; for(auto& validator : m_validatorList) { - ValidatorResult validResult({{}, false}); + ValidatorResult validResult; switch(validator->getConditionType()) { case Dice::OnScalar: @@ -244,7 +290,14 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, die.insertRollValue(scalar); if(validator->hasValid(&die, recursive, unlight)) { - validResult.m_allTrue= true; + validResult.setAllTrue(true); + DiceResult* diceResult= getDiceResult(result); + if(nullptr == diceResult) + break; + for(auto die : diceResult->getResultList()) + { + validResult.appendValidDice(die, die->getValue()); + } } } break; @@ -258,7 +311,7 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, auto score= validator->hasValid(die, recursive, unlight); if(score) { - validResult.m_validDice.push_back({die, score}); + validResult.appendValidDice(die, score); } } } @@ -274,7 +327,11 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, }); if(all) { - validResult.m_allTrue= true; + validResult.setAllTrue(true); + for(auto die : diceResult->getResultList()) + { + validResult.appendValidDice(die, die->getValue()); + } } } break; @@ -289,7 +346,11 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, }); if(any) { - validResult.m_allTrue= true; + validResult.setAllTrue(true); + for(auto die : diceResult->getResultList()) + { + validResult.appendValidDice(die, die->getValue()); + } } } } @@ -298,49 +359,54 @@ void ValidatorList::validResult(Result* result, bool recursive, bool unlight, if(validityData.empty()) return; - std::size_t i= 0; - ValidatorResult finalResult({{}, false}); - { - auto vec= validityData[i]; - finalResult.m_validDice.reserve(vec.m_validDice.size()); - finalResult= vec; - } - ++i; - for(auto op : m_operators) + int i= 0; + ValidatorResult finalResult; + + for(auto vec : validityData) { - ValidatorResult tmpResult({{}, false}); - if(validityData.size() > i) + auto diceList= vec.validDice(); + if(i == 0) { - auto vec= validityData[i]; - - auto bigger= (vec > finalResult) ? vec : finalResult; - auto smaller= (vec > finalResult) ? finalResult : vec; + std::copy(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef())); + } + else + { + auto id= i - 1; + if(m_operators.size() <= id) + continue; - if(bigger.m_allTrue && smaller.m_allTrue) - tmpResult.m_allTrue= true; - for(auto die : bigger.m_validDice) + auto op= m_operators.at(id); + switch(op) { - if(isValid(die.first, smaller, op)) - { - tmpResult.m_validDice.push_back(die); - } + case OR: + std::copy(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef())); + break; + case AND: + mergeResultsAsAND(vec, finalResult); + break; + case EXCLUSIVE_OR: + mergeResultsAsExeclusiveOR(vec, finalResult); + break; + case NONE: + break; } - finalResult= tmpResult; } + + ++i; } - if(finalResult.m_allTrue) + if(finalResult.allTrue()) { DiceResult* diceResult= getDiceResult(result); if(nullptr == diceResult) return; auto diceList= diceResult->getResultList(); - std::transform(diceList.begin(), diceList.end(), std::back_inserter(finalResult.m_validDice), [](Die* die) { + std::transform(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef()), [](Die* die) { return std::pair<Die*, qint64>({die, 0}); }); } - for(auto die : finalResult.m_validDice) + for(auto die : finalResult.validDice()) { functor(die.first, die.second); } diff --git a/validatorlist.h b/validatorlist.h index 5d29817..1faf7e6 100644 --- a/validatorlist.h +++ b/validatorlist.h @@ -34,12 +34,27 @@ class Validator; class Die; class Result; -struct ValidatorResult +class ValidatorResult { + +public: + ValidatorResult(); + + const std::vector<std::pair<Die*, qint64>>& validDice() const; + std::vector<std::pair<Die*, qint64>>& validDiceRef(); + void setValidDice(const std::vector<std::pair<Die*, qint64>>& pairs); + void appendValidDice(Die* die, qint64 sum); + + void setAllTrue(bool allTrue); + bool allTrue() const; + + bool contains(Die* die); + +private: std::vector<std::pair<Die*, qint64>> m_validDice; - bool m_allTrue; + bool m_allTrue= false; - friend bool operator>(const ValidatorResult& a, const ValidatorResult& b) + /*friend bool operator>(const ValidatorResult& a, const ValidatorResult& b) { if(a.m_validDice.size() > b.m_validDice.size()) return true; @@ -51,7 +66,7 @@ struct ValidatorResult return false; } return false; - } + }*/ }; /** * @brief The BooleanCondition class is a Validator class checking validity from logic expression. |