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 "compositevalidator.h" 0023 0024 #include <map> 0025 0026 CompositeValidator::CompositeValidator() {} 0027 0028 CompositeValidator::~CompositeValidator() 0029 { 0030 qDeleteAll(m_validatorList); 0031 } 0032 qint64 CompositeValidator::hasValid(Die* b, bool recursive, bool unhighlight) const 0033 { 0034 int i= 0; 0035 qint64 sum= 0; 0036 bool highLight= false; 0037 for(auto& validator : m_validatorList) 0038 { 0039 qint64 val= validator->hasValid(b, recursive, unhighlight); 0040 if(i == 0) 0041 { 0042 sum= val; 0043 if(b->isHighlighted()) 0044 { 0045 highLight= b->isHighlighted(); 0046 } 0047 } 0048 else 0049 { 0050 switch(m_operators.at(i - 1)) 0051 { 0052 case OR: 0053 sum|= val; 0054 0055 if(highLight) 0056 { 0057 b->setHighlighted(highLight); 0058 } 0059 break; 0060 case EXCLUSIVE_OR: 0061 sum^= val; /// @todo may required to be done by hand 0062 break; 0063 case AND: 0064 sum&= val; 0065 break; 0066 default: 0067 break; 0068 } 0069 } 0070 ++i; 0071 } 0072 0073 return sum; 0074 } 0075 0076 QString CompositeValidator::toString() 0077 { 0078 // m_validatorList 0079 QStringList validatorsTextList; 0080 std::transform(m_validatorList.begin(), m_validatorList.end(), std::back_inserter(validatorsTextList), 0081 [](Validator* validator) { return validator->toString(); }); 0082 QStringList operatorTextList; 0083 std::transform( 0084 m_operators.begin(), m_operators.end(), std::back_inserter(operatorTextList), [](LogicOperation validator) { 0085 static std::map<LogicOperation, QString> map({{OR, "|"}, {EXCLUSIVE_OR, "^"}, {AND, "&"}, {NONE, ""}}); 0086 return map[validator]; 0087 }); 0088 0089 if(validatorsTextList.size() - 1 != operatorTextList.size()) 0090 return QString("Error - operator and validator count don't fit"); 0091 0092 QStringList result; 0093 int i= 0; 0094 for(auto text : validatorsTextList) 0095 { 0096 result << text << operatorTextList[i]; 0097 0098 ++i; 0099 } 0100 return result.join(" "); 0101 } 0102 0103 Dice::CONDITION_STATE testAND(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current) 0104 { 0105 if(before == Dice::CONDITION_STATE::UNREACHABLE || current == Dice::CONDITION_STATE::UNREACHABLE) 0106 return Dice::CONDITION_STATE::UNREACHABLE; 0107 else if(before == Dice::CONDITION_STATE::ALWAYSTRUE && current == Dice::CONDITION_STATE::ALWAYSTRUE) 0108 return Dice::CONDITION_STATE::ALWAYSTRUE; 0109 else 0110 return Dice::CONDITION_STATE::REACHABLE; 0111 } 0112 0113 Dice::CONDITION_STATE testOR(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current) 0114 { 0115 if(before == Dice::CONDITION_STATE::UNREACHABLE && current == Dice::CONDITION_STATE::UNREACHABLE) 0116 return Dice::CONDITION_STATE::UNREACHABLE; 0117 else if(before == Dice::CONDITION_STATE::ALWAYSTRUE || current == Dice::CONDITION_STATE::ALWAYSTRUE) 0118 return Dice::CONDITION_STATE::ALWAYSTRUE; 0119 else 0120 return Dice::CONDITION_STATE::REACHABLE; 0121 } 0122 0123 Dice::CONDITION_STATE testXOR(Dice::CONDITION_STATE before, Dice::CONDITION_STATE current) 0124 { 0125 if(before == current 0126 && (before == Dice::CONDITION_STATE::UNREACHABLE || before == Dice::CONDITION_STATE::ALWAYSTRUE)) 0127 return Dice::CONDITION_STATE::UNREACHABLE; 0128 else if((before != current) 0129 && (before == Dice::CONDITION_STATE::ALWAYSTRUE || before == Dice::CONDITION_STATE::UNREACHABLE) 0130 && (before != Dice::CONDITION_STATE::REACHABLE || current != Dice::CONDITION_STATE::REACHABLE)) 0131 return Dice::CONDITION_STATE::ALWAYSTRUE; 0132 else 0133 return Dice::CONDITION_STATE::REACHABLE; 0134 } 0135 0136 Dice::CONDITION_STATE CompositeValidator::isValidRangeSize(const std::pair<qint64, qint64>& range) const 0137 { 0138 std::vector<Dice::CONDITION_STATE> vec; 0139 std::transform( 0140 m_validatorList.begin(), m_validatorList.end(), std::back_inserter(vec), 0141 [range](Validator* validator) -> Dice::CONDITION_STATE { return validator->isValidRangeSize(range); }); 0142 0143 auto itError= std::find(vec.begin(), vec.end(), Dice::CONDITION_STATE::ERROR_STATE); 0144 0145 if((static_cast<int>(vec.size()) != m_operators.size() + 1) || (itError != vec.end())) 0146 { 0147 return Dice::CONDITION_STATE::ERROR_STATE; 0148 } 0149 0150 std::size_t i= 0; 0151 Dice::CONDITION_STATE val= Dice::CONDITION_STATE::ERROR_STATE; 0152 for(const auto& op : m_operators) 0153 { 0154 auto currentState= vec[i + 1]; 0155 if(i == 0) 0156 { 0157 val= vec[i]; 0158 } 0159 switch(op) 0160 { 0161 case OR: 0162 val= testAND(val, currentState); 0163 break; 0164 case EXCLUSIVE_OR: 0165 val= testOR(val, currentState); 0166 break; 0167 case AND: 0168 val= testXOR(val, currentState); 0169 break; 0170 case NONE: 0171 val= Dice::CONDITION_STATE::ERROR_STATE; 0172 break; 0173 } 0174 0175 ++i; 0176 } 0177 return val; 0178 } 0179 0180 void CompositeValidator::setOperationList(const QVector<LogicOperation>& m) 0181 { 0182 m_operators= m; 0183 } 0184 0185 void CompositeValidator::setValidatorList(const QList<Validator*>& valids) 0186 { 0187 qDeleteAll(m_validatorList); 0188 m_validatorList= valids; 0189 } 0190 Validator* CompositeValidator::getCopy() const 0191 { 0192 CompositeValidator* val= new CompositeValidator(); 0193 val->setOperationList(m_operators); 0194 val->setValidatorList(m_validatorList); 0195 return val; 0196 }