File indexing completed on 2024-04-28 05:36:59

0001 /***************************************************************************
0002  * Copyright (C) 2014 by Renaud Guezennec                                   *
0003  * https://rolisteam.org/contact                      *
0004  *                                                                          *
0005  *  This file is part of DiceParser                                         *
0006  *                                                                          *
0007  * DiceParser is free software; you can redistribute it and/or modify       *
0008  * it under the terms of the GNU General Public License as published by     *
0009  * the Free Software Foundation; either version 2 of the License, or        *
0010  * (at your option) any later version.                                      *
0011  *                                                                          *
0012  * This program is distributed in the hope that it will be useful,          *
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of           *
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the             *
0015  * GNU General Public License for more details.                             *
0016  *                                                                          *
0017  * You should have received a copy of the GNU General Public License        *
0018  * along with this program; if not, write to the                            *
0019  * Free Software Foundation, Inc.,                                          *
0020  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.                 *
0021  ***************************************************************************/
0022 #include "booleancondition.h"
0023 
0024 Dice::CONDITION_STATE testEqual(bool insideRange, const std::pair<qint64, qint64>& range)
0025 {
0026     if(!insideRange)
0027         return Dice::CONDITION_STATE::UNREACHABLE;
0028     else if(insideRange && (range.first == range.second))
0029         return Dice::CONDITION_STATE::ALWAYSTRUE;
0030     else
0031         return Dice::CONDITION_STATE::REACHABLE;
0032 }
0033 
0034 Dice::CONDITION_STATE testGreatherThan(qint64 value, const std::pair<qint64, qint64>& range)
0035 {
0036     if(value >= std::max(range.first, range.second))
0037         return Dice::CONDITION_STATE::UNREACHABLE;
0038     else if(value < std::min(range.first, range.second))
0039         return Dice::CONDITION_STATE::ALWAYSTRUE;
0040     else
0041         return Dice::CONDITION_STATE::REACHABLE;
0042 }
0043 
0044 Dice::CONDITION_STATE testLesserThan(qint64 value, const std::pair<qint64, qint64>& range)
0045 {
0046     if(value <= std::min(range.first, range.second))
0047         return Dice::CONDITION_STATE::UNREACHABLE;
0048     else if(value > std::max(range.first, range.second))
0049         return Dice::CONDITION_STATE::ALWAYSTRUE;
0050     else
0051         return Dice::CONDITION_STATE::REACHABLE;
0052 }
0053 
0054 Dice::CONDITION_STATE testGreaterOrEqual(qint64 value, const std::pair<qint64, qint64>& range)
0055 {
0056     if(value > std::max(range.first, range.second))
0057         return Dice::CONDITION_STATE::UNREACHABLE;
0058     else if(value <= std::min(range.first, range.second))
0059         return Dice::CONDITION_STATE::ALWAYSTRUE;
0060     else
0061         return Dice::CONDITION_STATE::REACHABLE;
0062 }
0063 
0064 Dice::CONDITION_STATE testLesserOrEqual(qint64 value, const std::pair<qint64, qint64>& range)
0065 {
0066     if(value < std::min(range.first, range.second))
0067         return Dice::CONDITION_STATE::UNREACHABLE;
0068     else if(value >= std::max(range.first, range.second))
0069         return Dice::CONDITION_STATE::ALWAYSTRUE;
0070     else
0071         return Dice::CONDITION_STATE::REACHABLE;
0072 }
0073 
0074 Dice::CONDITION_STATE testDifferent(bool inside, const std::pair<qint64, qint64>& range)
0075 {
0076     if(inside && (range.first == range.second))
0077         return Dice::CONDITION_STATE::UNREACHABLE;
0078     else if(!inside)
0079         return Dice::CONDITION_STATE::ALWAYSTRUE;
0080     else
0081         return Dice::CONDITION_STATE::REACHABLE;
0082 }
0083 
0084 BooleanCondition::BooleanCondition() : m_operator(Dice::CompareOperator::Equal) {}
0085 
0086 BooleanCondition::~BooleanCondition()
0087 {
0088     if(m_value != nullptr)
0089     {
0090         delete m_value;
0091         m_value= nullptr;
0092     }
0093 }
0094 qint64 BooleanCondition::hasValid(Die* b, bool recursive, bool unhighlight) const
0095 {
0096     QList<qint64> listValues;
0097     if(m_conditionType == Dice::OnEachValue)
0098     {
0099         listValues.append(b->getValue());
0100     }
0101     else if(recursive)
0102     {
0103         listValues= b->getListValue();
0104     }
0105     else
0106     {
0107         listValues.append(b->getLastRolledValue());
0108     }
0109 
0110     qint64 sum= 0;
0111     auto valueScalar= valueToScalar();
0112     for(qint64& value : listValues)
0113     {
0114         switch(m_operator)
0115         {
0116         case Dice::CompareOperator::Equal:
0117             sum+= (value == valueScalar) ? 1 : 0;
0118             break;
0119         case Dice::CompareOperator::GreaterThan:
0120             sum+= (value > valueScalar) ? 1 : 0;
0121             break;
0122         case Dice::CompareOperator::LesserThan:
0123             sum+= (value < valueScalar) ? 1 : 0;
0124             break;
0125         case Dice::CompareOperator::GreaterOrEqual:
0126             sum+= (value >= valueScalar) ? 1 : 0;
0127             break;
0128         case Dice::CompareOperator::LesserOrEqual:
0129             sum+= (value <= valueScalar) ? 1 : 0;
0130             break;
0131         case Dice::CompareOperator::Different:
0132             sum+= (value != valueScalar) ? 1 : 0;
0133             break;
0134         }
0135     }
0136     if((unhighlight) && (sum == 0))
0137     {
0138         b->setHighlighted(false);
0139     }
0140     else
0141     {
0142         b->setHighlighted(true);
0143     }
0144 
0145     return sum;
0146 }
0147 
0148 void BooleanCondition::setOperator(Dice::CompareOperator m)
0149 {
0150     m_operator= m;
0151 }
0152 
0153 void BooleanCondition::setValueNode(ExecutionNode* v)
0154 {
0155     m_value= v;
0156 }
0157 QString BooleanCondition::toString()
0158 {
0159     QString str("");
0160     switch(m_operator)
0161     {
0162     case Dice::CompareOperator::Equal:
0163         str.append(QStringLiteral("="));
0164         break;
0165     case Dice::CompareOperator::GreaterThan:
0166         str.append(QStringLiteral(">"));
0167         break;
0168     case Dice::CompareOperator::LesserThan:
0169         str.append(QStringLiteral("<"));
0170         break;
0171     case Dice::CompareOperator::GreaterOrEqual:
0172         str.append(QStringLiteral(">="));
0173         break;
0174     case Dice::CompareOperator::LesserOrEqual:
0175         str.append(QStringLiteral("<="));
0176         break;
0177     case Dice::CompareOperator::Different:
0178         str.append(QStringLiteral("!="));
0179         break;
0180     }
0181     return QStringLiteral("[%1%2]").arg(str).arg(valueToScalar());
0182 }
0183 
0184 Dice::CONDITION_STATE BooleanCondition::isValidRangeSize(const std::pair<qint64, qint64>& range) const
0185 {
0186     Dice::CONDITION_STATE state;
0187     auto valueScalar= valueToScalar();
0188     qint64 boundValue= qBound(range.first, valueScalar, range.second);
0189     bool isInsideRange= (boundValue == valueScalar);
0190     switch(m_operator)
0191     {
0192     case Dice::CompareOperator::Equal:
0193         state= testEqual(isInsideRange, range); //(isInsideRange && (range.first != range.second)) ? ;
0194         break;
0195     case Dice::CompareOperator::GreaterThan:
0196         state= testGreatherThan(valueScalar, range);
0197         break;
0198     case Dice::CompareOperator::LesserThan:
0199         state= testLesserThan(valueScalar, range);
0200         break;
0201     case Dice::CompareOperator::GreaterOrEqual:
0202         state= testGreaterOrEqual(valueScalar, range);
0203         break;
0204     case Dice::CompareOperator::LesserOrEqual:
0205         state= testLesserOrEqual(valueScalar, range);
0206         break;
0207     case Dice::CompareOperator::Different:
0208         state= testDifferent(isInsideRange, range);
0209         break;
0210     }
0211     return state;
0212 }
0213 Validator* BooleanCondition::getCopy() const
0214 {
0215     BooleanCondition* val= new BooleanCondition();
0216     val->setOperator(m_operator);
0217     val->setValueNode(m_value->getCopy());
0218     return val;
0219 }
0220 qint64 BooleanCondition::valueToScalar() const
0221 {
0222     if(m_value == nullptr)
0223         return 0;
0224 
0225     m_value->run(nullptr);
0226     auto result= m_value->getResult();
0227     if(result)
0228         return result->getResult(Dice::RESULT_TYPE::SCALAR).toInt();
0229     else
0230         return 0;
0231 }