aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--diceParser.pro27
-rw-r--r--diceparser.cpp179
-rw-r--r--diceparser.h41
-rw-r--r--diceresult.cpp24
-rw-r--r--diceresult.h19
-rw-r--r--main.cpp26
-rw-r--r--node/dicerollernode.cpp30
-rw-r--r--node/dicerollernode.h25
-rw-r--r--node/executionnode.cpp24
-rw-r--r--node/executionnode.h20
-rw-r--r--node/node.pri15
-rw-r--r--node/numbernode.cpp19
-rw-r--r--node/numbernode.h17
-rw-r--r--node/rerolldicenode.cpp25
-rw-r--r--node/rerolldicenode.h22
-rw-r--r--node/scalaroperatornode.cpp91
-rw-r--r--node/scalaroperatornode.h32
-rw-r--r--node/startingnode.cpp14
-rw-r--r--node/startingnode.h14
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