aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/cli/main.cpp4
-rw-r--r--src/libparser/booleancondition.h1
-rw-r--r--src/libparser/die.cpp4
-rw-r--r--src/libparser/die.h2
-rw-r--r--src/libparser/node/explodedicenode.cpp43
-rw-r--r--src/libparser/node/rerolldicenode.cpp37
-rw-r--r--src/libparser/validatorlist.cpp7
-rw-r--r--src/libparser/validatorlist.h2
-rw-r--r--src/tests/dice/tst_dice.cpp72
9 files changed, 162 insertions, 10 deletions
diff --git a/src/bin/cli/main.cpp b/src/bin/cli/main.cpp
index 2864c27..91fa1ef 100644
--- a/src/bin/cli/main.cpp
+++ b/src/bin/cli/main.cpp
@@ -597,10 +597,6 @@ int main(int argc, char* argv[])
for(auto& cmd : cmdList)
cmd= QUrl::fromPercentEncoding(cmd.toUtf8());
- qDebug() << "cmdList" << cmdList;
- // cmdList << "(1)-1d4e4mk00;300;[$1\u0004$3]k1;0100;200;300;[$1,$2,$3]k1TK\u0004;$1+$1;$2i:[<1]{1}{0}";
- cmdList << "1d4e4mk00;300;100;[$1,$2,$3]k1TK\u0004";
-
QJsonArray aliases;
if(optionParser.isSet(alias))
{
diff --git a/src/libparser/booleancondition.h b/src/libparser/booleancondition.h
index d49c5fe..88f5c07 100644
--- a/src/libparser/booleancondition.h
+++ b/src/libparser/booleancondition.h
@@ -49,7 +49,6 @@ public:
*/
virtual Validator* getCopy() const override;
-private:
qint64 valueToScalar() const;
private:
diff --git a/src/libparser/die.cpp b/src/libparser/die.cpp
index 021ba5e..c1888b3 100644
--- a/src/libparser/die.cpp
+++ b/src/libparser/die.cpp
@@ -165,6 +165,8 @@ void Die::replaceLastValue(qint64 value)
void Die::roll(bool adding)
{
+ if(m_base > m_maxValue)
+ return;
std::uniform_int_distribution<qint64> dist(m_base, m_maxValue);
qint64 value= dist(s_rng);
if((adding) || (m_rollResult.isEmpty()))
@@ -213,7 +215,7 @@ void Die::setBase(qint64 base)
{
m_base= base;
}
-qint64 Die::getBase()
+qint64 Die::getBase() const
{
return m_base;
}
diff --git a/src/libparser/die.h b/src/libparser/die.h
index 48da214..0fe36fd 100644
--- a/src/libparser/die.h
+++ b/src/libparser/die.h
@@ -123,7 +123,7 @@ public:
* @brief setBase
*/
void setBase(qint64);
- qint64 getBase();
+ qint64 getBase() const;
QString getColor() const;
void setColor(const QString& color);
diff --git a/src/libparser/node/explodedicenode.cpp b/src/libparser/node/explodedicenode.cpp
index 136611a..f4c699d 100644
--- a/src/libparser/node/explodedicenode.cpp
+++ b/src/libparser/node/explodedicenode.cpp
@@ -1,5 +1,7 @@
#include "explodedicenode.h"
+#include "booleancondition.h"
#include "diceparser/parsingtoolbox.h"
+#include "validator.h"
#include "validatorlist.h"
ExplodeDiceNode::ExplodeDiceNode() : m_diceResult(new DiceResult())
@@ -21,11 +23,43 @@ void ExplodeDiceNode::run(ExecutionNode* previous)
if(!previous_result)
return;
- for(auto& die : previous_result->getResultList())
+ auto diceList= previous_result->getResultList();
+
+ auto allInvalid= std::all_of(std::begin(diceList), std::end(diceList),
+ [](const Die* die) { return die->getMaxValue() < die->getBase(); });
+
+ qint64 maxVal= 0;
+ if(allInvalid)
+ {
+
+ auto const& list= m_validatorList->validators();
+ auto max= std::max_element(std::begin(list), std::end(list),
+ [](Validator* a, Validator* b)
+ {
+ auto aa= dynamic_cast<BooleanCondition*>(a);
+ auto bb= dynamic_cast<BooleanCondition*>(b);
+
+ if(bb && aa)
+ return aa->valueToScalar() < bb->valueToScalar();
+ else
+ return (!bb && aa);
+ });
+
+ auto maxCondition= dynamic_cast<BooleanCondition*>(*max);
+ if(maxCondition)
+ maxVal= maxCondition->valueToScalar();
+ }
+
+ for(auto& die : diceList)
{
Die* tmpdie= new Die(*die);
m_diceResult->insertResult(tmpdie);
die->displayed();
+ if(allInvalid && maxVal != tmpdie->getMaxValue() && maxVal > tmpdie->getBase())
+ {
+ qInfo() << "Invalid range for explosing dice, set " << maxVal << " as maximum" << tmpdie->getMaxValue();
+ tmpdie->setMaxValue(maxVal);
+ }
}
qint64 limit= -1;
@@ -51,6 +85,13 @@ void ExplodeDiceNode::run(ExecutionNode* previous)
.arg(static_cast<int>(die->getBase()))
.arg(static_cast<int>(die->getMaxValue()))));
+ isValid(die->getBase() > die->getMaxValue(), Dice::ERROR_CODE::ENDLESS_LOOP_ERROR,
+ QObject::tr("Condition (%1) cause an endless loop with dice: %2")
+ .arg(toString(true))
+ .arg(QStringLiteral("d[%1,%2]")
+ .arg(static_cast<int>(die->getBase()))
+ .arg(static_cast<int>(die->getMaxValue()))));
+
hasExploded= true;
if(limit >= 0)
{
diff --git a/src/libparser/node/rerolldicenode.cpp b/src/libparser/node/rerolldicenode.cpp
index 25143ac..7e5bda3 100644
--- a/src/libparser/node/rerolldicenode.cpp
+++ b/src/libparser/node/rerolldicenode.cpp
@@ -1,5 +1,6 @@
#include <diceparser/parsingtoolbox.h>
+#include "booleancondition.h"
#include "rerolldicenode.h"
#include "validatorlist.h"
#include <utility>
@@ -37,7 +38,34 @@ void RerollDiceNode::run(ExecutionNode* previous)
m_result->setPrevious(previous_result);
- for(auto const& die : previous_result->getResultList())
+ QList<Die*>& list1= previous_result->getResultList();
+
+ auto allInvalid= std::all_of(std::begin(list1), std::end(list1),
+ [](const Die* die) { return die->getMaxValue() < die->getBase(); });
+
+ qint64 maxVal= 0;
+ if(allInvalid)
+ {
+
+ auto const& list1= m_validatorList->validators();
+ auto max= std::max_element(std::begin(list1), std::end(list1),
+ [](Validator* a, Validator* b)
+ {
+ auto aa= dynamic_cast<BooleanCondition*>(a);
+ auto bb= dynamic_cast<BooleanCondition*>(b);
+
+ if(bb && aa)
+ return aa->valueToScalar() < bb->valueToScalar();
+ else
+ return (!bb && aa);
+ });
+
+ auto maxCondition= dynamic_cast<BooleanCondition*>(*max);
+ if(maxCondition)
+ maxVal= maxCondition->valueToScalar();
+ }
+
+ for(auto const& die : list1)
{
if(!die)
return;
@@ -45,6 +73,13 @@ void RerollDiceNode::run(ExecutionNode* previous)
Die* tmpdie= new Die(*die);
m_diceResult->insertResult(tmpdie);
die->displayed();
+
+ if(allInvalid && maxVal != tmpdie->getMaxValue() && maxVal > tmpdie->getBase())
+ {
+ qInfo() << "Invalid range for explosing dice, set " << maxVal << " as maximum" << tmpdie->getMaxValue()
+ << tmpdie->getBase();
+ tmpdie->setMaxValue(maxVal);
+ }
}
QList<Die*>& list= m_diceResult->getResultList();
diff --git a/src/libparser/validatorlist.cpp b/src/libparser/validatorlist.cpp
index 17568d1..41bc24f 100644
--- a/src/libparser/validatorlist.cpp
+++ b/src/libparser/validatorlist.cpp
@@ -25,8 +25,8 @@
#include "result/result.h"
#include "validator.h"
#include <QDebug>
-#include <utility>
#include <QLoggingCategory>
+#include <utility>
Q_LOGGING_CATEGORY(DiceCat, "DiceParser")
@@ -456,3 +456,8 @@ ValidatorList* ValidatorList::getCopy() const
val->setValidators(m_validatorList);
return val;
}
+
+const QList<Validator*>& ValidatorList::validators() const
+{
+ return m_validatorList;
+}
diff --git a/src/libparser/validatorlist.h b/src/libparser/validatorlist.h
index ad2c9d4..9248426 100644
--- a/src/libparser/validatorlist.h
+++ b/src/libparser/validatorlist.h
@@ -91,6 +91,8 @@ public:
void validResult(Result* result, bool recursive, bool unlight, std::function<void(Die*, qint64)> functor) const;
+ const QList<Validator*>& validators() const;
+
private:
QVector<Dice::LogicOperation> m_operators;
QList<Validator*> m_validatorList;
diff --git a/src/tests/dice/tst_dice.cpp b/src/tests/dice/tst_dice.cpp
index 2de3bcc..d6b9de3 100644
--- a/src/tests/dice/tst_dice.cpp
+++ b/src/tests/dice/tst_dice.cpp
@@ -24,6 +24,7 @@
#include "diceparser/dicealias.h"
#include "diceparser/diceparser.h"
+#include "diceparser/diceparserhelper.h"
#include "die.h"
// node
@@ -206,6 +207,9 @@ private slots:
void deterministTest();
void deterministTest_data();
+ void listValueWithOption();
+ void listValueWithOption_data();
+
private:
std::unique_ptr<Die> m_die;
std::unique_ptr<DiceParser> m_diceParser;
@@ -1382,6 +1386,74 @@ void TestDice::deterministTest_data()
// 1d6;10d10e10k\$1
}
+void TestDice::listValueWithOption()
+{
+ QFETCH(QString, command);
+ QFETCH(int, results);
+ QFETCH(Dice::CompareOperator, theOperator);
+ QFETCH(bool, error);
+
+ auto parsing= m_diceParser->parseLine(command);
+ if(!error)
+ QVERIFY2(parsing, "parsing");
+
+ if(parsing)
+ m_diceParser->start();
+
+ if(error)
+ {
+ QVERIFY2(!m_diceParser->humanReadableError().isEmpty() || !m_diceParser->humanReadableWarning().isEmpty(),
+ "no error");
+ return;
+ }
+ else
+ {
+ QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
+ QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
+ }
+
+ auto resultCmd= m_diceParser->scalarResultsFromEachInstruction();
+
+ auto resultCommand= resultCmd.at(0);
+
+ switch(theOperator)
+ {
+ case Dice::CompareOperator::GreaterThan:
+ QVERIFY(results < resultCommand);
+ break;
+ case Dice::CompareOperator::LesserThan:
+ QVERIFY(results > resultCommand);
+ break;
+ case Dice::CompareOperator::LesserOrEqual:
+ qDebug() << results << " " << resultCommand;
+ QVERIFY(results >= resultCommand);
+ break;
+ default:
+ break;
+ }
+}
+
+void TestDice::listValueWithOption_data()
+{
+ QTest::addColumn<QString>("command");
+ QTest::addColumn<int>("results");
+ QTest::addColumn<Dice::CompareOperator>("theOperator");
+ QTest::addColumn<bool>("error");
+
+ // explode
+ QTest::addRow("cmd1") << "[10]e10" << 10 << Dice::CompareOperator::GreaterThan << false;
+ QTest::addRow("cmd2") << "[10]e10" << std::numeric_limits<int>::max() << Dice::CompareOperator::LesserThan << false;
+ // add
+ QTest::addRow("cmd3") << "[10]a10" << 10 << Dice::CompareOperator::GreaterThan << false;
+ QTest::addRow("cmd4") << "[10]a10" << 20 << Dice::CompareOperator::LesserOrEqual << false;
+ // reroll
+ QTest::addRow("cmd3") << "[10]r10" << 0 << Dice::CompareOperator::GreaterThan << false;
+ QTest::addRow("cmd4") << "[10]r10" << 11 << Dice::CompareOperator::LesserOrEqual << false;
+ // reroll until
+ QTest::addRow("cmd5") << "[10]R10" << 10 << Dice::CompareOperator::LesserOrEqual << false;
+ QTest::addRow("cmd6") << "[10]R1" << 10 << Dice::CompareOperator::LesserOrEqual << false;
+}
+
void TestDice::cleanupTestCase() {}
QTEST_MAIN(TestDice)