File indexing completed on 2024-05-12 05:39:28

0001 /*************************************************************************
0002  *   Copyright (C) 2009 by Renaud Guezennec                              *
0003  *                                                                       *
0004  *   https://rolisteam.org/                                           *
0005  *                                                                       *
0006  *   rolisteam is free software; you can redistribute it and/or modify   *
0007  *   it under the terms of the GNU General Public License as published   *
0008  *   by the Free Software Foundation; either version 2 of the License,   *
0009  *   or (at your option) any later version.                              *
0010  *                                                                       *
0011  *   This program is distributed in the hope that it will be useful,     *
0012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of      *
0013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *
0014  *   GNU General Public License for more details.                        *
0015  *                                                                       *
0016  *   You should have received a copy of the GNU General Public License   *
0017  *   along with this program; if not, write to the                       *
0018  *   Free Software Foundation, Inc.,                                     *
0019  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.           *
0020  *************************************************************************/
0021 #include "listsetrollnode.h"
0022 #include "die.h"
0023 
0024 #include <QDebug>
0025 
0026 ListSetRollNode::ListSetRollNode() : m_diceResult(new DiceResult()), m_stringResult(new StringResult()), m_unique(false)
0027 {
0028     m_result= m_stringResult;
0029 }
0030 ListSetRollNode::~ListSetRollNode()
0031 {
0032     if(nullptr != m_diceResult)
0033     {
0034         delete m_diceResult;
0035         m_diceResult= nullptr;
0036     }
0037 }
0038 
0039 QStringList ListSetRollNode::getList() const
0040 {
0041     return m_values;
0042 }
0043 QString ListSetRollNode::toString(bool wl) const
0044 {
0045     if(wl)
0046     {
0047         return QString("%1 [label=\"ListSetRoll list:%2\"]").arg(m_id, m_values.join(","));
0048     }
0049     else
0050     {
0051         return m_id;
0052     }
0053 }
0054 qint64 ListSetRollNode::getPriority() const
0055 {
0056     qint64 priority= 4;
0057     return priority;
0058 }
0059 void ListSetRollNode::run(ExecutionNode* previous)
0060 {
0061     m_previousNode= previous;
0062     if(nullptr != previous)
0063     {
0064         Result* result= previous->getResult();
0065         if(nullptr != result)
0066         {
0067             quint64 diceCount= result->getResult(Dice::RESULT_TYPE::SCALAR).toReal();
0068             if(diceCount > static_cast<quint64>(m_values.size()) && m_unique)
0069             {
0070                 m_errors.insert(Dice::ERROR_CODE::TOO_MANY_DICE,
0071                                 tr("More unique values asked than possible values (L operator)"));
0072             }
0073             else
0074             {
0075                 m_result->setPrevious(result);
0076                 for(quint64 i= 0; i < diceCount; ++i)
0077                 {
0078                     QStringList rollResult;
0079                     Die* die= new Die();
0080                     computeFacesNumber(die);
0081                     die->roll();
0082                     m_diceResult->insertResult(die);
0083                     getValueFromDie(die, rollResult);
0084                     for(auto const& str : qAsConst(rollResult))
0085                     {
0086                         m_stringResult->addText(str);
0087                     }
0088                 }
0089                 m_stringResult->finished();
0090             }
0091             if(nullptr != m_nextNode)
0092             {
0093                 m_nextNode->run(this);
0094             }
0095         }
0096     }
0097 }
0098 void ListSetRollNode::setListValue(QStringList lirs)
0099 {
0100     m_values= lirs;
0101 }
0102 void ListSetRollNode::setUnique(bool u)
0103 {
0104     m_unique= u;
0105 }
0106 void ListSetRollNode::setNoComma(bool b)
0107 {
0108     if(m_stringResult)
0109         m_stringResult->setNoComma(b);
0110 }
0111 void ListSetRollNode::setRangeList(QList<Range>& ranges)
0112 {
0113     m_rangeList= ranges;
0114 }
0115 void ListSetRollNode::computeFacesNumber(Die* die)
0116 {
0117     if(m_rangeList.isEmpty())
0118     {
0119         die->setMaxValue(m_values.size());
0120     }
0121     else
0122     {
0123         Q_ASSERT(m_values.size() == m_rangeList.size());
0124         qint64 max;
0125         int i= 0;
0126         for(Range& range : m_rangeList)
0127         {
0128             if(((i == 0) || (max < range.getEnd())) && (range.isFullyDefined()))
0129             {
0130                 max= range.getEnd();
0131             }
0132             ++i;
0133         }
0134         die->setMaxValue(max);
0135     }
0136 }
0137 void ListSetRollNode::getValueFromDie(Die* die, QStringList& rollResult)
0138 {
0139     if(m_rangeList.isEmpty())
0140     {
0141         if(die->getValue() - 1 < m_values.size())
0142         {
0143             auto str= m_values[die->getValue() - 1];
0144             while(m_unique && rollResult.contains(str))
0145             {
0146                 die->roll(false);
0147                 str= m_values[die->getValue() - 1];
0148             }
0149             rollResult << str;
0150         }
0151     }
0152     else
0153     {
0154         Q_ASSERT(m_values.size() == m_rangeList.size());
0155         bool found= false;
0156         while(!found)
0157         {
0158             int i= 0;
0159             for(Range& range : m_rangeList)
0160             {
0161                 auto it= std::find(m_rangeIndexResult.begin(), m_rangeIndexResult.end(), i);
0162                 auto isValid= range.hasValid(die, false);
0163                 if((isValid && !m_unique) || (isValid && it == m_rangeIndexResult.end()))
0164                 {
0165                     m_rangeIndexResult.push_back(i);
0166                     rollResult << m_values[i];
0167                     found= true;
0168                 }
0169                 ++i;
0170             }
0171             if(!found)
0172             {
0173                 die->roll(false);
0174             }
0175         }
0176     }
0177 }
0178 ExecutionNode* ListSetRollNode::getCopy() const
0179 {
0180     ListSetRollNode* node= new ListSetRollNode();
0181     QList<Range> dataList= m_rangeList;
0182     node->setRangeList(dataList);
0183     node->setUnique(m_unique);
0184     node->setListValue(m_values);
0185     if(nullptr != m_nextNode)
0186     {
0187         node->setNextNode(m_nextNode->getCopy());
0188     }
0189     return node;
0190 }