From 9317fc5571784bafdd6d5de88f2e86e55b646648 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:49:45 +0200 Subject: Add valueslistnode --- cli/CMakeLists.txt | 1 + diceparser.cpp | 39 ++++++++++++++++++++++++++++++++- diceparser.h | 2 ++ diceparser.pri | 2 ++ node/valueslistnode.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ node/valueslistnode.h | 24 ++++++++++++++++++++ 6 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 node/valueslistnode.cpp create mode 100644 node/valueslistnode.h diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 6268fb4..5886240 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -93,6 +93,7 @@ SET( dice_sources ../node/listsetrollnode.cpp ../node/numbernode.cpp ../node/parenthesesnode.cpp + ../node/valueslistnode.cpp # ../node/forloopnode.cpp ../node/paintnode.cpp ../node/rerolldicenode.cpp diff --git a/diceparser.cpp b/diceparser.cpp index f5d543f..78f5fff 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -33,7 +33,6 @@ #include "node/groupnode.h" #include "node/helpnode.h" #include "node/ifnode.h" -#include "node/uniquenode.h" #include "node/jumpbackwardnode.h" #include "node/keepdiceexecnode.h" #include "node/listaliasnode.h" @@ -49,6 +48,8 @@ #include "node/splitnode.h" #include "node/startingnode.h" #include "node/stringnode.h" +#include "node/uniquenode.h" +#include "node/valueslistnode.h" #include "node/variablenode.h" #define DEFAULT_FACES_NUMBER 10 @@ -263,6 +264,11 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) node= operandNode; return true; } + else if(readValuesList(str, operandNode)) + { + node= operandNode; + return true; + } else { ExecutionNode* diceNode= nullptr; @@ -308,6 +314,37 @@ bool DiceParser::readOperatorFromNull(QString& str, ExecutionNode*& node) return false; } +bool DiceParser::readValuesList(QString& str, ExecutionNode*& node) +{ + if(str.startsWith("[")) + { + str= str.remove(0, 1); + int pos= ParsingToolBox::findClosingCharacterIndexOf('[', ']', str, 1); // str.indexOf("]"); + if(-1 != pos) + { + QString liststr= str.left(pos); + auto list= liststr.split(","); + str= str.remove(0, pos + 1); + auto values= new ValuesListNode(); + for(auto var : list) + { + qint64 number= 1; + QString error; + if(ParsingToolBox::readDynamicVariable(var, number)) + { + VariableNode* variableNode= new VariableNode(); + variableNode->setIndex(number - 1); + variableNode->setData(&m_startNodes); + values->insertValue(variableNode); + } + } + node= values; + return true; + } + } + return false; +} + bool DiceParser::readNode(QString& str, ExecutionNode*& node) { if(str.isEmpty()) diff --git a/diceparser.h b/diceparser.h index ff162e3..a5e8619 100644 --- a/diceparser.h +++ b/diceparser.h @@ -254,6 +254,8 @@ public: void getDiceResultFromAllInstruction(QList& resultList); QString humanReadableWarning(); + bool readValuesList(QString& str, ExecutionNode*& node); + protected: bool readParameterNode(QString& str, ExecutionNode*& node); diff --git a/diceparser.pri b/diceparser.pri index c51c96d..8bdd93f 100644 --- a/diceparser.pri +++ b/diceparser.pri @@ -39,6 +39,7 @@ SOURCES += $$PWD/diceparser.cpp \ $$PWD/node/paintnode.cpp \ $$PWD/node/ifnode.cpp \ $$PWD/node/splitnode.cpp \ + $$PWD/node/valueslistnode.cpp \ $$PWD/node/uniquenode.cpp \ $$PWD/node/listsetrollnode.cpp\ $$PWD/node/variablenode.cpp\ @@ -78,6 +79,7 @@ HEADERS += \ $$PWD/node/keepdiceexecnode.h \ $$PWD/node/countexecutenode.h \ $$PWD/node/explodedicenode.h \ + $$PWD/node/valueslistnode.h \ $$PWD/node/parenthesesnode.h \ $$PWD/node/helpnode.h \ $$PWD/node/jumpbackwardnode.h \ diff --git a/node/valueslistnode.cpp b/node/valueslistnode.cpp new file mode 100644 index 0000000..e022741 --- /dev/null +++ b/node/valueslistnode.cpp @@ -0,0 +1,58 @@ +#include "valueslistnode.h" + +ValuesListNode::ValuesListNode() : m_diceResult(new DiceResult()) +{ + m_result= m_diceResult; +} + +void ValuesListNode::run(ExecutionNode* previous) +{ + m_previousNode= previous; + for(auto node : m_data) + { + node->run(this); + auto result= node->getResult(); + if(!result) + continue; + auto val= result->getResult(Result::SCALAR).toInt(); + Die* die= new Die(); + die->displayed(); + die->insertRollValue(val); + m_diceResult->insertResult(die); + } + + if(nullptr != m_nextNode) + { + m_nextNode->run(this); + } +} + +void ValuesListNode::insertValue(ExecutionNode* value) +{ + m_data.push_back(value); +} +ExecutionNode* ValuesListNode::getCopy() const +{ + ValuesListNode* node= new ValuesListNode(); + if(nullptr != m_nextNode) + { + node->setNextNode(m_nextNode->getCopy()); + } + return node; +} +QString ValuesListNode::toString(bool wl) const +{ + if(wl) + { + return QString("%1 [label=\"ValuesListNode list:\"]").arg(m_id); + } + else + { + return m_id; + } +} +qint64 ValuesListNode::getPriority() const +{ + qint64 priority= 4; + return priority; +} diff --git a/node/valueslistnode.h b/node/valueslistnode.h new file mode 100644 index 0000000..100f275 --- /dev/null +++ b/node/valueslistnode.h @@ -0,0 +1,24 @@ +#ifndef VALUESLISTNODE_H +#define VALUESLISTNODE_H + +#include "executionnode.h" +#include "result/diceresult.h" + +class ValuesListNode : public ExecutionNode +{ +public: + ValuesListNode(); + + virtual void run(ExecutionNode* previous= nullptr) override; + virtual QString toString(bool) const override; + virtual qint64 getPriority() const override; + virtual ExecutionNode* getCopy() const override; + + void insertValue(ExecutionNode*); + +private: + std::vector m_data; + DiceResult* m_diceResult = nullptr; +}; + +#endif // VALUESLISTNODE_H -- cgit v1.2.3-70-g09d2 From 133e95bdac75e5793851fd4054689c339794eae3 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:50:52 +0200 Subject: Fix read validator --- parsingtoolbox.cpp | 11 +++++------ parsingtoolbox.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 4fbbd6c..702019d 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -189,7 +189,7 @@ bool ParsingToolBox::readOperand(QString& str, ExecutionNode*& node) return false; } -Validator* ParsingToolBox::readValidator(QString& str) +Validator* ParsingToolBox::readValidator(QString& str, bool hasSquare) { Validator* returnVal= nullptr; BooleanCondition::LogicOperator myLogicOp= BooleanCondition::Equal; @@ -204,7 +204,7 @@ Validator* ParsingToolBox::readValidator(QString& str) { OperationCondition* condition= new OperationCondition(); condition->setValueNode(operandNode); - Validator* valid= readValidator(str); + Validator* valid= readValidator(str,hasSquare); BooleanCondition* boolC= dynamic_cast(valid); if(nullptr != boolC) { @@ -216,7 +216,7 @@ Validator* ParsingToolBox::readValidator(QString& str) else if(readOperand(str, operandNode)) { bool isRange= false; - if(str.startsWith("-")) + if(str.startsWith("-") && hasSquare) { str= str.remove(0, 1); qint64 end= 0; @@ -274,8 +274,7 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) str= str.remove(0, 1); expectSquareBrasket= true; } - - Validator* tmp= readValidator(str); + Validator* tmp= readValidator(str, expectSquareBrasket); CompositeValidator::LogicOperation opLogic; QVector* operators= new QVector(); @@ -288,7 +287,7 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) { operators->append(opLogic); validatorList->append(tmp); - tmp= readValidator(str); + tmp= readValidator(str, expectSquareBrasket); } else { diff --git a/parsingtoolbox.h b/parsingtoolbox.h index 7bb6059..b91db1a 100644 --- a/parsingtoolbox.h +++ b/parsingtoolbox.h @@ -111,7 +111,7 @@ public: * @param str * @return */ - Validator* readValidator(QString& str); + Validator* readValidator(QString& str, bool hasSquare=false); /** * @brief readCompositeValidator * @param str -- cgit v1.2.3-70-g09d2 From 6e449f6754294e02edbed0c64d0f018be139ff50 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:51:44 +0200 Subject: clang format --- diceparser.cpp | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/diceparser.cpp b/diceparser.cpp index 78f5fff..0b1e6da 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -171,11 +171,11 @@ bool DiceParser::parseLine(QString str, bool allowAlias) } m_command= str; bool hasInstruction= readInstructionList(str); - bool value= hasInstruction; if(!hasInstruction) { - m_errorMap.insert(ExecutionNode::NOTHING_UNDERSTOOD, + m_errorMap.insert( + ExecutionNode::NOTHING_UNDERSTOOD, QObject::tr("Nothing was understood. To roll dice: !1d6 - full documation: " "https://github.com/" @@ -184,10 +184,10 @@ bool DiceParser::parseLine(QString str, bool allowAlias) else if(hasInstruction && !str.isEmpty()) { auto i= m_command.size() - str.size(); - m_warningMap.insert(ExecutionNode::UNEXPECTED_CHARACTER, + m_warningMap.insert( + ExecutionNode::UNEXPECTED_CHARACTER, QObject::tr("Unexpected character at %1 - end of command was ignored \"%2\"").arg(i).arg(str)); } - if(!m_errorMap.isEmpty()) value= false; @@ -222,7 +222,7 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) else { m_warningMap.insert(ExecutionNode::BAD_SYNTAXE, - QObject::tr("Expected closing parenthesis - can't validate the inside.")); + QObject::tr("Expected closing parenthesis - can't validate the inside.")); } } } @@ -502,7 +502,7 @@ void DiceParser::getDiceResultFromAllInstruction(QList& resu faces= die->getFaces(); // qDebug() << "face" << faces; HighLightDice hlDice(die->getListValue(), die->isHighlighted(), die->getColor(), - die->hasBeenDisplayed(), die->getFaces()); + die->hasBeenDisplayed(), die->getFaces()); list.append(hlDice); } nodeResult.insert(faces, list); @@ -549,8 +549,8 @@ void DiceParser::getLastDiceResult(QList& diceValuesList, bo valuesResult.append(i); } } - HighLightDice hlDice( - valuesResult, die->isHighlighted(), die->getColor(), die->hasBeenDisplayed(), 0); + HighLightDice hlDice(valuesResult, die->isHighlighted(), die->getColor(), + die->hasBeenDisplayed(), 0); listpair.append(hlDice); } } @@ -686,7 +686,8 @@ bool DiceParser::readDice(QString& str, ExecutionNode*& node) { if(max < 1) { - m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, + m_errorMap.insert( + ExecutionNode::BAD_SYNTAXE, QObject::tr("Dice with %1 face(s) does not exist. Please, put a value higher than 0").arg(max)); return false; } @@ -740,7 +741,8 @@ bool DiceParser::readDice(QString& str, ExecutionNode*& node) } else { - m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, + m_errorMap.insert( + ExecutionNode::BAD_SYNTAXE, QObject::tr( "List is missing after the L operator. Please, add it (e.g : 1L[sword,spear,gun,arrow])")); } @@ -1069,7 +1071,7 @@ bool DiceParser::readOption(QString& str, ExecutionNode* previous) //, else { m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, - QObject::tr("Validator is missing after the c operator. Please, change it")); + QObject::tr("Validator is missing after the c operator. Please, change it")); } } break; @@ -1083,7 +1085,8 @@ bool DiceParser::readOption(QString& str, ExecutionNode* previous) //, { if(!m_parsingToolbox->isValidValidator(previous, validator)) { - m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, + m_errorMap.insert( + ExecutionNode::BAD_SYNTAXE, QObject::tr("Validator is missing after the %1 operator. Please, change it") .arg(operatorName == Reroll ? "r" : "a")); } @@ -1104,11 +1107,12 @@ bool DiceParser::readOption(QString& str, ExecutionNode* previous) //, else { m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, - QObject::tr("Validator is missing after the %1 operator. Please, change it") - .arg(operatorName == Reroll ? QStringLiteral("r") : - operatorName == RerollUntil ? - QStringLiteral("R") : - operatorName == RerollAndAdd ? QStringLiteral("a") : "")); + QObject::tr("Validator is missing after the %1 operator. Please, change it") + .arg(operatorName == Reroll ? + QStringLiteral("r") : + operatorName == RerollUntil ? + QStringLiteral("R") : + operatorName == RerollAndAdd ? QStringLiteral("a") : "")); } } break; @@ -1120,8 +1124,8 @@ bool DiceParser::readOption(QString& str, ExecutionNode* previous) //, if(!m_parsingToolbox->isValidValidator(previous, validator)) { m_errorMap.insert(ExecutionNode::ENDLESS_LOOP_ERROR, - QObject::tr("This condition %1 introduces an endless loop. Please, change it") - .arg(validator->toString())); + QObject::tr("This condition %1 introduces an endless loop. Please, change it") + .arg(validator->toString())); } ExplodeDiceNode* explodedNode= new ExplodeDiceNode(); explodedNode->setValidator(validator); @@ -1132,7 +1136,7 @@ bool DiceParser::readOption(QString& str, ExecutionNode* previous) //, else { m_errorMap.insert(ExecutionNode::BAD_SYNTAXE, - QObject::tr("Validator is missing after the e operator. Please, change it")); + QObject::tr("Validator is missing after the e operator. Please, change it")); } } break; -- cgit v1.2.3-70-g09d2 From 4dddfd6d1821ca3537849243e37d064f75e3b37d Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:53:11 +0200 Subject: use copy constructor instead of assignement --- node/explodedicenode.cpp | 4 ++-- node/filternode.cpp | 4 ++-- node/jumpbackwardnode.cpp | 4 ++-- node/keepdiceexecnode.cpp | 4 ++-- node/mergenode.cpp | 4 ++-- node/rerolldicenode.cpp | 4 ++-- node/uniquenode.cpp | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/node/explodedicenode.cpp b/node/explodedicenode.cpp index 6df64ba..704ac8a 100644 --- a/node/explodedicenode.cpp +++ b/node/explodedicenode.cpp @@ -15,8 +15,8 @@ void ExplodeDiceNode::run(ExecutionNode* previous) { for(auto& die : previous_result->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); +// *tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/filternode.cpp b/node/filternode.cpp index bda9c20..d5d155a 100644 --- a/node/filternode.cpp +++ b/node/filternode.cpp @@ -34,8 +34,8 @@ void FilterNode::run(ExecutionNode* previous) { if(m_validator->hasValid(tmp, m_eachValue)) { - Die* tmpdie= new Die(); - *tmpdie= *tmp; + Die* tmpdie= new Die(*tmp); + //*tmpdie= *tmp; diceList2.append(tmpdie); tmp->displayed(); } diff --git a/node/jumpbackwardnode.cpp b/node/jumpbackwardnode.cpp index 83bdb1e..15c7063 100644 --- a/node/jumpbackwardnode.cpp +++ b/node/jumpbackwardnode.cpp @@ -128,8 +128,8 @@ void JumpBackwardNode::run(ExecutionNode* previous) { for(auto& die : diceResult->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/keepdiceexecnode.cpp b/node/keepdiceexecnode.cpp index bad2370..42b4c40 100644 --- a/node/keepdiceexecnode.cpp +++ b/node/keepdiceexecnode.cpp @@ -50,8 +50,8 @@ void KeepDiceExecNode::run(ExecutionNode* previous) for(Die* die : diceList3) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; diceList2.append(tmpdie); die->displayed(); } diff --git a/node/mergenode.cpp b/node/mergenode.cpp index e708cef..4a11a76 100644 --- a/node/mergenode.cpp +++ b/node/mergenode.cpp @@ -61,8 +61,8 @@ void MergeNode::run(ExecutionNode* previous) { if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed())) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; die->displayed(); m_diceResult->getResultList().append(tmpdie); } diff --git a/node/rerolldicenode.cpp b/node/rerolldicenode.cpp index 659e9c0..56ee6d9 100644 --- a/node/rerolldicenode.cpp +++ b/node/rerolldicenode.cpp @@ -25,8 +25,8 @@ void RerollDiceNode::run(ExecutionNode* previous) { for(auto& die : previous_result->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/uniquenode.cpp b/node/uniquenode.cpp index 4ef7fa6..e937c6d 100644 --- a/node/uniquenode.cpp +++ b/node/uniquenode.cpp @@ -50,8 +50,8 @@ void UniqueNode::run(ExecutionNode* previous) if(it == formerValues.end()) { - auto die = new Die(); - *die = *oldDie; + auto die = new Die(*oldDie); + //*die = *oldDie; m_diceResult->insertResult(die); formerValues.push_back(value); } -- cgit v1.2.3-70-g09d2 From 51f9064933ee08afeb774fe962617572a992d0c5 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:54:09 +0200 Subject: Add forloopnode - experiemental it is not compiled --- node/forloopnode.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ node/forloopnode.h | 36 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 node/forloopnode.cpp create mode 100644 node/forloopnode.h diff --git a/node/forloopnode.cpp b/node/forloopnode.cpp new file mode 100644 index 0000000..f65a389 --- /dev/null +++ b/node/forloopnode.cpp @@ -0,0 +1,103 @@ +#include "forloopnode.h" + +#include "die.h" + +MockNode::MockNode() {} + +void MockNode::run(ExecutionNode* node) +{ + return; +} + +void MockNode::setResult(Result* result) +{ + m_result= result; +} + +QString MockNode::toString(bool) const +{ + return {}; +}; +qint64 MockNode::getPriority() const +{ + return 0; +} +ExecutionNode* MockNode::getCopy() const +{ + return new MockNode(); +} +// end mocknode + +ForLoopNode::ForLoopNode() : m_diceResult(new DiceResult) {} + +void ForLoopNode::setInternal(ExecutionNode* node) +{ + m_internal.reset(node); +} + +void ForLoopNode::run(ExecutionNode* previous) +{ + if(nullptr != previous) + { + auto prevResult= dynamic_cast(previous->getResult()); + if(nullptr != prevResult) + { + m_diceResult->setPrevious(prevResult); + QList diceList= prevResult->getResultList(); + for(Die* dice : diceList) + { + MockNode node; + DiceResult diceResult; + diceResult.insertResult(dice); + node.setResult(&diceResult); + m_internal->run(&node); + + auto tmp= m_internal.get(); + while(nullptr != tmp->getNextNode()) + { + tmp= tmp->getNextNode(); + } + Result* internalResult= tmp->getResult(); + auto value= internalResult->getResult(Result::SCALAR).toInt(); + + Die* neodie= new Die(); + *neodie= *dice; + neodie->setValue(value); + m_diceResult->insertResult(neodie); + node.setResult(nullptr); + diceResult.clear(); + dice->displayed(); + } + } + } + m_result= m_diceResult; + if(m_nextNode != nullptr) + m_nextNode->run(this); +} + +qint64 ForLoopNode::getPriority() const +{ + return 2; +} + +QString ForLoopNode::toString(bool withLabel) const +{ + if(withLabel) + { + return QString("%1 [label=\"ForLoopNode Node\"]").arg(m_id); + } + else + { + return m_id; + } +} + +ExecutionNode* ForLoopNode::getCopy() const +{ + auto node= new ForLoopNode(); + if(m_internal) + { + node->setInternal(m_internal->getCopy()); + } + return node; +} diff --git a/node/forloopnode.h b/node/forloopnode.h new file mode 100644 index 0000000..a9acf20 --- /dev/null +++ b/node/forloopnode.h @@ -0,0 +1,36 @@ +#ifndef FORLOOPNODE_H +#define FORLOOPNODE_H + +#include "executionnode.h" +#include "result/diceresult.h" +#include + +class MockNode : public ExecutionNode +{ +public: + MockNode(); + void run(ExecutionNode* node); + void setResult(Result* result); + QString toString(bool withLabel) const; + qint64 getPriority() const; + ExecutionNode* getCopy() const; +}; + +class ForLoopNode : public ExecutionNode +{ +public: + ForLoopNode(); + void run(ExecutionNode* previous); + + void setInternal(ExecutionNode* internal); + + QString toString(bool withLabel) const; + qint64 getPriority() const; + ExecutionNode* getCopy() const; + +private: + std::unique_ptr m_internal; + DiceResult* m_diceResult; +}; + +#endif // FORLOOPNODE_H -- cgit v1.2.3-70-g09d2 From 8e8384b27f83d0375d381a86622b0afd4c42eacb Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:55:14 +0200 Subject: Change behaviour of occurence count node. Now it can generate a dice result. --- node/occurencecountnode.cpp | 107 +++++++++++++++++++++++++++++--------------- node/occurencecountnode.h | 6 +++ 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/node/occurencecountnode.cpp b/node/occurencecountnode.cpp index 4fdbc51..e0117ef 100644 --- a/node/occurencecountnode.cpp +++ b/node/occurencecountnode.cpp @@ -21,11 +21,7 @@ #include "result/diceresult.h" #include "result/stringresult.h" -OccurenceCountNode::OccurenceCountNode() : ExecutionNode() -{ - m_stringResult= new StringResult(); - m_result= m_stringResult; -} +OccurenceCountNode::OccurenceCountNode() : ExecutionNode() {} void OccurenceCountNode::run(ExecutionNode* previous) { @@ -35,7 +31,6 @@ void OccurenceCountNode::run(ExecutionNode* previous) return; DiceResult* previousDiceResult= dynamic_cast(m_previousNode->getResult()); - // m_diceResult->setPrevious(previousDiceResult); if(nullptr == previousDiceResult) return; @@ -55,40 +50,13 @@ void OccurenceCountNode::run(ExecutionNode* previous) } std::sort(vec.begin(), vec.end()); - - QStringList list; - for(auto key : mapOccurence) + if(nullptr == m_nextNode) { - if(nullptr != m_validator) - { - Die die; - die.insertRollValue(key.first); - if(!m_validator->hasValid(&die, true)) - continue; - } - - if(key.second < m_width) - continue; - - if(key.first >= m_height) - list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + runForStringResult(mapOccurence, vec); } - - QStringList resultList; - std::for_each(vec.begin(), vec.end(), [&resultList](qint64 val) { resultList << QString::number(val); }); - - QString result; - - if(!list.isEmpty()) - result= list.join(','); else - result= QObject::tr("No matching result"); - - m_stringResult->setText(QStringLiteral("%1 - [%2]").arg(result).arg(resultList.join(','))); - - if(nullptr != m_nextNode) { - m_nextNode->run(this); + runForDiceResult(mapOccurence); } } QString OccurenceCountNode::toString(bool label) const @@ -109,6 +77,7 @@ ExecutionNode* OccurenceCountNode::getCopy() const qint64 OccurenceCountNode::getPriority() const { qint64 priority= 0; + if(nullptr != m_previousNode) { priority= m_previousNode->getPriority(); @@ -145,3 +114,69 @@ void OccurenceCountNode::setValidator(Validator* validator) { m_validator= validator; } +void OccurenceCountNode::runForStringResult(const std::map& mapOccurence, QVector& vec) +{ + m_stringResult= new StringResult(); + m_result= m_stringResult; + QStringList list; + for(auto key : mapOccurence) + { + if(nullptr != m_validator) + { + Die die; + die.insertRollValue(key.first); + if(!m_validator->hasValid(&die, true)) + continue; + } + + if(key.second < m_width) + continue; + + if(key.first >= m_height) + list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + } + + QStringList resultList; + std::for_each(vec.begin(), vec.end(), [&resultList](qint64 val) { resultList << QString::number(val); }); + + QString result; + + if(!list.isEmpty()) + result= list.join(','); + else + result= QObject::tr("No matching result"); + + m_stringResult->setText(QStringLiteral("%1 - [%2]").arg(result).arg(resultList.join(','))); +} +void OccurenceCountNode::runForDiceResult(const std::map& mapOccurence) +{ + m_diceResult= new DiceResult(); + m_result= m_diceResult; + QStringList list; + for(auto key : mapOccurence) + { + if(nullptr != m_validator) + { + Die die; + die.insertRollValue(key.first); + if(!m_validator->hasValid(&die, true)) + continue; + } + + if(key.second < m_width) + continue; + + if(key.first >= m_height) + { + // list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + Die* die= new Die(); + die->insertRollValue(key.second * key.first); + m_diceResult->insertResult(die); + } + } + + if(nullptr != m_nextNode) + { + m_nextNode->run(this); + } +} diff --git a/node/occurencecountnode.h b/node/occurencecountnode.h index 125f340..492b295 100644 --- a/node/occurencecountnode.h +++ b/node/occurencecountnode.h @@ -24,6 +24,7 @@ #include "validator.h" class StringResult; +class DiceResult; class OccurenceCountNode : public ExecutionNode { public: @@ -44,11 +45,16 @@ public: Validator* getValidator() const; void setValidator(Validator* validator); +private: + void runForStringResult(const std::map& mapOccurence, QVector& vec); + void runForDiceResult(const std::map& mapOccurence); + private: qint64 m_width= 1; qint64 m_height= 0; Validator* m_validator= nullptr; StringResult* m_stringResult= nullptr; + DiceResult* m_diceResult= nullptr; }; #endif // OCCURENCECOUNTNODE_H -- cgit v1.2.3-70-g09d2 From d810aab9b7df705d325ee00f1909dfd835b9b97c Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 00:28:09 +0200 Subject: Fix errors --- diceparser.cpp | 10 +++++----- node/dicerollernode.cpp | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/diceparser.cpp b/diceparser.cpp index 0b1e6da..e01373c 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -226,6 +226,11 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) } } } + else if(readOperatorFromNull(str, operandNode)) + { + node= operandNode; + return true; + } else if(m_parsingToolbox->readOperand(str, operandNode)) { ExecutionNode* diceNode= nullptr; @@ -259,11 +264,6 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) node= operandNode; return true; } - else if(readOperatorFromNull(str, operandNode)) - { - node= operandNode; - return true; - } else if(readValuesList(str, operandNode)) { node= operandNode; diff --git a/node/dicerollernode.cpp b/node/dicerollernode.cpp index 44b9e0a..f57d3e3 100644 --- a/node/dicerollernode.cpp +++ b/node/dicerollernode.cpp @@ -19,18 +19,19 @@ void DiceRollerNode::run(ExecutionNode* previous) Result* result= previous->getResult(); if(nullptr != result) { - m_diceCount= static_cast(result->getResult(Result::SCALAR).toReal()); - m_result->setPrevious(result); - - if(m_diceCount == 0) + auto num= result->getResult(Result::SCALAR).toReal(); + if(num <= 0) { m_errors.insert(NO_DICE_TO_ROLL, QObject::tr("No dice to roll")); } + m_diceCount= num > 0 ? static_cast(num) : 0; + m_result->setPrevious(result); + auto possibleValue= static_cast(std::abs((m_max - m_min) + 1)); if(possibleValue < m_diceCount && m_unique) { - m_errors.insert( - TOO_MANY_DICE, QObject::tr("More unique values asked than possible values (D operator)")); + m_errors.insert(TOO_MANY_DICE, + QObject::tr("More unique values asked than possible values (D operator)")); return; } -- cgit v1.2.3-70-g09d2 From 9698a39a46f736cf37e31f8940e7c1a0a164185b Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:49:45 +0200 Subject: Add valueslistnode --- CMakeLists.txt | 1 + diceparser.cpp | 36 ++++++++++++++++++++++++++++++ diceparser.h | 2 ++ diceparser.pri | 2 ++ node/valueslistnode.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ node/valueslistnode.h | 24 ++++++++++++++++++++ 6 files changed, 123 insertions(+) create mode 100644 node/valueslistnode.cpp create mode 100644 node/valueslistnode.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8642f97..9a9a340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ SET( dice_sources node/uniquenode.cpp highlightdice.cpp node/variablenode.cpp + node/valueslistnode.cpp ) add_library(diceparser SHARED ${dice_sources} ) diff --git a/diceparser.cpp b/diceparser.cpp index 18be076..1f58948 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -271,6 +271,11 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) node= operandNode; return true; } + else if(readValuesList(str, operandNode)) + { + node= operandNode; + return true; + } else { ExecutionNode* diceNode= nullptr; @@ -316,6 +321,37 @@ bool DiceParser::readOperatorFromNull(QString& str, ExecutionNode*& node) return false; } +bool DiceParser::readValuesList(QString& str, ExecutionNode*& node) +{ + if(str.startsWith("[")) + { + str= str.remove(0, 1); + int pos= ParsingToolBox::findClosingCharacterIndexOf('[', ']', str, 1); // str.indexOf("]"); + if(-1 != pos) + { + QString liststr= str.left(pos); + auto list= liststr.split(","); + str= str.remove(0, pos + 1); + auto values= new ValuesListNode(); + for(auto var : list) + { + qint64 number= 1; + QString error; + if(ParsingToolBox::readDynamicVariable(var, number)) + { + VariableNode* variableNode= new VariableNode(); + variableNode->setIndex(number - 1); + variableNode->setData(&m_startNodes); + values->insertValue(variableNode); + } + } + node= values; + return true; + } + } + return false; +} + bool DiceParser::readNode(QString& str, ExecutionNode*& node) { if(str.isEmpty()) diff --git a/diceparser.h b/diceparser.h index 72e6937..8ecfb50 100644 --- a/diceparser.h +++ b/diceparser.h @@ -250,6 +250,8 @@ public: void getDiceResultFromAllInstruction(QList& resultList); QString humanReadableWarning(); + bool readValuesList(QString& str, ExecutionNode*& node); + protected: bool readParameterNode(QString& str, ExecutionNode*& node); diff --git a/diceparser.pri b/diceparser.pri index 933bed0..2424c18 100644 --- a/diceparser.pri +++ b/diceparser.pri @@ -38,6 +38,7 @@ SOURCES += $$PWD/diceparser.cpp \ $$PWD/node/paintnode.cpp \ $$PWD/node/ifnode.cpp \ $$PWD/node/splitnode.cpp \ + $$PWD/node/valueslistnode.cpp \ $$PWD/node/uniquenode.cpp \ $$PWD/node/listsetrollnode.cpp\ $$PWD/node/variablenode.cpp\ @@ -76,6 +77,7 @@ HEADERS += \ $$PWD/node/keepdiceexecnode.h \ $$PWD/node/countexecutenode.h \ $$PWD/node/explodedicenode.h \ + $$PWD/node/valueslistnode.h \ $$PWD/node/parenthesesnode.h \ $$PWD/node/helpnode.h \ $$PWD/node/jumpbackwardnode.h \ diff --git a/node/valueslistnode.cpp b/node/valueslistnode.cpp new file mode 100644 index 0000000..e022741 --- /dev/null +++ b/node/valueslistnode.cpp @@ -0,0 +1,58 @@ +#include "valueslistnode.h" + +ValuesListNode::ValuesListNode() : m_diceResult(new DiceResult()) +{ + m_result= m_diceResult; +} + +void ValuesListNode::run(ExecutionNode* previous) +{ + m_previousNode= previous; + for(auto node : m_data) + { + node->run(this); + auto result= node->getResult(); + if(!result) + continue; + auto val= result->getResult(Result::SCALAR).toInt(); + Die* die= new Die(); + die->displayed(); + die->insertRollValue(val); + m_diceResult->insertResult(die); + } + + if(nullptr != m_nextNode) + { + m_nextNode->run(this); + } +} + +void ValuesListNode::insertValue(ExecutionNode* value) +{ + m_data.push_back(value); +} +ExecutionNode* ValuesListNode::getCopy() const +{ + ValuesListNode* node= new ValuesListNode(); + if(nullptr != m_nextNode) + { + node->setNextNode(m_nextNode->getCopy()); + } + return node; +} +QString ValuesListNode::toString(bool wl) const +{ + if(wl) + { + return QString("%1 [label=\"ValuesListNode list:\"]").arg(m_id); + } + else + { + return m_id; + } +} +qint64 ValuesListNode::getPriority() const +{ + qint64 priority= 4; + return priority; +} diff --git a/node/valueslistnode.h b/node/valueslistnode.h new file mode 100644 index 0000000..100f275 --- /dev/null +++ b/node/valueslistnode.h @@ -0,0 +1,24 @@ +#ifndef VALUESLISTNODE_H +#define VALUESLISTNODE_H + +#include "executionnode.h" +#include "result/diceresult.h" + +class ValuesListNode : public ExecutionNode +{ +public: + ValuesListNode(); + + virtual void run(ExecutionNode* previous= nullptr) override; + virtual QString toString(bool) const override; + virtual qint64 getPriority() const override; + virtual ExecutionNode* getCopy() const override; + + void insertValue(ExecutionNode*); + +private: + std::vector m_data; + DiceResult* m_diceResult = nullptr; +}; + +#endif // VALUESLISTNODE_H -- cgit v1.2.3-70-g09d2 From 3003420a1efae5bb8f7baca7062c509a633fd977 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:50:52 +0200 Subject: Fix read validator --- parsingtoolbox.cpp | 11 +++++------ parsingtoolbox.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/parsingtoolbox.cpp b/parsingtoolbox.cpp index 4fbbd6c..702019d 100644 --- a/parsingtoolbox.cpp +++ b/parsingtoolbox.cpp @@ -189,7 +189,7 @@ bool ParsingToolBox::readOperand(QString& str, ExecutionNode*& node) return false; } -Validator* ParsingToolBox::readValidator(QString& str) +Validator* ParsingToolBox::readValidator(QString& str, bool hasSquare) { Validator* returnVal= nullptr; BooleanCondition::LogicOperator myLogicOp= BooleanCondition::Equal; @@ -204,7 +204,7 @@ Validator* ParsingToolBox::readValidator(QString& str) { OperationCondition* condition= new OperationCondition(); condition->setValueNode(operandNode); - Validator* valid= readValidator(str); + Validator* valid= readValidator(str,hasSquare); BooleanCondition* boolC= dynamic_cast(valid); if(nullptr != boolC) { @@ -216,7 +216,7 @@ Validator* ParsingToolBox::readValidator(QString& str) else if(readOperand(str, operandNode)) { bool isRange= false; - if(str.startsWith("-")) + if(str.startsWith("-") && hasSquare) { str= str.remove(0, 1); qint64 end= 0; @@ -274,8 +274,7 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) str= str.remove(0, 1); expectSquareBrasket= true; } - - Validator* tmp= readValidator(str); + Validator* tmp= readValidator(str, expectSquareBrasket); CompositeValidator::LogicOperation opLogic; QVector* operators= new QVector(); @@ -288,7 +287,7 @@ Validator* ParsingToolBox::readCompositeValidator(QString& str) { operators->append(opLogic); validatorList->append(tmp); - tmp= readValidator(str); + tmp= readValidator(str, expectSquareBrasket); } else { diff --git a/parsingtoolbox.h b/parsingtoolbox.h index 7bb6059..b91db1a 100644 --- a/parsingtoolbox.h +++ b/parsingtoolbox.h @@ -111,7 +111,7 @@ public: * @param str * @return */ - Validator* readValidator(QString& str); + Validator* readValidator(QString& str, bool hasSquare=false); /** * @brief readCompositeValidator * @param str -- cgit v1.2.3-70-g09d2 From fb12f7ea65cf14398b5d23ffa1a56c78dc3e58b3 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:51:44 +0200 Subject: clang format --- diceparser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/diceparser.cpp b/diceparser.cpp index 1f58948..7add97d 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -176,7 +176,6 @@ bool DiceParser::parseLine(QString str, bool allowAlias) } m_command= str; bool hasInstruction= readInstructionList(str); - bool value= hasInstruction; if(!hasInstruction) { @@ -194,7 +193,6 @@ bool DiceParser::parseLine(QString str, bool allowAlias) ExecutionNode::UNEXPECTED_CHARACTER, QObject::tr("Unexpected character at %1 - end of command was ignored \"%2\"").arg(i).arg(str)); } - if(!m_errorMap.isEmpty()) value= false; -- cgit v1.2.3-70-g09d2 From 2b1abc365f2d7b262e92e3d418a41e4f6d981fcb Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:53:11 +0200 Subject: use copy constructor instead of assignement --- node/explodedicenode.cpp | 4 ++-- node/filternode.cpp | 4 ++-- node/jumpbackwardnode.cpp | 4 ++-- node/keepdiceexecnode.cpp | 4 ++-- node/mergenode.cpp | 4 ++-- node/rerolldicenode.cpp | 4 ++-- node/uniquenode.cpp | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/node/explodedicenode.cpp b/node/explodedicenode.cpp index 6df64ba..704ac8a 100644 --- a/node/explodedicenode.cpp +++ b/node/explodedicenode.cpp @@ -15,8 +15,8 @@ void ExplodeDiceNode::run(ExecutionNode* previous) { for(auto& die : previous_result->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); +// *tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/filternode.cpp b/node/filternode.cpp index bda9c20..d5d155a 100644 --- a/node/filternode.cpp +++ b/node/filternode.cpp @@ -34,8 +34,8 @@ void FilterNode::run(ExecutionNode* previous) { if(m_validator->hasValid(tmp, m_eachValue)) { - Die* tmpdie= new Die(); - *tmpdie= *tmp; + Die* tmpdie= new Die(*tmp); + //*tmpdie= *tmp; diceList2.append(tmpdie); tmp->displayed(); } diff --git a/node/jumpbackwardnode.cpp b/node/jumpbackwardnode.cpp index 83bdb1e..15c7063 100644 --- a/node/jumpbackwardnode.cpp +++ b/node/jumpbackwardnode.cpp @@ -128,8 +128,8 @@ void JumpBackwardNode::run(ExecutionNode* previous) { for(auto& die : diceResult->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/keepdiceexecnode.cpp b/node/keepdiceexecnode.cpp index bad2370..42b4c40 100644 --- a/node/keepdiceexecnode.cpp +++ b/node/keepdiceexecnode.cpp @@ -50,8 +50,8 @@ void KeepDiceExecNode::run(ExecutionNode* previous) for(Die* die : diceList3) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; diceList2.append(tmpdie); die->displayed(); } diff --git a/node/mergenode.cpp b/node/mergenode.cpp index e708cef..4a11a76 100644 --- a/node/mergenode.cpp +++ b/node/mergenode.cpp @@ -61,8 +61,8 @@ void MergeNode::run(ExecutionNode* previous) { if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed())) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; die->displayed(); m_diceResult->getResultList().append(tmpdie); } diff --git a/node/rerolldicenode.cpp b/node/rerolldicenode.cpp index 659e9c0..56ee6d9 100644 --- a/node/rerolldicenode.cpp +++ b/node/rerolldicenode.cpp @@ -25,8 +25,8 @@ void RerollDiceNode::run(ExecutionNode* previous) { for(auto& die : previous_result->getResultList()) { - Die* tmpdie= new Die(); - *tmpdie= *die; + Die* tmpdie= new Die(*die); + //*tmpdie= *die; m_diceResult->insertResult(tmpdie); die->displayed(); } diff --git a/node/uniquenode.cpp b/node/uniquenode.cpp index 4ef7fa6..e937c6d 100644 --- a/node/uniquenode.cpp +++ b/node/uniquenode.cpp @@ -50,8 +50,8 @@ void UniqueNode::run(ExecutionNode* previous) if(it == formerValues.end()) { - auto die = new Die(); - *die = *oldDie; + auto die = new Die(*oldDie); + //*die = *oldDie; m_diceResult->insertResult(die); formerValues.push_back(value); } -- cgit v1.2.3-70-g09d2 From 0351038352f4f22f5a114abe875fb58d55183a86 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:54:09 +0200 Subject: Add forloopnode - experiemental it is not compiled --- node/forloopnode.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ node/forloopnode.h | 36 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 node/forloopnode.cpp create mode 100644 node/forloopnode.h diff --git a/node/forloopnode.cpp b/node/forloopnode.cpp new file mode 100644 index 0000000..f65a389 --- /dev/null +++ b/node/forloopnode.cpp @@ -0,0 +1,103 @@ +#include "forloopnode.h" + +#include "die.h" + +MockNode::MockNode() {} + +void MockNode::run(ExecutionNode* node) +{ + return; +} + +void MockNode::setResult(Result* result) +{ + m_result= result; +} + +QString MockNode::toString(bool) const +{ + return {}; +}; +qint64 MockNode::getPriority() const +{ + return 0; +} +ExecutionNode* MockNode::getCopy() const +{ + return new MockNode(); +} +// end mocknode + +ForLoopNode::ForLoopNode() : m_diceResult(new DiceResult) {} + +void ForLoopNode::setInternal(ExecutionNode* node) +{ + m_internal.reset(node); +} + +void ForLoopNode::run(ExecutionNode* previous) +{ + if(nullptr != previous) + { + auto prevResult= dynamic_cast(previous->getResult()); + if(nullptr != prevResult) + { + m_diceResult->setPrevious(prevResult); + QList diceList= prevResult->getResultList(); + for(Die* dice : diceList) + { + MockNode node; + DiceResult diceResult; + diceResult.insertResult(dice); + node.setResult(&diceResult); + m_internal->run(&node); + + auto tmp= m_internal.get(); + while(nullptr != tmp->getNextNode()) + { + tmp= tmp->getNextNode(); + } + Result* internalResult= tmp->getResult(); + auto value= internalResult->getResult(Result::SCALAR).toInt(); + + Die* neodie= new Die(); + *neodie= *dice; + neodie->setValue(value); + m_diceResult->insertResult(neodie); + node.setResult(nullptr); + diceResult.clear(); + dice->displayed(); + } + } + } + m_result= m_diceResult; + if(m_nextNode != nullptr) + m_nextNode->run(this); +} + +qint64 ForLoopNode::getPriority() const +{ + return 2; +} + +QString ForLoopNode::toString(bool withLabel) const +{ + if(withLabel) + { + return QString("%1 [label=\"ForLoopNode Node\"]").arg(m_id); + } + else + { + return m_id; + } +} + +ExecutionNode* ForLoopNode::getCopy() const +{ + auto node= new ForLoopNode(); + if(m_internal) + { + node->setInternal(m_internal->getCopy()); + } + return node; +} diff --git a/node/forloopnode.h b/node/forloopnode.h new file mode 100644 index 0000000..a9acf20 --- /dev/null +++ b/node/forloopnode.h @@ -0,0 +1,36 @@ +#ifndef FORLOOPNODE_H +#define FORLOOPNODE_H + +#include "executionnode.h" +#include "result/diceresult.h" +#include + +class MockNode : public ExecutionNode +{ +public: + MockNode(); + void run(ExecutionNode* node); + void setResult(Result* result); + QString toString(bool withLabel) const; + qint64 getPriority() const; + ExecutionNode* getCopy() const; +}; + +class ForLoopNode : public ExecutionNode +{ +public: + ForLoopNode(); + void run(ExecutionNode* previous); + + void setInternal(ExecutionNode* internal); + + QString toString(bool withLabel) const; + qint64 getPriority() const; + ExecutionNode* getCopy() const; + +private: + std::unique_ptr m_internal; + DiceResult* m_diceResult; +}; + +#endif // FORLOOPNODE_H -- cgit v1.2.3-70-g09d2 From 80bc5ef3c8276a33d0c3b1cb962939e7c252ae7c Mon Sep 17 00:00:00 2001 From: Renaud G Date: Wed, 10 Jul 2019 11:55:14 +0200 Subject: Change behaviour of occurence count node. Now it can generate a dice result. --- node/occurencecountnode.cpp | 107 +++++++++++++++++++++++++++++--------------- node/occurencecountnode.h | 6 +++ 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/node/occurencecountnode.cpp b/node/occurencecountnode.cpp index 4fdbc51..e0117ef 100644 --- a/node/occurencecountnode.cpp +++ b/node/occurencecountnode.cpp @@ -21,11 +21,7 @@ #include "result/diceresult.h" #include "result/stringresult.h" -OccurenceCountNode::OccurenceCountNode() : ExecutionNode() -{ - m_stringResult= new StringResult(); - m_result= m_stringResult; -} +OccurenceCountNode::OccurenceCountNode() : ExecutionNode() {} void OccurenceCountNode::run(ExecutionNode* previous) { @@ -35,7 +31,6 @@ void OccurenceCountNode::run(ExecutionNode* previous) return; DiceResult* previousDiceResult= dynamic_cast(m_previousNode->getResult()); - // m_diceResult->setPrevious(previousDiceResult); if(nullptr == previousDiceResult) return; @@ -55,40 +50,13 @@ void OccurenceCountNode::run(ExecutionNode* previous) } std::sort(vec.begin(), vec.end()); - - QStringList list; - for(auto key : mapOccurence) + if(nullptr == m_nextNode) { - if(nullptr != m_validator) - { - Die die; - die.insertRollValue(key.first); - if(!m_validator->hasValid(&die, true)) - continue; - } - - if(key.second < m_width) - continue; - - if(key.first >= m_height) - list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + runForStringResult(mapOccurence, vec); } - - QStringList resultList; - std::for_each(vec.begin(), vec.end(), [&resultList](qint64 val) { resultList << QString::number(val); }); - - QString result; - - if(!list.isEmpty()) - result= list.join(','); else - result= QObject::tr("No matching result"); - - m_stringResult->setText(QStringLiteral("%1 - [%2]").arg(result).arg(resultList.join(','))); - - if(nullptr != m_nextNode) { - m_nextNode->run(this); + runForDiceResult(mapOccurence); } } QString OccurenceCountNode::toString(bool label) const @@ -109,6 +77,7 @@ ExecutionNode* OccurenceCountNode::getCopy() const qint64 OccurenceCountNode::getPriority() const { qint64 priority= 0; + if(nullptr != m_previousNode) { priority= m_previousNode->getPriority(); @@ -145,3 +114,69 @@ void OccurenceCountNode::setValidator(Validator* validator) { m_validator= validator; } +void OccurenceCountNode::runForStringResult(const std::map& mapOccurence, QVector& vec) +{ + m_stringResult= new StringResult(); + m_result= m_stringResult; + QStringList list; + for(auto key : mapOccurence) + { + if(nullptr != m_validator) + { + Die die; + die.insertRollValue(key.first); + if(!m_validator->hasValid(&die, true)) + continue; + } + + if(key.second < m_width) + continue; + + if(key.first >= m_height) + list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + } + + QStringList resultList; + std::for_each(vec.begin(), vec.end(), [&resultList](qint64 val) { resultList << QString::number(val); }); + + QString result; + + if(!list.isEmpty()) + result= list.join(','); + else + result= QObject::tr("No matching result"); + + m_stringResult->setText(QStringLiteral("%1 - [%2]").arg(result).arg(resultList.join(','))); +} +void OccurenceCountNode::runForDiceResult(const std::map& mapOccurence) +{ + m_diceResult= new DiceResult(); + m_result= m_diceResult; + QStringList list; + for(auto key : mapOccurence) + { + if(nullptr != m_validator) + { + Die die; + die.insertRollValue(key.first); + if(!m_validator->hasValid(&die, true)) + continue; + } + + if(key.second < m_width) + continue; + + if(key.first >= m_height) + { + // list << QStringLiteral("%1x%2").arg(key.second).arg(key.first); + Die* die= new Die(); + die->insertRollValue(key.second * key.first); + m_diceResult->insertResult(die); + } + } + + if(nullptr != m_nextNode) + { + m_nextNode->run(this); + } +} diff --git a/node/occurencecountnode.h b/node/occurencecountnode.h index 125f340..492b295 100644 --- a/node/occurencecountnode.h +++ b/node/occurencecountnode.h @@ -24,6 +24,7 @@ #include "validator.h" class StringResult; +class DiceResult; class OccurenceCountNode : public ExecutionNode { public: @@ -44,11 +45,16 @@ public: Validator* getValidator() const; void setValidator(Validator* validator); +private: + void runForStringResult(const std::map& mapOccurence, QVector& vec); + void runForDiceResult(const std::map& mapOccurence); + private: qint64 m_width= 1; qint64 m_height= 0; Validator* m_validator= nullptr; StringResult* m_stringResult= nullptr; + DiceResult* m_diceResult= nullptr; }; #endif // OCCURENCECOUNTNODE_H -- cgit v1.2.3-70-g09d2 From 3900611f9bc0b8e47f198587defd632403beaf90 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 00:28:09 +0200 Subject: Fix errors --- diceparser.cpp | 10 +++++----- node/dicerollernode.cpp | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/diceparser.cpp b/diceparser.cpp index 7add97d..0de05fc 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -231,6 +231,11 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) } } } + else if(readOperatorFromNull(str, operandNode)) + { + node= operandNode; + return true; + } else if(m_parsingToolbox->readOperand(str, operandNode)) { ExecutionNode* diceNode= nullptr; @@ -264,11 +269,6 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node) node= operandNode; return true; } - else if(readOperatorFromNull(str, operandNode)) - { - node= operandNode; - return true; - } else if(readValuesList(str, operandNode)) { node= operandNode; diff --git a/node/dicerollernode.cpp b/node/dicerollernode.cpp index 44b9e0a..f57d3e3 100644 --- a/node/dicerollernode.cpp +++ b/node/dicerollernode.cpp @@ -19,18 +19,19 @@ void DiceRollerNode::run(ExecutionNode* previous) Result* result= previous->getResult(); if(nullptr != result) { - m_diceCount= static_cast(result->getResult(Result::SCALAR).toReal()); - m_result->setPrevious(result); - - if(m_diceCount == 0) + auto num= result->getResult(Result::SCALAR).toReal(); + if(num <= 0) { m_errors.insert(NO_DICE_TO_ROLL, QObject::tr("No dice to roll")); } + m_diceCount= num > 0 ? static_cast(num) : 0; + m_result->setPrevious(result); + auto possibleValue= static_cast(std::abs((m_max - m_min) + 1)); if(possibleValue < m_diceCount && m_unique) { - m_errors.insert( - TOO_MANY_DICE, QObject::tr("More unique values asked than possible values (D operator)")); + m_errors.insert(TOO_MANY_DICE, + QObject::tr("More unique values asked than possible values (D operator)")); return; } -- cgit v1.2.3-70-g09d2 From 713f548d5c3ddabd7f8a65d19edb38205a159091 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 22:40:01 +0200 Subject: Add values list node --- diceparser.cpp | 9 ++++++++- node/valueslistnode.cpp | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/diceparser.cpp b/diceparser.cpp index 0de05fc..75247ba 100644 --- a/diceparser.cpp +++ b/diceparser.cpp @@ -28,6 +28,7 @@ #include "node/bind.h" #include "node/countexecutenode.h" +#include "node/dicerollernode.h" #include "node/explodedicenode.h" #include "node/filternode.h" #include "node/groupnode.h" @@ -49,10 +50,10 @@ #include "node/startingnode.h" #include "node/stringnode.h" #include "node/uniquenode.h" +#include "node/valueslistnode.h" #include "node/variablenode.h" #include "booleancondition.h" -#include "node/dicerollernode.h" #include "parsingtoolbox.h" #include "range.h" #include "validator.h" @@ -342,6 +343,12 @@ bool DiceParser::readValuesList(QString& str, ExecutionNode*& node) variableNode->setData(&m_startNodes); values->insertValue(variableNode); } + else if(ParsingToolBox::readNumber(var, number)) + { + NumberNode* numberNode= new NumberNode(); + numberNode->setNumber(number); + values->insertValue(numberNode); + } } node= values; return true; diff --git a/node/valueslistnode.cpp b/node/valueslistnode.cpp index e022741..b31ee84 100644 --- a/node/valueslistnode.cpp +++ b/node/valueslistnode.cpp @@ -1,5 +1,7 @@ #include "valueslistnode.h" +#include "variablenode.h" + ValuesListNode::ValuesListNode() : m_diceResult(new DiceResult()) { m_result= m_diceResult; @@ -16,7 +18,9 @@ void ValuesListNode::run(ExecutionNode* previous) continue; auto val= result->getResult(Result::SCALAR).toInt(); Die* die= new Die(); - die->displayed(); + auto dyna= dynamic_cast(node); + if(nullptr != dyna) + die->displayed(); die->insertRollValue(val); m_diceResult->insertResult(die); } -- cgit v1.2.3-70-g09d2 From a9570bbb2d01cafd79ccea2722a0da86bd5f2b0e Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 22:40:17 +0200 Subject: fix warnings --- tests/testnode.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testnode.cpp b/tests/testnode.cpp index 263286b..de9fc05 100644 --- a/tests/testnode.cpp +++ b/tests/testnode.cpp @@ -10,6 +10,7 @@ TestNode::~TestNode() } void TestNode::run(ExecutionNode* previous) { + Q_UNUSED(previous) if(nullptr != m_nextNode) { m_nextNode->run(this); -- cgit v1.2.3-70-g09d2 From 516bc93cf2f23b1cb1ba795351fdae366b45269b Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 22:40:31 +0200 Subject: add new command to test. --- tests/tst_dice.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/tst_dice.cpp b/tests/tst_dice.cpp index c513337..81618ca 100644 --- a/tests/tst_dice.cpp +++ b/tests/tst_dice.cpp @@ -27,6 +27,7 @@ #include "die.h" // node +#include "booleancondition.h" #include "node/bind.h" #include "node/countexecutenode.h" #include "node/explodedicenode.h" @@ -40,9 +41,8 @@ #include "node/rerolldicenode.h" #include "node/sortresult.h" #include "node/stringnode.h" -#include "testnode.h" #include "result/stringresult.h" -#include "booleancondition.h" +#include "testnode.h" class TestDice : public QObject { @@ -189,7 +189,6 @@ void TestDice::commandsTest() m_diceParser->start(); QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error"); - QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning"); } @@ -261,6 +260,19 @@ void TestDice::commandsTest_data() QTest::addRow("cmd72") << "3d100g5"; QTest::addRow("cmd73") << "3d100g40"; QTest::addRow("cmd74") << "2d10k1+2d10k1+2d10k1"; + QTest::addRow("cmd75") << "2d10k1-2d10k1-2d10k1"; + QTest::addRow("cmd76") << "(2d10k1)-2d10k1-2d10k1"; + QTest::addRow("cmd77") << "2d10k1-(2d10k1)-2d10k1"; + QTest::addRow("cmd78") << "2d10k1-2d10k1-(2d10k1)"; + QTest::addRow("cmd79") << "1d6-2d6e6"; + QTest::addRow("cmd80") << "(1)-1d6e6"; + QTest::addRow("cmd81") << "(1)-(1d6e6)"; + QTest::addRow("cmd82") << "8d10o"; + QTest::addRow("cmd83") << "8d10o2,4"; + QTest::addRow("cmd84") << "8d10o2[>2]"; + QTest::addRow("cmd85") << "8d10ok2"; + QTest::addRow("cmd86") << "[100,200,300]k2"; + QTest::addRow("cmd87") << "100;200;300;[$1,$2,$3]k2"; } void TestDice::wrongCommandsTest() -- cgit v1.2.3-70-g09d2 From ced2aa420e551d16d92671807a2e17806e55e227 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Fri, 12 Jul 2019 22:53:21 +0200 Subject: Improve readme --- HelpMe.md | 92 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/HelpMe.md b/HelpMe.md index 94f6dce..f6a11c1 100644 --- a/HelpMe.md +++ b/HelpMe.md @@ -2,9 +2,9 @@ # Table of Contents -* [DiceParser](#diceparser--what-is-it-) -* [Roll a die](#how-to-roll-a-die) -* [List of operator](#list-of-operator) +* [DiceParser](#diceparser--what-is-it-) +* [Roll a die](#how-to-roll-a-die) +* [List of operator](#list-of-operator) * [Keep](#keep) * [Explode and Keep](#explode-and-keep) * [Keep Lower dice](#keep-lower-dice) @@ -22,12 +22,13 @@ * [Group](#group) * [Spread](#spread) * [Unique](#unique) + * [Value list](#Value-list) * [Comment (\#)](#comment-) -* [Arithmetic](#arithmetic) -* [Arithmetic and Dice](#arithmetic-and-dice) -* [Validator](#validator) -* [Value from set](#select-value-from-list) -* [Miscellaneous examples](#examples) +* [Arithmetic](#arithmetic) +* [Arithmetic and Dice](#arithmetic-and-dice) +* [Validator](#validator) +* [Value from set](#select-value-from-list) +* [Miscellaneous examples](#examples) * [Best Practices](#best-practices) * [Platforms](#roll-dice-on-each-platform) * [Discord bot](#discord-bot) @@ -42,12 +43,12 @@ Such as: Irc bot, discord bot, included in Rolisteam, web server, on twitter etc ## About examples in this documentation -To make it clear, all examples in this documentation do not show the start up prefix. -Please, remember to add the proper prefix given where you run dice command: Rolisteam, discord, IRC… -If you don't know, try `!`. +To make it clear, all examples in this documentation do not show the start up prefix. +Please, remember to add the proper prefix given where you run dice command: Rolisteam, discord, IRC… +If you don't know, try `!`. The prefix allows the system to identify your command. -## How to roll a die +## How to roll a die It is real simple. you have to call: > 1d6 @@ -89,7 +90,7 @@ Rolling 3 dice with 10 faces starting at 0. Rolling 3 dice, values are between -20 and -9. -### Instruction: Roll two (or more) kinds of dice at once +### Instruction: Roll two (or more) kinds of dice at once Adding (or any arithmetic operations) results from two (or more) kinds of dice is easy: @@ -106,8 +107,8 @@ or ### Merge -It is possible to merge every instruction inside a huge one. -The operator merge is dedicated to that. +It is possible to merge every instruction inside a huge one. +The operator merge is dedicated to that. It is useful when you need to manage all diceresult as the same result. For example, if you need to keep the higher dice between a d6 and d8. @@ -127,7 +128,7 @@ the number of instruction is not limited. > 8d10;$1c[>6];$1c1;$2-$3 -* The first instruction rolls 8 (10 sided) dice +* The first instruction rolls 8 (10 sided) dice * The second instruction counts how many dice are higher than 6. * The third instruction counts how many dice are equal to 1. * The fourth instruction substracts the result of the third instruction to the result of seconde one. @@ -248,10 +249,19 @@ Result: `2x8 - [1,2,3,5,6,7,8,8,9,10]` Count and sort occurence when they occur at least 2 times, the value should respect the validator (here less than 6). Result: `2x3,2x5 - [3,3,5,5,6,6,6,7,7,8]` + +#### Errors + +> 10d10o[<6] + +This command is triggering a warning. As occurence operator can have 0 or 2 parameters. But only one validator is unsupported yet. + + + ### Backward Jump This operator is dedicated to apply its next operator to the second to last result. -For example: +For example: > 8D10c[>=7]+@c[=10] @@ -263,7 +273,7 @@ c[=10] in this command is counting the number of 10 in the result of 8D10, if yo Paint the first die in the list in blue -> 8d10p[2:blue] +> 8d10p[2:blue] Paint the two first dice in the list in blue. @@ -300,19 +310,29 @@ It makes exploded dice as new dice. > 4d6e6u - Result: 6 4 3 3 2 Final result: 6+4+3 = 13 +### Value list + +Build your own value list and apply any dice operator. + +> [10,25,43,8]k1 + +Get the higher score from several instruction: + +> 1d10;2d6+9;1d20;[$1,$2,$3,$4]k1 + +Each value is transformed into a die. ### Bind -Bind works exactly as merge but one thing. +Bind works exactly as merge but it keeps instruction array untouched. > !2d8;2d12b;$2k2;$2k2kl1;"your total is $3 with lowest: $4" Roll two 8-sided dice and two 12-sided dice then bind their results. using this final result, we keep the 2 higher dice and then we isolate the lowest of the two highest. -At the end, we display the result inside a setence. +At the end, we display the result inside a sentence. ### if @@ -415,8 +435,8 @@ or In this example, the critical fail happens when there are more fails than success. - - + + In the next example, the critical fail happens when there was no success and a least one fail. > 8d10;$1c[>6];$1c1;$2-$3;$4i:[=0]{"Fail $4 [%2]"}{$4i:[>0]{"$2 Success[%2]"}{$2i:[=0]{"Critical Fail $4 [%2]"}{"Fail $4 [%2]"}}} @@ -428,7 +448,7 @@ Group dices, then count the number of group (7th sea system). #### Example -> 3d20g10 +> 3d20g10 This will roll 3 dices and then try to group them to make groups of 10. If you get `9 9 2`, you can only create one group whose value is more or equal to ten (`{9,2}`, the second `9` being "wasted"). @@ -437,7 +457,7 @@ The `g` operator is allowed to re-order dices to create groups. When rolling `4d ### Comment (\#) -> 2D6 # Sword attack +> 2D6 # Sword attack Display "Sword attack" and the result of the two dice. DiceParser ignore everything after the \#. The whole part is treated as one comment. @@ -452,7 +472,7 @@ yes ## Arithmetic -Rolisteam Dice Parser is able to compute primary arithmetic operation such as: +, -, /, * and it also manages those operator priority and it can also manage parenthesis. +Rolisteam Dice Parser is able to compute primary arithmetic operation such as: +, -, /, * and it also manages those operator priority and it can also manage parenthesis. > 8+8+8 @@ -484,8 +504,8 @@ Result: 2.5 ## Arithmetic and Dice -It is possible to use arithmetic opearation on dice. Please pay attention that the default operation to translate a -dice list to scalar is the sum. So if you roll `3d6`, the result will be a list with 3 values {2, 5 ,1}. Now, we +It is possible to use arithmetic opearation on dice. Please pay attention that the default operation to translate a +dice list to scalar is the sum. So if you roll `3d6`, the result will be a list with 3 values {2, 5 ,1}. Now, we change a bit the command `3d6+4`: It is resolved like this: {2, 5 ,1} = 8; 8+4 = 12. The final result is 12. > 3d6+4 @@ -502,14 +522,14 @@ Substract the result of 1 die to 87 > (6-4)D10 -Substract 4 to 6 and then roll two dice. +Substract 4 to 6 and then roll two dice. > 1D10/2 Divide by 2 the result of 1 die. > (2+2)^2 -Result: 16 +Result: 16 > 1d10^2 @@ -529,7 +549,7 @@ There are three kind of Validator: Any operator which requires validator (such as `a,r,e,c`) can use those three kind. -### Scalar +### Scalar The scalar value sets the validator on eguality between the dice value and the validator @@ -612,7 +632,7 @@ compute: 24 > 1L[sword,bow,knife,gun,shotgun] -One of this word will be picked. +One of this word will be picked. > 8D10c[Validator1]-@c[validator2] @@ -624,7 +644,7 @@ Old World in darkness system. > 8D10c[>=7]+@c[=10] -Exalted 2nd edition system. +Exalted 2nd edition system. ## Best Practices @@ -682,7 +702,7 @@ The k operator to keeps as many dice as you roll is pretty useless because it is ### To change the prefix > !prefix set newprefix -/!\ Please, don't set "newprefix" as your new prefix. +/!\ Please, don't set "newprefix" as your new prefix. ### Set the prefix by default @@ -694,7 +714,7 @@ The k operator to keeps as many dice as you roll is pretty useless because it is > roll 2d6 -> rollprefix set ! +> rollprefix set ! # Macro management @@ -761,5 +781,3 @@ All lines must be part of the same messages, so prepare it first. Please fulfill a ticket in our [Bug tracker](https://github.com/Rolisteam/DiceParser/issues) system. Or contact us on [discord](https://discordapp.com/invite/MrMrQwX) or any [other ways](http://www.rolisteam.org/contact.html) - - -- cgit v1.2.3-70-g09d2