private float ValueNode(FormulaNode cur) { if (cur == null) { return(0.00f); } if (cur.type == NodeType.NODE_TYPE_OP) { return(Cacul(ValueNode(cur.left), cur.op, ValueNode(cur.right))); } else { if (cur.type == NodeType.NODE_TYPE_NUM) { return(cur.value * cur.sign); } else if (cur.type == NodeType.NODE_TYPE_VAR || cur.type == NodeType.NODE_TYPE_EXPAND_VAR || cur.type == NodeType.NODE_TYPE_PARAM || cur.type == NodeType.NODE_TYPE_RANDOM) { return(GetParamValue(cur.chValue) * cur.sign); } else { return(0.00f); } } }
private void OnPopFuncMenu() { var currentEvent = Event.current; if (currentEvent.type == EventType.ContextClick) { Vector2 mousePos = currentEvent.mousePosition; if (m_TreeWindowRect.Contains(mousePos)) { GenericMenu menu = new GenericMenu(); foreach (var funcContent in m_FuncContents) { menu.AddItem(funcContent, false, obj => { var formulaNode = new FormulaNode(); m_FormulaNodeRects.Add(new Rect(mousePos.x, mousePos.y, 100, 100)); m_Nodes.Add(formulaNode); var str = obj.ToString(); if (str.Contains("Maths/")) { formulaNode.type = (FormulaNodeType)Enum.Parse(typeof(FormulaNodeType), str.Replace("Maths/", string.Empty)); } else { formulaNode.key = "0"; } }, funcContent.ToString()); } menu.ShowAsContext(); currentEvent.Use(); } } }
public FormulaNode() { type = NodeType.NODE_TYPE_OP; op = ' '; value = 0.0f; from = ' '; sign = 0; chValue = ""; left = null; right = null; }
public float GetValue(FormulaNode formulaNode) { if (typeof(MathExpNode) == formulaNode.GetType()) { return(mathParserRouter.CalculateAnswer(((MathExpNode)formulaNode).formula)); } else if (typeof(PureNumberNode) == formulaNode.GetType()) { return(((PureNumberNode)formulaNode).value); } else if (typeof(SequenceNode) == formulaNode.GetType()) { } return(0); }
public FormulaParser() { // 初始化运算符优先级 if (m_priTable[0] == null) { m_priTable[0] = new Priority('#', 0, 0); m_priTable[1] = new Priority('+', 3, 2); m_priTable[2] = new Priority('-', 3, 2); m_priTable[3] = new Priority('*', 5, 4); m_priTable[4] = new Priority('/', 5, 4); m_priTable[5] = new Priority('^', 6, 7); m_priTable[6] = new Priority('(', 1, 8); m_priTable[7] = new Priority(')', 8, 1); } // 初始化节点池 for (int i = 0; i < FormulaParserManager.MAX_NODE_COUNT; i++) { FormulaNode node = new FormulaNode(); m_formulaNode.Add(node); } }
/// 计算结果,传入的Dictionary中必须包含所有信息// public float GetData(NumericComponent comp, NumericComponent other) { ListComponent <int> priorityList = ListComponent <int> .Create(); ListComponent <FormulaNode> tempList = ListComponent <FormulaNode> .Create(); for (int i = 0; i < formulaNodeList.Count; i++) { FormulaNode node = new FormulaNode(formulaNodeList[i].Key, formulaNodeList[i].Value, formulaNodeList[i].IsSelf); tempList.Add(node); } for (int i = 0; i < tempList.Count; i++) { if (!float.TryParse(tempList[i].Value, out _)) { if (NumericType.Map.TryGetValue(tempList[i].Value, out int type)) { if (tempList[i].IsSelf) { tempList[i].Value = comp.GetAsFloat(type).ToString(); } else if (other != null) { tempList[i].Value = other.GetAsFloat(type).ToString(); } else { tempList[i].Value = "0"; Log.Error("计算伤害未传入目标"); } } } if (tempList[i].Key != 0 && !priorityList.Contains(tempList[i].Key)) { priorityList.Add(tempList[i].Key); } } priorityList.Sort(); while (priorityList.Count > 0) { int currentpri = priorityList[priorityList.Count - 1]; bool hasfind = false; do { hasfind = false; for (int i = 0; i < tempList.Count && tempList.Count >= 3; i++) { if (tempList[i].Key == currentpri && GetPriority(tempList[i].Value) != 0) { float final = GetOperactorFinal(tempList[i - 1].Value, tempList[i].Value, tempList[i + 1].Value); var newformula = new FormulaNode(tempList[i - 1].Key, final.ToString()); tempList.RemoveRange(i - 1, 3); tempList.Insert(i - 1, newformula); hasfind = true; break; } } } while (hasfind); priorityList.RemoveAt(priorityList.Count - 1); priorityList.Sort(); } if (tempList.Count == 0) { #if UNITY_EDITOR // UnityEngine.Debug.LogError("FormulaString is Error string = "+ lastFormatString); #endif return(0); } string outstring = tempList[0].Value;// + formulaNodeList.Count.ToString(); float finalnum = 0; if (!float.TryParse(outstring, out finalnum)) { #if UNITY_EDITOR // UnityEngine.Debug.Log(outstring); #endif finalnum = 0; } priorityList.Dispose(); tempList.Dispose(); return(finalnum); }
public override Node Visit(FormulaNode node) { return(new FormulaNode(node.ChildNode.Visit(this), node.FormulaText)); }
/// 计算结果,传入的Dictionary中必须包含所有信息// public float GetData(Dictionary <string, float> dict) { List <int> priorityList = new List <int>(); List <FormulaNode> tempList = new List <FormulaNode>(); for (int i = 0; i < formulaNodeList.Count; i++) { FormulaNode node = new FormulaNode(formulaNodeList[i].Key, formulaNodeList[i].Value); tempList.Add(node); } Dictionary <string, float> tempdict = new Dictionary <string, float>(); foreach (var dic in dict) { tempdict.Add(dic.Key.ToLower(), dic.Value); } { for (int i = 0; i < tempList.Count; i++) { if (tempdict.ContainsKey(tempList[i].Value.ToLower()))//替换字段为数值// { tempList[i].Value = tempdict[tempList[i].Value.ToLower()].ToString(); } if (tempList[i].Key != 0 && !priorityList.Contains(tempList[i].Key)) { priorityList.Add(tempList[i].Key); } } priorityList.Sort(); } { while (priorityList.Count > 0) { int currentpri = priorityList[priorityList.Count - 1]; bool hasfind = false; do { hasfind = false; for (int i = 0; i < tempList.Count && tempList.Count >= 3; i++) { if (tempList[i].Key == currentpri && GetPriority(tempList[i].Value) != 0) { float final = GetOperactorFinal(tempList[i - 1].Value, tempList[i].Value, tempList[i + 1].Value); var newformula = new FormulaNode(tempList[i - 1].Key, final.ToString()); tempList.RemoveRange(i - 1, 3); tempList.Insert(i - 1, newformula); hasfind = true; break; } } } while (hasfind); priorityList.RemoveAt(priorityList.Count - 1); priorityList.Sort(); } } if (tempList.Count == 0) { #if UNITY_EDITOR // UnityEngine.Debug.LogError("FormulaString is Error string = "+ lastFormatString); #endif return(0); } string outstring = tempList[0].Value;// + formulaNodeList.Count.ToString(); float finalnum = 0; if (!float.TryParse(outstring, out finalnum)) { #if UNITY_EDITOR // UnityEngine.Debug.Log(outstring); #endif finalnum = 0; } return(finalnum); }
public virtual TResult Visit(FormulaNode node) => node.ChildNode.Visit(this);
// 创建公式解析树 public bool CreateFormulaTree(string formula) { if (!ScanNode(formula)) { return(false); } Stack <FormulaNode> nodeStack = new Stack <FormulaNode>(); Stack <FormulaNode> opStack = new Stack <FormulaNode>(); FormulaNode tempNode = new FormulaNode(); tempNode.type = NodeType.NODE_TYPE_OP; tempNode.op = '#'; opStack.Push(tempNode); for (int i = 0; i < m_count; i++) { if (m_formulaNode[i].type == NodeType.NODE_TYPE_NUM || m_formulaNode[i].type == NodeType.NODE_TYPE_VAR || m_formulaNode[i].type == NodeType.NODE_TYPE_PARAM || m_formulaNode[i].type == NodeType.NODE_TYPE_RANDOM) { m_formulaNode[i].left = null; m_formulaNode[i].right = null; nodeStack.Push(m_formulaNode[i]); } else if (m_formulaNode[i].type == NodeType.NODE_TYPE_OP) { switch (m_formulaNode[i].op) { case '(': { opStack.Push(m_formulaNode[i]); } break; case ')': { while (opStack.Peek().op != '(') { FormulaNode op = opStack.Peek(); opStack.Pop(); FormulaNode right = nodeStack.Peek(); nodeStack.Pop(); FormulaNode left = nodeStack.Peek(); nodeStack.Pop(); op.left = left; op.right = right; nodeStack.Push(op); } if (opStack.Count < 1) { return(false); } opStack.Pop(); //弹出栈顶左括号 } break; case '+': case '-': case '*': case '/': case '^': { while (CmpSymbolPri(opStack.Peek().op, m_formulaNode[i].op) >= 0) { FormulaNode op = opStack.Peek(); opStack.Pop(); FormulaNode right = nodeStack.Peek(); nodeStack.Pop(); FormulaNode left = nodeStack.Peek(); nodeStack.Pop(); op.left = left; op.right = right; nodeStack.Push(op); } opStack.Push(m_formulaNode[i]); } break; default: return(false); } } else { return(false); } } while (opStack.Peek().op != '#') { FormulaNode op = opStack.Peek(); opStack.Pop(); FormulaNode right = nodeStack.Peek(); nodeStack.Pop(); FormulaNode left = nodeStack.Peek(); nodeStack.Pop(); op.left = left; op.right = right; nodeStack.Push(op); } opStack.Pop(); if (nodeStack.Count != 1) { return(false); } m_root = nodeStack.Peek(); nodeStack.Pop(); return(true); }