/// <summary> /// 連按單元運算子的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateAfterUnary(ComputeObject computeObject) { //取得單元運算子 UnaryOperator unaryOperator = UnaryDic[Content]; var formula = unaryOperator.Formula; int removeLength = computeObject.CurrentUnaryString.Length; //必須case by case處理 if (Content == '√') { computeObject.CurrentUnaryString = $"√({computeObject.CurrentUnaryString})"; if (computeObject.NumberField.Number.HasValue && computeObject.NumberField.Number.Value <= 0) { throw new SquareRootException("無效的輸入"); } } else if (Content == '±') { computeObject.CurrentUnaryString = $"negate({computeObject.CurrentUnaryString})"; } else { throw new Exception("無此運算元"); } //計算後將結果存起來 computeObject.NumberField.Number = formula(computeObject.NumberField.Number.Value); return(new FrameUpdate(computeObject.NumberField.Number.ToString(), removeLength, computeObject.CurrentUnaryString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { FrameUpdate frameUpdate; //等號後輸入數字 if (computeObject.LastFeature == typeof(Equal)) { //特殊情況,boardObject已在父類清空 computeObject.Init(); frameUpdate = GetUpdateDefault(computeObject); frameUpdate.RemoveLength = FrameUpdate.REMOVE_ALL; return(frameUpdate); } //backspace或clearerror之後的數字處理 if ((computeObject.LastFeature == typeof(BackSpace) || computeObject.LastFeature == typeof(ClearError)) && computeObject.NumberField.Number == 0) { frameUpdate = GetUpdateDefault(computeObject); frameUpdate.RemoveLength += 1; return(frameUpdate); } frameUpdate = GetUpdateDefault(computeObject); return(frameUpdate); }
/// <summary> /// 回傳當下的運算樹計算結果 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>計算結果</returns> protected Result GetResult(ComputeObject computeObject) { if (computeObject.TreeStack.Count == 1) { //算完不能pop var answer = new Evaluator().EvaluateTree(computeObject.TreeStack.Peek()); return(new Result(answer, 0)); } else if (computeObject.TreeStack.Count > 1) { int extraRightBracket = 0; //這裡不用tmp嗎,再想想 while (computeObject.TreeStack.Count > 1) { var subTree = computeObject.TreeStack.Pop(); computeObject.TreeStack.Peek().Add(subTree); extraRightBracket++; } //算完不能pop var ans = new Evaluator().EvaluateTree(computeObject.TreeStack.Peek()); return(new Result(ans, extraRightBracket)); } else { throw new Exception("資料有誤"); } }
/// <summary> /// 回傳預設的等號事件的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateDefault(ComputeObject computeObject) { if (computeObject.NumberField != null) { computeObject.TreeStack.Peek().Add(computeObject.NumberField.Number.Value); computeObject.NumberField = null; } //result處理 var result = GetResult(computeObject); var updateString = string.Empty; for (int i = 0; i < result.ExtraRightBracketCount; i++) { updateString += ")"; } //送出結果 updateString += "="; var ans = result.Answer; //暫存答案 computeObject.CurrentAnswer = ans; return(new FrameUpdate(ans.ToString(), removeLength: 0, updateString: updateString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { string updateString = string.Empty; if (computeObject.NumberField != null) { computeObject.TreeStack.Peek().Add(computeObject.NumberField.Number.Value); } else if (computeObject.NumberField == null) { computeObject.TreeStack.Peek().Add(computeObject.CurrentAnswer); updateString += computeObject.CurrentAnswer.ToString(); } //右括號處理 if (computeObject.TreeStack.Count <= 1) { throw new BracketException("右括號數量過多"); } var subTree = computeObject.TreeStack.Pop(); computeObject.TreeStack.Peek().Add(subTree); updateString += ")"; computeObject.NumberField = null; computeObject.CurrentAnswer = GetTmpResult(computeObject); return(new FrameUpdate(computeObject.CurrentAnswer.ToString(), removeLength: 0, updateString: updateString)); }
public FrameUpdate UseTree(ComputeObject computeObject) { var frameUpdate = Feature.UseTree(computeObject); Users.GetUserInfo2(UserId).ComputeObject = computeObject; return(frameUpdate); }
/// <summary> /// 回傳連續輸入雙元運算子的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateAfterBinary(ComputeObject computeObject) { BinaryOperator binaryOperator = BinaryDic[Content]; if (computeObject.NumberField != null) { throw new Exception("ModifyBinary時Number不能有值"); } computeObject.TreeStack.Peek().ModifyOperator(binaryOperator); return(new FrameUpdate(computeObject.CurrentAnswer.ToString(), removeLength: 1, updateString: Content.ToString())); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { if (computeObject.NumberField == null) { return(new FrameUpdate(removeLength: 0, updateString: string.Empty)); } int length = computeObject.NumberField.Number.Value.ToString().Length; computeObject.NumberField = new NumberField(); return(new FrameUpdate(removeLength: length, updateString: "0")); }
/// <summary> /// 回傳Tree右半部的計算結果 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>計算結果</returns> private decimal GetRightHalf(ComputeObject computeObject) { var top = computeObject.TreeStack.Peek().GetTop(); if (top.RightNode == null) { return(0); } return(new Evaluator().PackNode(top.RightNode)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { computeObject.TreeStack.Push(new ExpressionTree()); var frameUpdate = new FrameUpdate(removeLength: 0, updateString: "("); if (computeObject.LastFeature == typeof(Equal)) { frameUpdate.RemoveLength = FrameUpdate.REMOVE_ALL; } return(frameUpdate); }
/// <summary> /// 回傳連續等號的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateAfterEqual(ComputeObject computeObject) { string updateString = computeObject.CurrentAnswer.ToString(); //更新計算答案 ReplaceLeft(computeObject, computeObject.CurrentAnswer); var op = computeObject.TreeStack.Peek().GetTop().NodeValue.Operator.Name; var rightResult = GetRightHalf(computeObject); updateString += $"{op}{rightResult}="; computeObject.CurrentAnswer = GetResult(computeObject).Answer; return(new FrameUpdate(computeObject.CurrentAnswer.ToString(), removeLength: FrameUpdate.REMOVE_ALL, updateString: updateString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { //如果單元連按會有迭代的表現方式 if (computeObject.LastFeature == typeof(Unary)) { return(GetUpdateAfterUnary(computeObject)); } else { //非迭代的case return(GetUpdateDefault(computeObject)); } }
/// <summary> /// 以一個數字替換Tree的左半部 /// </summary> /// <param name="computeObject">計算物件</param> /// <param name="newNumber">新數字</param> private void ReplaceLeft(ComputeObject computeObject, decimal newNumber) { //在這個方法被呼叫之前,TreeStack已經收束成一棵完整的樹了,也就是TreeStack.Count = 1 var tree = computeObject.TreeStack.Peek(); var top = tree.GetTop(); //新的左節點 Node newLeftNode = Node.Build() .SetParentNode(top) .SetNumber(newNumber) .Exec(); top.LeftNode = newLeftNode; tree.Root = newLeftNode; }
/// <summary> /// 回傳當下最外層子樹的計算結果 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>計算結果</returns> protected decimal GetTmpResult(ComputeObject computeObject) { //暫時計算的結果只需要到第一層 if (computeObject.TreeStack.Count > 0) { var outerTree = computeObject.TreeStack.Peek(); return(new Evaluator().EvaluateTree(outerTree)); } else if (computeObject.TreeStack.Count == 0) { return(0); } else { throw new Exception("資料有誤"); } }
/// <summary> /// 回傳預設雙元運算子事件的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateDefault(ComputeObject computeObject) { BinaryOperator binaryOperator = BinaryDic[Content]; //若沒有輸入過值,則視為輸入了0 computeObject.TreeStack.Peek().Add((computeObject.NumberField == null) ? 0 : computeObject.NumberField.Number.Value); //數字歸零 computeObject.NumberField = null; //算出一個暫時的結果並存下 computeObject.CurrentAnswer = GetTmpResult(computeObject); computeObject.TreeStack.Peek().Add(binaryOperator); return(new FrameUpdate(computeObject.CurrentAnswer.ToString(), removeLength: 0, updateString: Content.ToString())); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { if (computeObject.LastFeature == typeof(Clear)) { var frameUpdate = GetUpdateDefault(computeObject); //要補0 frameUpdate.UpdateString = $"0{frameUpdate.UpdateString}"; return(frameUpdate); } else if (computeObject.LastFeature == typeof(Binary)) { return(GetUpdateAfterBinary(computeObject)); } else { return(GetUpdateDefault(computeObject)); } }
/// <summary> /// 回傳預設的單元運算子事件的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateDefault(ComputeObject computeObject) { //拿到單元運算的公式 UnaryOperator unaryOperator = UnaryDic[Content]; var formula = unaryOperator.Formula; int removeLength = 0; if (computeObject.NumberField == null) { return(new FrameUpdate("0", removeLength: removeLength, updateString: string.Empty)); } removeLength = computeObject.NumberField.Number.Value.ToString().Length; if (computeObject.NumberField.IsEndWithPoint()) { removeLength += 1; } //暫存 var OriginNumberString = computeObject.NumberField.Number.ToString(); string updateString = string.Empty; //必須case by case處理 if (Content == '√') { updateString = $"√({OriginNumberString})"; } else if (Content == '±') { updateString = $"negate({OriginNumberString})"; } else { throw new Exception("無此運算元"); } //計算後將結果存起來 computeObject.NumberField.Number = formula(computeObject.NumberField.Number.Value); //記住這次的結果 computeObject.CurrentUnaryString = updateString; return(new FrameUpdate(computeObject.NumberField.Number.ToString(), removeLength, updateString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { if (computeObject.LastFeature == typeof(Clear)) { return(new FrameUpdate("0", removeLength: 0, updateString: "0=")); } else if (computeObject.LastFeature == typeof(Equal)) { //等號連按 return(GetUpdateAfterEqual(computeObject)); } else if (computeObject.LastFeature == typeof(Binary)) { //運算符配等號 return(GetUpdateAfterBinary(computeObject)); } return(GetUpdateDefault(computeObject)); }
/// <summary> /// 回傳數字鍵事件的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateDefault(ComputeObject computeObject) { //小數點case if (Content.Equals('.')) { //若這時沒有值→視為已經輸入零 if (computeObject.NumberField == null) { computeObject.NumberField = new NumberField(); computeObject.NumberField.AddDigit(Content); return(new FrameUpdate("0.", removeLength: 0, updateString: "0.")); } //若有值→判斷是否已為小數 if (computeObject.NumberField.IsNumeric) { //已經是小數→不回傳值 return(new FrameUpdate(computeObject.NumberField.Number.ToString() + ".", removeLength: 0, updateString: string.Empty)); } else { //不是小數→更新小數點 computeObject.NumberField.AddDigit(Content); return(new FrameUpdate(computeObject.NumberField.Number.ToString() + ".", removeLength: 0, updateString: ".")); } } //防呆 if (!char.IsNumber(Content)) { throw new Exception("該輸入數字"); } //正常的數字case if (computeObject.NumberField == null) { computeObject.NumberField = new NumberField(Content); } else { computeObject.NumberField.AddDigit(Content); } return(new FrameUpdate(computeObject.NumberField.Number.ToString(), removeLength: 0, updateString: Content.ToString())); }
/// <summary> /// 回傳雙元運算子後接等號的畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> private FrameUpdate GetUpdateAfterBinary(ComputeObject computeObject) { //CurrentAnswer已經被Binary算好了 computeObject.TreeStack.Peek().Add(computeObject.CurrentAnswer); //result處理 var result = GetResult(computeObject); var ans = result.Answer; //做更新字串 var updateString = computeObject.CurrentAnswer.ToString(); for (int i = 0; i < result.ExtraRightBracketCount; i++) { updateString += ")"; } //送出結果 updateString += "="; return(new FrameUpdate(ans.ToString(), removeLength: 0, updateString: updateString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { int RemoveLength = 0; if (computeObject.NumberField == null) { return(new FrameUpdate(removeLength: RemoveLength, updateString: string.Empty)); } RemoveLength = computeObject.NumberField.Number.Value.ToString().Length; if (computeObject.NumberField.IsEndWithPoint()) { RemoveLength += 1; } computeObject.NumberField.ClearOneDigit(); string updateString = computeObject.NumberField.Number.ToString(); if (computeObject.NumberField.IsEndWithPoint()) { updateString += "."; } return(new FrameUpdate(RemoveLength, updateString)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public override FrameUpdate Compute(ComputeObject computeObject) { computeObject.Init(); return(new FrameUpdate(FrameUpdate.REMOVE_ALL, string.Empty)); }
/// <summary> /// 依計畫內容回傳畫面更新 /// </summary> /// <param name="computeObject">計算物件</param> /// <returns>畫面更新</returns> public abstract FrameUpdate Compute(ComputeObject computeObject);
/// <summary> /// 建構子 /// </summary> public UserInfo() { BoardObject = new BoardObject(); ComputeObject = new ComputeObject(); }