aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--HelpMe.md92
-rw-r--r--diceparser.cpp49
-rw-r--r--diceparser.h2
-rw-r--r--diceparser.pri2
-rw-r--r--node/dicerollernode.cpp13
-rw-r--r--node/explodedicenode.cpp4
-rw-r--r--node/filternode.cpp4
-rw-r--r--node/forloopnode.cpp103
-rw-r--r--node/forloopnode.h36
-rw-r--r--node/jumpbackwardnode.cpp4
-rw-r--r--node/keepdiceexecnode.cpp4
-rw-r--r--node/mergenode.cpp4
-rw-r--r--node/occurencecountnode.cpp107
-rw-r--r--node/occurencecountnode.h6
-rw-r--r--node/rerolldicenode.cpp4
-rw-r--r--node/uniquenode.cpp4
-rw-r--r--node/valueslistnode.cpp62
-rw-r--r--node/valueslistnode.h24
-rw-r--r--parsingtoolbox.cpp11
-rw-r--r--parsingtoolbox.h2
-rw-r--r--tests/testnode.cpp1
-rw-r--r--tests/tst_dice.cpp14
23 files changed, 448 insertions, 105 deletions
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/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)
-
-
diff --git a/diceparser.cpp b/diceparser.cpp
index 18be076..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"
@@ -176,7 +177,6 @@ bool DiceParser::parseLine(QString str, bool allowAlias)
}
m_command= str;
bool hasInstruction= readInstructionList(str);
-
bool value= hasInstruction;
if(!hasInstruction)
{
@@ -194,7 +194,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;
@@ -233,6 +232,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;
@@ -266,7 +270,7 @@ bool DiceParser::readExpression(QString& str, ExecutionNode*& node)
node= operandNode;
return true;
}
- else if(readOperatorFromNull(str, operandNode))
+ else if(readValuesList(str, operandNode))
{
node= operandNode;
return true;
@@ -316,6 +320,43 @@ 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);
+ }
+ else if(ParsingToolBox::readNumber(var, number))
+ {
+ NumberNode* numberNode= new NumberNode();
+ numberNode->setNumber(number);
+ values->insertValue(numberNode);
+ }
+ }
+ 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<ExportedDiceResult>& 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/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<quint64>(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<quint64>(num) : 0;
+ m_result->setPrevious(result);
+
auto possibleValue= static_cast<quint64>(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;
}
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/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<DiceResult*>(previous->getResult());
+ if(nullptr != prevResult)
+ {
+ m_diceResult->setPrevious(prevResult);
+ QList<Die*> 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 <memory>
+
+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<ExecutionNode> m_internal;
+ DiceResult* m_diceResult;
+};
+
+#endif // FORLOOPNODE_H
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/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<DiceResult*>(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<qint64, qint64>& mapOccurence, QVector<qint64>& 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<qint64, qint64>& 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:
@@ -45,10 +46,15 @@ public:
void setValidator(Validator* validator);
private:
+ void runForStringResult(const std::map<qint64, qint64>& mapOccurence, QVector<qint64>& vec);
+ void runForDiceResult(const std::map<qint64, qint64>& 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
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);
}
diff --git a/node/valueslistnode.cpp b/node/valueslistnode.cpp
new file mode 100644
index 0000000..b31ee84
--- /dev/null
+++ b/node/valueslistnode.cpp
@@ -0,0 +1,62 @@
+#include "valueslistnode.h"
+
+#include "variablenode.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();
+ auto dyna= dynamic_cast<VariableNode*>(node);
+ if(nullptr != dyna)
+ 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<ExecutionNode*> m_data;
+ DiceResult* m_diceResult = nullptr;
+};
+
+#endif // VALUESLISTNODE_H
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<BooleanCondition*>(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<CompositeValidator::LogicOperation>* operators= new QVector<CompositeValidator::LogicOperation>();
@@ -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
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);
diff --git a/tests/tst_dice.cpp b/tests/tst_dice.cpp
index 5d9efc0..81618ca 100644
--- a/tests/tst_dice.cpp
+++ b/tests/tst_dice.cpp
@@ -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()