File indexing completed on 2024-05-12 05:39:27
0001 /*************************************************************************** 0002 * Copyright (C) 2016 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "ifnode.h" 0021 #include "result/diceresult.h" 0022 #include "validatorlist.h" 0023 0024 PartialDiceRollNode::PartialDiceRollNode() : m_diceResult(new DiceResult) 0025 { 0026 m_result= m_diceResult; 0027 } 0028 0029 void PartialDiceRollNode::insertDie(Die* die) 0030 { 0031 m_diceResult->insertResult(die); 0032 } 0033 0034 void PartialDiceRollNode::run(ExecutionNode* previous) 0035 { 0036 m_previousNode= previous; 0037 Result* presult= previous->getResult(); 0038 if(nullptr != presult) 0039 { 0040 m_result->setPrevious(presult); 0041 } 0042 if(nullptr != m_nextNode) 0043 { 0044 m_nextNode->run(this); 0045 } 0046 } 0047 ExecutionNode* PartialDiceRollNode::getCopy() const 0048 { 0049 return new PartialDiceRollNode(); 0050 } 0051 qint64 PartialDiceRollNode::getPriority() const 0052 { 0053 qint64 priority= 4; 0054 return priority; 0055 } 0056 0057 QString PartialDiceRollNode::toString(bool withLabel) const 0058 { 0059 if(withLabel) 0060 { 0061 return QString("%1 [label=\"PartialDiceRollNode \"]").arg(m_id); 0062 } 0063 else 0064 { 0065 return m_id; 0066 } 0067 } 0068 0069 DiceResult* getFirstDiceResult(Result* result) 0070 { 0071 DiceResult* found= nullptr; 0072 0073 if(nullptr == result) 0074 return found; 0075 do 0076 { 0077 found= dynamic_cast<DiceResult*>(result); 0078 result= result->getPrevious(); 0079 } while((nullptr == found) && (result != nullptr)); 0080 0081 return found; 0082 } 0083 0084 IfNode::IfNode() : m_conditionType(Dice::AllOfThem), m_true(nullptr), m_false(nullptr) 0085 { 0086 // m_result = new DiceResult(); 0087 } 0088 0089 IfNode::~IfNode() 0090 { 0091 m_result= nullptr; 0092 } 0093 0094 void IfNode::run(ExecutionNode* previous) 0095 { 0096 m_previousNode= previous; 0097 if(nullptr == previous) 0098 { 0099 return; 0100 } 0101 ExecutionNode* previousLoop= previous; 0102 ExecutionNode* nextNode= nullptr; 0103 bool runNext= (nullptr == m_nextNode) ? false : true; 0104 Result* previousResult= previous->getResult(); 0105 m_result= previousResult->getCopy(); 0106 0107 if(nullptr != m_result) 0108 { 0109 qreal value= previousResult->getResult(Dice::RESULT_TYPE::SCALAR).toReal(); 0110 0111 if(nullptr != m_validatorList) 0112 { 0113 DiceResult* previousDiceResult= getFirstDiceResult(previousResult); 0114 if(nullptr != previousDiceResult) 0115 { 0116 QList<Die*> diceList= previousDiceResult->getResultList(); 0117 0118 if(m_conditionType == Dice::OnEach) 0119 { 0120 for(Die* dice : diceList) 0121 { 0122 auto diceNode= new PartialDiceRollNode(); 0123 diceNode->insertDie(new Die(*dice)); 0124 if(m_validatorList->hasValid(dice, true, true)) 0125 { 0126 nextNode= (nullptr == m_true) ? nullptr : m_true->getCopy(); 0127 } 0128 else 0129 { 0130 nextNode= (nullptr == m_false) ? nullptr : m_false->getCopy(); 0131 } 0132 0133 if(nullptr != nextNode) 0134 { 0135 if(nullptr == previousLoop->getNextNode()) 0136 { 0137 previousLoop->setNextNode(nextNode); 0138 } 0139 if(nullptr == m_nextNode) 0140 { 0141 m_nextNode= nextNode; 0142 } 0143 diceNode->setNextNode(nextNode); 0144 diceNode->run(previousLoop); 0145 previousLoop= getLeafNode(nextNode); 0146 } 0147 } 0148 } 0149 else if((m_conditionType == Dice::OneOfThem) || (m_conditionType == Dice::AllOfThem)) 0150 { 0151 bool trueForAll= true; 0152 bool falseForAll= true; 0153 0154 bool oneIsTrue= false; 0155 bool oneIsFalse= false; 0156 0157 for(Die* dice : diceList) 0158 { 0159 bool result= m_validatorList->hasValid(dice, true, true); 0160 trueForAll= trueForAll ? result : false; 0161 falseForAll= falseForAll ? result : false; 0162 0163 oneIsTrue|= result; 0164 oneIsFalse= !result ? true : oneIsFalse; 0165 } 0166 if(m_conditionType == Dice::OneOfThem) 0167 { 0168 if(oneIsTrue) 0169 { 0170 nextNode= (nullptr == m_true) ? nullptr : m_true->getCopy(); 0171 } 0172 else // if(oneIsFalse) 0173 { 0174 nextNode= (nullptr == m_false) ? nullptr : m_false->getCopy(); 0175 } 0176 } 0177 else if(m_conditionType == Dice::AllOfThem) 0178 { 0179 if(trueForAll) 0180 { 0181 nextNode= (nullptr == m_true) ? nullptr : m_true->getCopy(); 0182 } 0183 else // if(falseForAll) 0184 { 0185 nextNode= (nullptr == m_false) ? nullptr : m_false->getCopy(); 0186 } 0187 } 0188 0189 if(nullptr != nextNode) 0190 { 0191 if(nullptr == m_nextNode) 0192 { 0193 m_nextNode= nextNode; 0194 } 0195 nextNode->run(previousLoop); 0196 previousLoop= getLeafNode(nextNode); 0197 } 0198 } 0199 } 0200 0201 if(m_conditionType == Dice::OnScalar) 0202 { 0203 Die dice; 0204 auto val= static_cast<qint64>(value); 0205 dice.setValue(val); 0206 dice.insertRollValue(val); 0207 dice.setMaxValue(val); 0208 if(m_validatorList->hasValid(&dice, true, true)) 0209 { 0210 nextNode= m_true; 0211 } 0212 else 0213 { 0214 nextNode= m_false; 0215 } 0216 if(nullptr != nextNode) 0217 { 0218 if(nullptr == m_nextNode) 0219 { 0220 m_nextNode= nextNode; 0221 } 0222 nextNode->run(previousLoop); 0223 previousLoop= getLeafNode(nextNode); 0224 } 0225 } 0226 } 0227 } 0228 0229 if((nullptr != m_nextNode) && (runNext)) 0230 { 0231 m_nextNode->run(previousLoop); 0232 } 0233 } 0234 0235 void IfNode::setValidatorList(ValidatorList* val) 0236 { 0237 m_validatorList= val; 0238 } 0239 void IfNode::setInstructionTrue(ExecutionNode* node) 0240 { 0241 m_true= node; 0242 } 0243 0244 void IfNode::setInstructionFalse(ExecutionNode* node) 0245 { 0246 m_false= node; 0247 } 0248 void IfNode::generateDotTree(QString& s) 0249 { 0250 s.append(toString(true)); 0251 s.append(";\n"); 0252 0253 if((nullptr != m_true) && (m_true != m_nextNode)) 0254 { 0255 s.append(toString(false)); 0256 s.append(" -> "); 0257 s.append(m_true->toString(false)); 0258 s.append("[label=\"true" + m_validatorList->toString() + "\"];\n"); 0259 0260 m_true->generateDotTree(s); 0261 } 0262 if((nullptr != m_false) && (m_false != m_nextNode)) 0263 { 0264 s.append(toString(false)); 0265 s.append(" -> "); 0266 s.append(m_false->toString(false)); 0267 s.append("[label=\"false\"];\n"); 0268 m_false->generateDotTree(s); 0269 } 0270 0271 if(nullptr != m_nextNode) 0272 { 0273 s.append(toString(false)); 0274 s.append(" -> "); 0275 s.append(m_nextNode->toString(false)); 0276 s.append("[label=\"next\"];\n"); 0277 m_nextNode->generateDotTree(s); 0278 } 0279 else 0280 { 0281 s.append(toString(false)); 0282 s.append(" -> "); 0283 s.append("nullptr;\n"); 0284 0285 if(nullptr != m_result) 0286 { 0287 s.append(toString(false)); 0288 s.append(" ->"); 0289 s.append(m_result->toString(false)); 0290 s.append(" [label=\"Result\"];\n"); 0291 m_result->generateDotTree(s); 0292 } 0293 } 0294 } 0295 0296 QString IfNode::toString(bool wl) const 0297 { 0298 if(wl) 0299 { 0300 return QString("%1 [label=\"IfNode\"]").arg(m_id); 0301 } 0302 else 0303 { 0304 return m_id; 0305 } 0306 } 0307 0308 qint64 IfNode::getPriority() const 0309 { 0310 return 0; 0311 } 0312 0313 ExecutionNode* IfNode::getLeafNode(ExecutionNode* node) 0314 { 0315 ExecutionNode* next= node; 0316 while(nullptr != next->getNextNode()) 0317 { 0318 next= next->getNextNode(); 0319 } 0320 return next; 0321 } 0322 0323 Dice::ConditionType IfNode::getConditionType() const 0324 { 0325 return m_conditionType; 0326 } 0327 0328 void IfNode::setConditionType(const Dice::ConditionType& conditionType) 0329 { 0330 m_conditionType= conditionType; 0331 } 0332 ExecutionNode* IfNode::getCopy() const 0333 { 0334 IfNode* node= new IfNode(); 0335 0336 node->setConditionType(m_conditionType); 0337 if(nullptr != m_validatorList) 0338 { 0339 node->setValidatorList(m_validatorList->getCopy()); 0340 } 0341 if(nullptr != m_false) 0342 { 0343 node->setInstructionFalse(m_false->getCopy()); 0344 } 0345 if(nullptr != m_true) 0346 { 0347 node->setInstructionTrue(m_true->getCopy()); 0348 } 0349 if(nullptr != m_nextNode) 0350 { 0351 node->setNextNode(m_nextNode->getCopy()); 0352 } 0353 return node; 0354 }