Exemple #1
0
        /// <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));
        }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        /// <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("資料有誤");
            }
        }
Exemple #4
0
        /// <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));
        }
Exemple #5
0
        /// <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));
        }
Exemple #6
0
        public FrameUpdate UseTree(ComputeObject computeObject)
        {
            var frameUpdate = Feature.UseTree(computeObject);

            Users.GetUserInfo2(UserId).ComputeObject = computeObject;
            return(frameUpdate);
        }
Exemple #7
0
        /// <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()));
        }
Exemple #8
0
        /// <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"));
        }
Exemple #9
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));
        }
Exemple #10
0
        /// <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);
        }
Exemple #11
0
        /// <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));
        }
Exemple #12
0
 /// <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));
     }
 }
Exemple #13
0
        /// <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;
        }
Exemple #14
0
 /// <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("資料有誤");
     }
 }
Exemple #15
0
        /// <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()));
        }
Exemple #16
0
 /// <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));
     }
 }
Exemple #17
0
        /// <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));
        }
Exemple #18
0
        /// <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));
        }
Exemple #19
0
        /// <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()));
        }
Exemple #20
0
        /// <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));
        }
Exemple #21
0
        /// <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));
        }
Exemple #22
0
 /// <summary>
 /// 依計畫內容回傳畫面更新
 /// </summary>
 /// <param name="computeObject">計算物件</param>
 /// <returns>畫面更新</returns>
 public override FrameUpdate Compute(ComputeObject computeObject)
 {
     computeObject.Init();
     return(new FrameUpdate(FrameUpdate.REMOVE_ALL, string.Empty));
 }
Exemple #23
0
 /// <summary>
 /// 依計畫內容回傳畫面更新
 /// </summary>
 /// <param name="computeObject">計算物件</param>
 /// <returns>畫面更新</returns>
 public abstract FrameUpdate Compute(ComputeObject computeObject);
Exemple #24
0
 /// <summary>
 /// 建構子
 /// </summary>
 public UserInfo()
 {
     BoardObject   = new BoardObject();
     ComputeObject = new ComputeObject();
 }