diff options
| -rw-r--r-- | diceParser.pro | 27 | ||||
| -rw-r--r-- | diceparser.cpp | 179 | ||||
| -rw-r--r-- | diceparser.h | 41 | ||||
| -rw-r--r-- | diceresult.cpp | 24 | ||||
| -rw-r--r-- | diceresult.h | 19 | ||||
| -rw-r--r-- | main.cpp | 26 | ||||
| -rw-r--r-- | node/dicerollernode.cpp | 30 | ||||
| -rw-r--r-- | node/dicerollernode.h | 25 | ||||
| -rw-r--r-- | node/executionnode.cpp | 24 | ||||
| -rw-r--r-- | node/executionnode.h | 20 | ||||
| -rw-r--r-- | node/node.pri | 15 | ||||
| -rw-r--r-- | node/numbernode.cpp | 19 | ||||
| -rw-r--r-- | node/numbernode.h | 17 | ||||
| -rw-r--r-- | node/rerolldicenode.cpp | 25 | ||||
| -rw-r--r-- | node/rerolldicenode.h | 22 | ||||
| -rw-r--r-- | node/scalaroperatornode.cpp | 91 | ||||
| -rw-r--r-- | node/scalaroperatornode.h | 32 | ||||
| -rw-r--r-- | node/startingnode.cpp | 14 | ||||
| -rw-r--r-- | node/startingnode.h | 14 |
19 files changed, 664 insertions, 0 deletions
diff --git a/diceParser.pro b/diceParser.pro new file mode 100644 index 0000000..dcf1b5b --- /dev/null +++ b/diceParser.pro @@ -0,0 +1,27 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2013-12-24T13:06:36 +# +#------------------------------------------------- + +QT += core + +QT -= gui + +include(node/node.pri) + +TARGET = diceParser +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + + +SOURCES += main.cpp \ + diceparser.cpp \ + diceresult.cpp \ + + +HEADERS += \ + diceparser.h \ + diceresult.h \ diff --git a/diceparser.cpp b/diceparser.cpp new file mode 100644 index 0000000..6096a4d --- /dev/null +++ b/diceparser.cpp @@ -0,0 +1,179 @@ +#include "diceparser.h" +#include <QDebug> +#include <QStringList> + +#include "node/dicerollernode.h" +#include "node/startingnode.h" +#include "node/scalaroperatornode.h" +#include "node/numbernode.h" + +DiceParser::DiceParser() +{ + m_mapDiceOp = new QMap<QString,DiceOperator>(); + m_mapDiceOp->insert("D",D); +} + +void DiceParser::setCurrentNode(ExecutionNode* node) +{ + ExecutionNode* next = node; + while(NULL != next->getNextNode() ) + { + next = next->getNextNode(); + } + m_current = next; +} + +void DiceParser::parseLine(QString str) +{ + m_start = new StartingNode(); + m_current = m_start; + bool keepParsing = true; + ExecutionNode* execNode=NULL; + keepParsing = readDiceExpression(str,execNode); + + m_current->setNextNode(execNode); + setCurrentNode(execNode); + + execNode=NULL; + keepParsing =!str.isEmpty(); + while(keepParsing) + { + keepParsing = readOperator(str); + +// if(keepParsing) +// { +// keepParsing = readDiceExpression(str,execNode); + +// m_current->setNextNode(execNode); +// m_current= execNode; + +// if(keepParsing) +// { +// keepParsing =!str.isEmpty(); +// } +// } + } + + m_start->run(); + ExecutionNode* next = m_start; + while(NULL != next->getNextNode() ) + { + next = next->getNextNode(); + } + qDebug() << "list:" <<next->getResult()->getResultList() << "sum" <<next->getResult()->getSum() ; +} +bool DiceParser::readNumber(QString& str, int& myNumber) +{ + if(str.isEmpty()) + return false; + + QString number; + int i=0; + + while(i<str.length() && str[i].isNumber()) + { + number+=str[i]; + ++i; + } + + if(number.isEmpty()) + return false; + + bool ok; + myNumber = number.toInt(&ok); + if(ok) + { + str=str.remove(0,number.size()); + return true; + } + return false; +} + +bool DiceParser::readDice(QString& str,Dice& dice) +{ + DiceOperator myOperator; + if(readDiceOperator(str,myOperator)) + { + int num; + if(readNumber(str,num)) + { + dice.m_diceOp = myOperator; + dice.m_faces = num; + return true; + } + } + + return false; + +} +bool DiceParser::readDiceOperator(QString& str,DiceOperator& op) +{ + QStringList listKey = m_mapDiceOp->keys(); + foreach(QString key, listKey) + { + if(str.startsWith(key,Qt::CaseInsensitive)) + { + str=str.remove(0,key.size()); + op = m_mapDiceOp->value(key); + return true; + } + } + return false; +} +bool DiceParser::readDiceExpression(QString& str,ExecutionNode* & node) +{ + int number=1; + bool hasRead = readNumber(str,number); + + NumberNode* numberNode = new NumberNode(); + numberNode->setNumber(number); + + + Dice myDice; + if(readDice(str,myDice)) + { + DiceRollerNode* next = new DiceRollerNode(myDice.m_faces); + + numberNode->setNextNode(next); + + node = numberNode; + + return true; + } + else if(hasRead) + { + node = numberNode; + return true; + } + else + { + qDebug() << "error" << number << str; + return false; + } + +} +bool DiceParser::readOperator(QString& str) +{ + if(str.isEmpty()) + { + return false; + } + + ScalarOperatorNode* node = new ScalarOperatorNode(); + if(node->setOperatorChar(str[0])) + { + + ExecutionNode* nodeExec = NULL; + str=str.remove(0,1);//removal of one character + if(readDiceExpression(str,nodeExec)) + { + + node->setInternalNode(nodeExec); + m_current->setNextNode(node); + m_current= node; + + return true; + } + } + return false; +} diff --git a/diceparser.h b/diceparser.h new file mode 100644 index 0000000..022f95e --- /dev/null +++ b/diceparser.h @@ -0,0 +1,41 @@ +#ifndef DICEPARSER_H +#define DICEPARSER_H + +#include <QString> +#include <QMap> +#include "node/executionnode.h" + +class Dice; + +class DiceParser +{ + +public: + enum DiceOperator {D}; + enum MathOperator {K,k,r,e}; + DiceParser(); + void parseLine(QString str); + +private: + bool readNumber(QString& str, int& myNumber); + bool readDice(QString& str,Dice&); + bool readDiceOperator(QString&,DiceOperator&); + bool readDiceExpression(QString&,ExecutionNode* & node); + bool readOperator(QString&); + + void setCurrentNode(ExecutionNode* node); + +private: + QMap<QString,DiceOperator>* m_mapDiceOp; + ExecutionNode* m_start; + ExecutionNode* m_current; +}; + +class Dice +{ +public: + DiceParser::DiceOperator m_diceOp; + int m_faces; +}; + +#endif // DICEPARSER_H diff --git a/diceresult.cpp b/diceresult.cpp new file mode 100644 index 0000000..dfdd765 --- /dev/null +++ b/diceresult.cpp @@ -0,0 +1,24 @@ +#include "diceresult.h" + +DiceResult::DiceResult() +{ + +} +void DiceResult::insertResult(qint64 die) +{ + m_diceValues.append(die); +} +QList<qint64>& DiceResult::getResultList() +{ + return m_diceValues; +} +qint64 DiceResult::getSum() +{ + qint64 sum=0; + foreach (qint64 tmp, m_diceValues) + { + sum+=tmp; + } + return sum; +} + diff --git a/diceresult.h b/diceresult.h new file mode 100644 index 0000000..a9d36a3 --- /dev/null +++ b/diceresult.h @@ -0,0 +1,19 @@ +#ifndef DICERESULT_H +#define DICERESULT_H +#include <QList> + +class DiceResult +{ +public: + DiceResult(); + + qint64 getSum(); + QList<qint64>& getResultList(); + void insertResult(qint64); + + +private: + QList<qint64> m_diceValues; +}; + +#endif // DICERESULT_H diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..479ac8a --- /dev/null +++ b/main.cpp @@ -0,0 +1,26 @@ +#include <QCoreApplication> + +#include "diceparser.h" + +int main(int argc, char *argv[]) +{ + // QCoreApplication a(argc, argv); + DiceParser* myParser = new DiceParser(); + + myParser->parseLine("3D100"); + myParser->parseLine("3D100"); + //myParser->parseLine("100291D66666666"); + //myParser->parseLine("10D10g3"); + //myParser->parseLine("10g3"); + myParser->parseLine("1D8"); + myParser->parseLine("1D8+2D6+7"); + myParser->parseLine("D25"); + myParser->parseLine("8+8"); + myParser->parseLine("8-88"); + myParser->parseLine("100*28"); + myParser->parseLine("100/28"); + myParser->parseLine("100/8"); + myParser->parseLine("100*3"); + //return a.exec(); + return 0; +} diff --git a/node/dicerollernode.cpp b/node/dicerollernode.cpp new file mode 100644 index 0000000..c21b53c --- /dev/null +++ b/node/dicerollernode.cpp @@ -0,0 +1,30 @@ +#include "dicerollernode.h" + +#include <QDateTime> +#include <QDebug> + +DiceRollerNode::DiceRollerNode(quint64 faces) + : m_faces(faces) +{ + uint seed = quintptr(this) + QDateTime::currentDateTime().toMSecsSinceEpoch(); + qsrand(seed); +} +void DiceRollerNode::run(ExecutionNode* previous) +{ + if(NULL!=previous) + { + m_diceCount = previous->getResult()->getSum(); + for(quint64 i=0; i < m_diceCount ; ++i) + { + m_result.insertResult(rollDice()); + } + if(NULL!=m_nextNode) + { + m_nextNode->run(this); + } + } +} +quint64 DiceRollerNode::rollDice() +{ + return (qrand()%m_faces)+1; +} diff --git a/node/dicerollernode.h b/node/dicerollernode.h new file mode 100644 index 0000000..172d09d --- /dev/null +++ b/node/dicerollernode.h @@ -0,0 +1,25 @@ +#ifndef DICEROLLERNODE_H +#define DICEROLLERNODE_H + +#include "executionnode.h" + +class DiceRollerNode : public ExecutionNode +{ +public: + DiceRollerNode(quint64 faces); + + virtual void run(ExecutionNode*); + + //private method +private: + quint64 rollDice(); + + +//private members +private: + quint64 m_diceCount; + quint64 m_faces; /// faces + +}; + +#endif // DICEROLLERNODE_H diff --git a/node/executionnode.cpp b/node/executionnode.cpp new file mode 100644 index 0000000..cf1826d --- /dev/null +++ b/node/executionnode.cpp @@ -0,0 +1,24 @@ +#include "executionnode.h" + +ExecutionNode::ExecutionNode() + : m_nextNode(NULL) +{ + +} +ExecutionNode::~ExecutionNode() +{ + +} + +DiceResult* ExecutionNode::getResult() +{ + return &m_result; +} +void ExecutionNode::setNextNode(ExecutionNode* node) +{ + m_nextNode = node; +} +ExecutionNode* ExecutionNode::getNextNode() +{ + return m_nextNode; +} diff --git a/node/executionnode.h b/node/executionnode.h new file mode 100644 index 0000000..2d81556 --- /dev/null +++ b/node/executionnode.h @@ -0,0 +1,20 @@ +#ifndef EXECUTIONNODE_H +#define EXECUTIONNODE_H + +#include "diceresult.h" + +class ExecutionNode +{ +public: + ExecutionNode(); + virtual ~ExecutionNode(); + virtual void run(ExecutionNode* previous = NULL)=0; + DiceResult* getResult(); + void setNextNode(ExecutionNode*); + ExecutionNode* getNextNode(); +protected: + DiceResult m_result; + ExecutionNode* m_nextNode; +}; + +#endif // EXECUTIONNODE_H diff --git a/node/node.pri b/node/node.pri new file mode 100644 index 0000000..c3e1d65 --- /dev/null +++ b/node/node.pri @@ -0,0 +1,15 @@ +HEADERS += \ + node/dicerollernode.h \ + node/executionnode.h \ + node/rerolldicenode.h \ + node/startingnode.h \ + node/scalaroperatornode.h \ + node/numbernode.h + +SOURCES += \ + node/dicerollernode.cpp \ + node/executionnode.cpp \ + node/startingnode.cpp \ + node/rerolldicenode.cpp \ + node/scalaroperatornode.cpp \ + node/numbernode.cpp diff --git a/node/numbernode.cpp b/node/numbernode.cpp new file mode 100644 index 0000000..690918a --- /dev/null +++ b/node/numbernode.cpp @@ -0,0 +1,19 @@ +#include "numbernode.h" + +NumberNode::NumberNode() +{ + +} +void NumberNode::run(ExecutionNode* ) +{ + if(NULL!=m_nextNode) + { + m_nextNode->run(this); + } +} + +void NumberNode::setNumber(qint64 a) +{ + m_result.insertResult(a); + m_number = a; +} diff --git a/node/numbernode.h b/node/numbernode.h new file mode 100644 index 0000000..ad472c6 --- /dev/null +++ b/node/numbernode.h @@ -0,0 +1,17 @@ +#ifndef NUMBERNODE_H +#define NUMBERNODE_H +#include "node/executionnode.h" + +class NumberNode : public ExecutionNode +{ +public: + NumberNode(); + void run(ExecutionNode* previous); + void setNumber(qint64); + +private: + qint64 m_number; + +}; + +#endif // NUMBERNODE_H diff --git a/node/rerolldicenode.cpp b/node/rerolldicenode.cpp new file mode 100644 index 0000000..45f27de --- /dev/null +++ b/node/rerolldicenode.cpp @@ -0,0 +1,25 @@ +#include "rerolldicenode.h" + +RerollDiceNode::RerollDiceNode(ExecutionNode* previous) + : m_previous(previous) +{ + +} +void RerollDiceNode::run() +{ + if((NULL!=m_previous)&&(NULL!=m_previous->getResult())) + { + QList<qint64> list = m_previous->getResult()->getResultList(); + + + for(qint64 i=0; i < list.size() ; ++i) + { + // m_result.insertResult(rollDice()); + } + if(NULL!=m_nextNode) + { + m_nextNode->run(this); + } + } +} + diff --git a/node/rerolldicenode.h b/node/rerolldicenode.h new file mode 100644 index 0000000..90dc81a --- /dev/null +++ b/node/rerolldicenode.h @@ -0,0 +1,22 @@ +#ifndef REROLLDICENODE_H +#define REROLLDICENODE_H + + +#include "executionnode.h" + +/** + * @brief The RerollDiceNode class reroll dice given a condition and replace(or add) the result. + */ +class RerollDiceNode : public ExecutionNode +{ + +public: + enum ReRollMode {EQUAL,LESSER,GREATER}; + RerollDiceNode(ExecutionNode* previous); + + virtual void run(); +private: + ExecutionNode* m_previous; +}; + +#endif // REROLLDICENODE_H diff --git a/node/scalaroperatornode.cpp b/node/scalaroperatornode.cpp new file mode 100644 index 0000000..e8a2ec0 --- /dev/null +++ b/node/scalaroperatornode.cpp @@ -0,0 +1,91 @@ +#include "scalaroperatornode.h" + +#include <QDebug> + +ScalarOperatorNode::ScalarOperatorNode() + : m_internalNode(NULL) +{ + m_scalarOperationList.insert('+',PLUS); + m_scalarOperationList.insert('-',MINUS); + m_scalarOperationList.insert('x',MULTIPLICATION); + m_scalarOperationList.insert('*',MULTIPLICATION); + m_scalarOperationList.insert('/',DIVIDE); + m_scalarOperationList.insert('÷',DIVIDE); +} + +void ScalarOperatorNode::run(ExecutionNode* previous) +{ + if(NULL!=m_internalNode) + { + m_internalNode->run(this); + } + if(NULL!=previous) + { + DiceResult* previousResult = previous->getResult(); + ExecutionNode* internal = m_internalNode; + while(NULL != internal->getNextNode() ) + { + internal = internal->getNextNode(); + } + DiceResult* internalResult = internal->getResult(); + + switch(m_myOperator) + { + case PLUS: + m_result.insertResult(add(previousResult->getSum(),internalResult->getSum())); + break; + case MINUS: + m_result.insertResult(substract(previousResult->getSum(),internalResult->getSum())); + break; + case MULTIPLICATION: + m_result.insertResult(multiple(previousResult->getSum(),internalResult->getSum())); + break; + case DIVIDE: + m_result.insertResult(divide(previousResult->getSum(),internalResult->getSum())); + break; + default: + break; + + } + + if(NULL!=m_nextNode) + { + m_nextNode->run(this); + } + } + +} +bool ScalarOperatorNode::setOperatorChar(QChar c) +{ + if(m_scalarOperationList.contains(c)) + { + m_myOperator = m_scalarOperationList.value(c); + return true; + } + return false; +} + + +void ScalarOperatorNode::setInternalNode(ExecutionNode* node) +{ + m_internalNode = node; +} +qint64 ScalarOperatorNode::add(qint64 a,qint64 b) +{ + return a+b; +} + +qint64 ScalarOperatorNode::substract(qint64 a,qint64 b) +{ + return a-b; +} + +qint64 ScalarOperatorNode::divide(qint64 a,qint64 b) +{ + return a/b; +} + +qint64 ScalarOperatorNode::multiple(qint64 a,qint64 b) +{ + return a*b; +} diff --git a/node/scalaroperatornode.h b/node/scalaroperatornode.h new file mode 100644 index 0000000..96324ba --- /dev/null +++ b/node/scalaroperatornode.h @@ -0,0 +1,32 @@ +#ifndef SCALAROPERATORNODE_H +#define SCALAROPERATORNODE_H + +#include <QMap> +#include <QChar> + +#include "executionnode.h" + + +class ScalarOperatorNode : public ExecutionNode +{ +public: + enum ScalarOperator {PLUS,MINUS,DIVIDE,MULTIPLICATION}; + ScalarOperatorNode(); + virtual void run(ExecutionNode*); + bool setOperatorChar(QChar c); + void setInternalNode(ExecutionNode* node); + + +private: + qint64 add(qint64,qint64); + qint64 substract(qint64,qint64); + qint64 divide(qint64,qint64); + qint64 multiple(qint64,qint64); + +private: + ScalarOperator m_myOperator; + ExecutionNode* m_internalNode; + QMap<QChar,ScalarOperator> m_scalarOperationList; +}; + +#endif // SCALAROPERATORNODE_H diff --git a/node/startingnode.cpp b/node/startingnode.cpp new file mode 100644 index 0000000..602fec0 --- /dev/null +++ b/node/startingnode.cpp @@ -0,0 +1,14 @@ +#include "startingnode.h" +#include <QDebug> + +StartingNode::StartingNode() +{ + +} +void StartingNode::run(ExecutionNode*) +{ + if(NULL!=m_nextNode) + { + m_nextNode->run(this); + } +} diff --git a/node/startingnode.h b/node/startingnode.h new file mode 100644 index 0000000..08134e7 --- /dev/null +++ b/node/startingnode.h @@ -0,0 +1,14 @@ +#ifndef STARTINGNODE_H +#define STARTINGNODE_H + +#include "executionnode.h" + +class StartingNode : public ExecutionNode +{ +public: + StartingNode(); + + virtual void run(ExecutionNode*); +}; + +#endif // STARTINGNODE_H |