aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libparser/validatorlist.cpp
diff options
context:
space:
mode:
authorRenaud G <renaud@rolisteam.org>2022-04-29 10:48:09 +0200
committerRenaud G <renaud@rolisteam.org>2022-04-29 10:48:09 +0200
commit07c5f6ec23fcf9237a24e71adcfacabce677f818 (patch)
tree588e8c5f82b9163181fad3581f610e6f1d88cba4 /src/libparser/validatorlist.cpp
parenta9153f1615a842cfb9e9bcda4d9071e202618569 (diff)
downloadOneRoll-07c5f6ec23fcf9237a24e71adcfacabce677f818.tar.gz
OneRoll-07c5f6ec23fcf9237a24e71adcfacabce677f818.zip
Change file organization.
Diffstat (limited to 'src/libparser/validatorlist.cpp')
-rw-r--r--src/libparser/validatorlist.cpp453
1 files changed, 453 insertions, 0 deletions
diff --git a/src/libparser/validatorlist.cpp b/src/libparser/validatorlist.cpp
new file mode 100644
index 0000000..f1d1ba4
--- /dev/null
+++ b/src/libparser/validatorlist.cpp
@@ -0,0 +1,453 @@
+/***************************************************************************
+ * Copyright (C) 2014 by Renaud Guezennec *
+ * http://www.rolisteam.org/contact *
+ * *
+ * This file is part of DiceParser *
+ * *
+ * DiceParser is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "validatorlist.h"
+
+#include "result/diceresult.h"
+#include "result/result.h"
+#include "validator.h"
+#include <QDebug>
+#include <utility>
+
+void mergeResultsAsAND(const ValidatorResult& diceList, ValidatorResult& result)
+{
+ ValidatorResult val;
+ for(auto dice : diceList.validDice())
+ {
+ if(result.contains(dice.first) || diceList.allTrue())
+ val.appendValidDice(dice.first, dice.second);
+ }
+ result= val;
+ result.setAllTrue(diceList.allTrue() & result.allTrue());
+}
+
+void mergeResultsAsExeclusiveOR(const ValidatorResult& diceList, ValidatorResult& result)
+{
+ ValidatorResult val;
+ for(auto dice : diceList.validDice())
+ {
+ if(!result.contains(dice.first))
+ val.appendValidDice(dice.first, dice.second);
+ }
+ result= val;
+ result.setAllTrue(diceList.allTrue() ^ result.allTrue());
+}
+
+DiceResult* getDiceResult(Result* result)
+{
+ auto dice= dynamic_cast<DiceResult*>(result);
+ if(nullptr == dice)
+ {
+ auto value= result->getResult(Dice::RESULT_TYPE::SCALAR).toInt();
+ dice= new DiceResult();
+ auto die= new Die();
+ die->setValue(value);
+ dice->insertResult(die);
+ qWarning("Error, no dice result");
+ // TODO: manage error here.
+ }
+ return dice;
+}
+
+//////////////////////////////////
+/// \brief ValidatorResult::ValidatorResult
+///
+///
+///
+/// ////////////////////////////////
+ValidatorResult::ValidatorResult() {}
+
+const std::vector<std::pair<Die*, qint64>>& ValidatorResult::validDice() const
+{
+ return m_validDice;
+}
+
+std::vector<std::pair<Die*, qint64>>& ValidatorResult::validDiceRef()
+{
+ return m_validDice;
+}
+
+void ValidatorResult::appendValidDice(Die* die, qint64 sum)
+{
+ m_validDice.push_back(std::make_pair(die, sum));
+}
+
+void ValidatorResult::setAllTrue(bool allTrue)
+{
+ m_allTrue= allTrue;
+}
+
+bool ValidatorResult::allTrue() const
+{
+ return m_allTrue;
+}
+
+bool ValidatorResult::contains(Die* die)
+{
+ auto it= std::find_if(m_validDice.begin(), m_validDice.end(),
+ [die](const std::pair<Die*, qint64>& pair) { return pair.first == die; });
+
+ return it != m_validDice.end();
+}
+
+////////////////////////////////////
+/// \brief ValidatorList::ValidatorList
+///***
+///
+////////////////////////////////////
+
+ValidatorList::ValidatorList() {}
+
+ValidatorList::~ValidatorList()
+{
+ qDeleteAll(m_validatorList);
+}
+qint64 ValidatorList::hasValid(Die* b, bool recursive, bool unhighlight) const
+{
+ int i= 0;
+ qint64 sum= 0;
+ bool highLight= false;
+ for(auto& validator : m_validatorList)
+ {
+ qint64 val= validator->hasValid(b, recursive, unhighlight);
+ if(i == 0)
+ {
+ sum= val;
+ if(b->isHighlighted())
+ {
+ highLight= b->isHighlighted();
+ }
+ }
+ else
+ {
+ switch(m_operators.at(i - 1))
+ {
+ case Dice::LogicOperation::OR:
+ sum|= val;
+
+ if(highLight)
+ {
+ b->setHighlighted(highLight);
+ }
+ break;
+ case Dice::LogicOperation::EXCLUSIVE_OR:
+ sum^= val; /// @todo may required to be done by hand
+ break;
+ case Dice::LogicOperation::AND:
+ sum&= val;
+ break;
+ default:
+ break;
+ }
+ }
+ ++i;
+ }
+
+ return sum;
+}
+
+QString ValidatorList::toString()
+{
+ QString str= "";
+ /*switch (m_operator)
+ {
+ case Equal:
+ str.append("=");
+ break;
+ case GreaterThan:
+ str.append(">");
+ break;
+ case LesserThan:
+ str.append("<");
+ break;
+ case GreaterOrEqual:
+ str.append(">=");
+ break;
+ case LesserOrEqual:
+ str.append("<=");
+ break;
+ }
+ return QString("[%1%2]").arg(str).arg(m_value);*/
+ return str;
+}
+namespace
+{
+Dice::CONDITION_STATE testAND(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current)
+{
+ if(before == Dice::CONDITION_STATE::UNREACHABLE || current == Dice::CONDITION_STATE::UNREACHABLE)
+ return Dice::CONDITION_STATE::UNREACHABLE;
+ else if(before == Dice::CONDITION_STATE::ALWAYSTRUE && current == Dice::CONDITION_STATE::ALWAYSTRUE)
+ return Dice::CONDITION_STATE::ALWAYSTRUE;
+ else
+ return Dice::CONDITION_STATE::REACHABLE;
+}
+
+Dice::CONDITION_STATE testOR(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current)
+{
+ if(before == Dice::CONDITION_STATE::UNREACHABLE && current == Dice::CONDITION_STATE::UNREACHABLE)
+ return Dice::CONDITION_STATE::UNREACHABLE;
+ else if(before == Dice::CONDITION_STATE::ALWAYSTRUE || current == Dice::CONDITION_STATE::ALWAYSTRUE)
+ return Dice::CONDITION_STATE::ALWAYSTRUE;
+ else
+ return Dice::CONDITION_STATE::REACHABLE;
+}
+
+Dice::CONDITION_STATE testXOR(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current)
+{
+ if(before == current
+ && (before == Dice::CONDITION_STATE::UNREACHABLE || before == Dice::CONDITION_STATE::ALWAYSTRUE))
+ return Dice::CONDITION_STATE::UNREACHABLE;
+ else if((before != current)
+ && (before == Dice::CONDITION_STATE::ALWAYSTRUE || before == Dice::CONDITION_STATE::UNREACHABLE)
+ && (before != Dice::CONDITION_STATE::REACHABLE || current != Dice::CONDITION_STATE::REACHABLE))
+ return Dice::CONDITION_STATE::ALWAYSTRUE;
+ else
+ return Dice::CONDITION_STATE::REACHABLE;
+}
+} // namespace
+
+Dice::CONDITION_STATE ValidatorList::isValidRangeSize(const std::pair<qint64, qint64>& range) const
+{
+ std::vector<Dice::CONDITION_STATE> vec;
+ std::transform(m_validatorList.begin(), m_validatorList.end(), std::back_inserter(vec),
+ [range](Validator* validator) -> Dice::CONDITION_STATE
+ { return validator->isValidRangeSize(range); });
+
+ auto itError= std::find(vec.begin(), vec.end(), Dice::CONDITION_STATE::ERROR_STATE);
+
+ if(vec.size() == 1)
+ return vec.front();
+
+ if((static_cast<int>(vec.size()) != m_operators.size() + 1) || (itError != vec.end()))
+ {
+ return Dice::CONDITION_STATE::ERROR_STATE;
+ }
+
+ std::size_t i= 0;
+ Dice::CONDITION_STATE val= Dice::CONDITION_STATE::ERROR_STATE;
+ for(const auto& op : m_operators)
+ {
+ auto currentState= vec[i + 1];
+ if(i == 0)
+ {
+ val= vec[i];
+ }
+ switch(op)
+ {
+ case Dice::LogicOperation::OR:
+ val= testAND(val, currentState);
+ break;
+ case Dice::LogicOperation::EXCLUSIVE_OR:
+ val= testOR(val, currentState);
+ break;
+ case Dice::LogicOperation::AND:
+ val= testXOR(val, currentState);
+ break;
+ case Dice::LogicOperation::NONE:
+ val= Dice::CONDITION_STATE::ERROR_STATE;
+ break;
+ }
+
+ ++i;
+ }
+ return val;
+}
+
+void ValidatorList::setOperationList(const QVector<Dice::LogicOperation>& m)
+{
+ m_operators= m;
+}
+
+void ValidatorList::setValidators(const QList<Validator*>& valids)
+{
+ qDeleteAll(m_validatorList);
+ m_validatorList= valids;
+}
+
+void ValidatorList::validResult(Result* result, bool recursive, bool unlight,
+ std::function<void(Die*, qint64)> functor) const
+{
+ std::vector<ValidatorResult> validityData;
+ for(auto& validator : m_validatorList)
+ {
+ ValidatorResult validResult;
+ switch(validator->getConditionType())
+ {
+ case Dice::OnScalar:
+ {
+ Die die;
+ auto scalar= result->getResult(Dice::RESULT_TYPE::SCALAR).toInt();
+ die.insertRollValue(scalar);
+ if(validator->hasValid(&die, recursive, unlight))
+ {
+ validResult.setAllTrue(true);
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ break;
+
+ if(m_validatorList.size() > 1)
+ {
+ for(auto const& die : qAsConst(diceResult->getResultList()))
+ {
+ validResult.appendValidDice(die, die->getValue());
+ }
+ }
+ else
+ {
+ validResult.appendValidDice(new Die(die), die.getValue());
+ }
+ }
+ }
+ break;
+ case Dice::OnEach:
+ {
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ break;
+ for(auto const& die : qAsConst(diceResult->getResultList()))
+ {
+ auto score= validator->hasValid(die, recursive, unlight);
+ if(score)
+ {
+ validResult.appendValidDice(die, score);
+ }
+ }
+ }
+ break;
+ case Dice::OnEachValue:
+ {
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ break;
+ for(auto const& die : qAsConst(diceResult->getResultList()))
+ {
+ auto score= validator->hasValid(die, recursive, unlight);
+ if(score)
+ {
+ validResult.appendValidDice(die, score);
+ }
+ }
+ }
+ break;
+ case Dice::AllOfThem:
+ {
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ break;
+ auto diceList= diceResult->getResultList();
+ auto all= std::all_of(diceList.begin(), diceList.end(),
+ [validator, recursive, unlight](Die* die)
+ { return validator->hasValid(die, recursive, unlight); });
+ if(all)
+ {
+ validResult.setAllTrue(true);
+ for(auto die : qAsConst(diceResult->getResultList()))
+ {
+ validResult.appendValidDice(die, die->getValue());
+ }
+ }
+ }
+ break;
+ case Dice::OneOfThem:
+ {
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ break;
+ auto diceList= diceResult->getResultList();
+ auto any= std::any_of(diceList.begin(), diceList.end(),
+ [validator, recursive, unlight](Die* die)
+ { return validator->hasValid(die, recursive, unlight); });
+ if(any)
+ {
+ validResult.setAllTrue(true);
+ for(auto die : qAsConst(diceResult->getResultList()))
+ {
+ validResult.appendValidDice(die, die->getValue());
+ }
+ }
+ }
+ }
+ validityData.push_back(validResult);
+ }
+ if(validityData.empty())
+ return;
+
+ int i= 0;
+ ValidatorResult finalResult;
+
+ for(const auto& vec : validityData)
+ {
+ auto diceList= vec.validDice();
+ if(i == 0)
+ {
+ std::copy(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef()));
+ }
+ else
+ {
+ auto id= i - 1;
+ if(m_operators.size() <= id)
+ continue;
+
+ auto op= m_operators.at(id);
+ switch(op)
+ {
+ case Dice::LogicOperation::OR:
+ std::copy(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef()));
+ break;
+ case Dice::LogicOperation::AND:
+ mergeResultsAsAND(vec, finalResult);
+ break;
+ case Dice::LogicOperation::EXCLUSIVE_OR:
+ mergeResultsAsExeclusiveOR(vec, finalResult);
+ break;
+ case Dice::LogicOperation::NONE:
+ break;
+ }
+ }
+
+ ++i;
+ }
+
+ if(finalResult.allTrue())
+ {
+ DiceResult* diceResult= getDiceResult(result);
+ if(nullptr == diceResult)
+ return;
+ auto diceList= diceResult->getResultList();
+ std::transform(diceList.begin(), diceList.end(), std::back_inserter(finalResult.validDiceRef()),
+ [](Die* die) {
+ return std::pair<Die*, qint64>({die, 0});
+ });
+ }
+
+ for(auto die : finalResult.validDice())
+ {
+ functor(die.first, die.second);
+ }
+}
+
+ValidatorList* ValidatorList::getCopy() const
+{
+ ValidatorList* val= new ValidatorList();
+ val->setOperationList(m_operators);
+ val->setValidators(m_validatorList);
+ return val;
+}