【软件工程实践】结对项目-四则运算 “软件”之升级版

本次作业要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2213

我们的项目GitHub远程仓库地址:https://github.com/numtozzy/Twinning

作业要求:

(1)基本要求

  • 自动生成题目,单个题目最多不能超过4个运算符,操作数小于100。
  • 用户可以输入答案
  • 若用户输入答案正确,则提示正确;若答案错误,则提示错误,并要提示正确答案是多少。

(2)我们是在IDEA和Chrome浏览器开发环境下开发调试的,主要拓展的方向有:

  3.用户答题结束以后,程序可以显示用户答题所用的时间

  6.程序可以出单个整数阶乘的题目:如:4!=24

  7.程序可以设置答题时间,时间设置为整数,单位为秒,最大不能超过120秒,若超过了答题时间未答题,则提示:时间已到,不能答题。

  8.程序可以设置皮肤功能,可以改变界面的颜色即可。

  第四个方向(4.用户可以选择出题的个数(最多不能超过5个题目),答题结束可以显示用户答错的题目个数和答对的题目个数)有所涉及,但没有完善好。

(3)结对成员

       姓名:周志勇 学号:201606120025  博客园地址:https://www.cnblogs.com/me-zzy/

       姓名:李耀强 学号:201606120027  博客园地址:http://www.cnblogs.com/leo0724/

结对子项目粗略的过程记录:

分工:我做的主要是3和8方向,页面

   同伴做的主要是6和7方向,算法实现

遇到的问题:1.按钮之间的互斥关系、2.bootstrap布局问题、3.算法的实现、4.需要使用到Stack()函数,js中没有定义、5.鼠标、时间监听事件的功能实现、

如何解决:1.利用正则表达式检测、2.反复查看学习bootstrap文档、3.多思考多尝试互相讨论、4.利用数组自主实现了Stack()函数,5.反复琢磨尝试,根据需求实现功能

注:思考时间很多,记录有所偏颇,实际时间可能比这个长。

  两个人的代码嵌套在一起,可能有些相似的功能被分成不同的函数,代码看起来会有点冗余。

部分程序截图:

 

 

部分核心代码(主要JS代码 arithmetic.js):

    var record=0;
    var op= new Array( "+", "-", "*", "/" );  //运算符

    var num;//题目个数
    var time;//解题时间
    var a;//记录setTimeout()方法返回的 ID 值。
    var timer_is_on = 0;//判断按键是否按下

        //开始按钮监听
        $("#begin").click(function(){
            if(document.getElementById("begins").firstChild.nodeValue == "开始" && timer_is_on==0){
                var intReg = /^[1-9]+\d*$/;
                num = document.getElementById("count").value;
                if (!(intReg.test(num))) {
                    alert(num + "请输入题目个数(正整数):");
                    document.getElementById("number").focus();
                    return;
                }

                time = num * 60;
                jishi();
            }


            //开始/下一题的监听事件
            var s2 = $("input[name='options']:checked").val();
            document.getElementById("begins").innerText = "下一题";
            document.getElementById("answer").value = "";
            document.getElementById("result").value = "";
            if (s2 == "basic") {
                document.getElementById("option2").value = "basic";
                var count = parseInt(document.getElementById("count").value);
                for (var i = 0; i < 1; i++) {
                    var question = MakeFormula();
                    var result = Solve(question);
                    //过滤掉答案不为负数的
                    if ("invalid" == result) {
                        i--;
                        continue;
                    }
                    document.getElementById("formula").value = question + '=';

                    //提交的监听事件
                    $("#submit").click(function () {
                        var answerNode = document.getElementById("answer");
                        var answers = answerNode.value;
                        var numReg = /^[0-9]+([.]{1}[0-9]+){0,1}$/;
                        var reg = /^\s*|\s*$/g;
                        var temp = answers;
                        temp = temp.replace(reg, "");
                        answerNode.value = temp;
                        if (temp == "") {
                            alert("请输入答案");
                            return false;
                        } else if (!(numReg.test(answers))) {
                            alert("请输入合法的答案");
                            return false;
                        } else if (result == answers) {

                            document.getElementById("result").value = "    恭喜你答对了!";
                            record++;
                        } else {

                            document.getElementById("result").value = "正确答案为:" + result + "    很遗憾答错了!";
                        }
                        return false;
                    });

                }
            }
            else {
                var tReg = /^[1-9]+\d*$/;
                document.getElementById("option1").value = "jiecheng";
                var count = parseInt(document.getElementById("count").value);  //获取用户输入的n阶乘
                if (!(tReg.test(count))) {
                    alert(count + "请输入题目个数(正整数):");
                    document.getElementById("number").focus();
                    return;
                }
                var results = jiecheng(count);  //计算阶乘答案
                document.getElementById("formula").value = count + '! =';
                $("#submit").click(function () {

                    var answers = document.getElementById("answer").value;
                    document.getElementById("count").value = "";
                    if (results == answers) {
                        document.getElementById("result").value = "    恭喜你答对了!";
                        record++;
                    }
                    else {
                        document.getElementById("result").value = "正确答案为:" + results + "    很遗憾答错了!";
                    }

                });
            }

    });


    
    
    //阶乘
    function jiecheng(n)
    {
        var s= new Stack();
        if(n==0)
        {
                return 1;
        }
        while(n>1)
        {
            s.push(n--);
        }
        var product = 1;
        while(s.length()>0)
        {
            product*=s.pop();
        }
        return product;
        
    }
    
    
    function Score()
    {
        return record*10;
    }
    
    
    /**
     * 随机生成运算式子
     * @resulturn
     */
    function MakeFormula(){
        
        var build="";
        var count =parseInt((Math.random() * 2)+1,10);        //2-3个运算符
        var number1 = parseInt((Math.random() * 99) + 1,10);  //1-100之内的随机数
        var start = 0;
        build+=number1;
        while (start <= count)
        {
            var operation = parseInt((Math.random() * 3)+1,10); // 随机的运算符
            var number2 = parseInt((Math.random() * 99) + 1,10);
            build=build+(op[operation])+(number2);
            start++;
        }
        
        return build.toString();
    }

    /**
     * 运算符优先级
     * @param formula
     * @resulturn
     */
    function Solve(formula){
        var tempStack = new Stack();//放数字,运算符
        var operatorStack = new Stack();//放运算符
        var len = formula.length; 
        var k = 0;
        var mark = "invalid";
        for(var j = -1; j < len - 1; j++){
            var formulaChar = formula.charAt(j+1);  //index 0 返回 第一个数
            if(j == len - 2 || formulaChar == '+' || formulaChar == '-' || formulaChar == '/' || formulaChar == '*') {
                if (j == len - 2) {
                    
                    tempStack.push(formula.substring(k));
                    
                }
                else {
                        tempStack.push(formula.substring(k, j + 1));
                    if(operatorStack.dataStore == false){
                        operatorStack.push(formulaChar); // 在栈中放入第一个符号
                    }else{
                        var stackChar = operatorStack.peek();
                        if ((stackChar == '+' || stackChar == '-')
                                && (formulaChar == '*' || formulaChar == '/')){
                            operatorStack.push(formulaChar);
                        }else {
                            
                            tempStack.push(operatorStack.pop());
                            operatorStack.push(formulaChar);
                        }
                    }
                }
                k = j + 2; 
            }
        }
      while(operatorStack.dataStore.length>0){
         
            tempStack.push(operatorStack.pop());
            operatorStack.dataStore.length--;
            
        }
        var calcStack = new Stack();
        // 遍历
      
        for(var i=0;i<tempStack.dataStore.length;i++){
            if(tempStack.dataStore[i]!="+" && tempStack.dataStore[i]!="-" && tempStack.dataStore[i]!="/" && tempStack.dataStore[i]!="*") {
                calcStack.push(tempStack.dataStore[i]); // 把数字存入栈
            }else{
                var a = 0;
                var b = 0;
                while(calcStack.dataStore.length>0){
                    
                    b = parseFloat(calcStack.pop());
                    a = parseFloat(calcStack.pop());
                    calcStack.dataStore.length=calcStack.dataStore.length-2;
                    
                }
                    
                switch (tempStack.dataStore[i]) {
                    case "+":
                       calcStack.push(String(a + b));
                        break;
                    case "-":
                       calcStack.push(String(a - b));
                        break;
                    case "*":
                        calcStack.push(String(a * b));
                        break;
                    default:
                        calcStack.push(String(a / b));
                        break;
                }
            }
        }
        if(parseFloat(calcStack.peek())<0){
            return mark;
        }
        return calcStack.pop();
    }
    /*使用栈stack类的实现*/
    function Stack() {
        this.dataStore = [];//保存栈内元素,初始化为一个空数组
        this.top = 0;//栈顶位置,初始化为0
        this.push = push;//入栈
        this.pop = pop;//出栈
        this.peek = peek;//查看栈顶元素
        this.clear = clear;//清空栈
        this.length = length;//栈内存放元素的个数
    }

    function push(element){
        return this.dataStore[this.top++] = element;
    }

    function pop(){
        return this.dataStore[--this.top];
    }

    function peek(){
        return this.dataStore[this.top-1];
    }

    function clear(){
        this.top = 0;
    }

    function length(){
        return this.top;
    }




    /**
     * 统计时间
     */
    function jishi() {
        time--;

        document.getElementById('time').innerHTML = calTime(time); //倒计时
        a = setTimeout(jishi, 1000);

        if (time == num * 0.5) {
            alert("考试时间还剩一半!");
        }
        if(time == 0) {
            clearTimeout(a);
            alert("时间到,测试结束!");
            jieshu();
            location.reload();
        }
    }
    $("#over").click(function(){
        jieshu();
        alert("用时:"+ timeOfUse(num * 60 - time));
        location.reload();
    });
    function timeOfUse(time){
        var hour = Math.floor(time/3600%24);
        var min = Math.floor(time/60%60);
        var second = time - hour*3600 - min*60;
        return (hour + "时" + min + "分" + second + "秒");
    }
    function jieshu() {
        //结束按钮的监听事件
        document.getElementById("formula").value="";
        document.getElementById("result").value="";
        document.getElementById("answer").value="";
        alert("你共答对"+record+"题,分数为"+Score());
        if(timer_is_on = 1){
            alert("用时:"+ timeOfUse(120));
        }else{
            alert("用时:"+ timeOfUse(num * 60));
        }

    }
    document.getElementById("timeOut").onclick = function() {

        if (!timer_is_on) {
            timer_is_on = 1;
            time = 120;
            jishi();
        }
    }
    function calTime(time) {
        var spit = ":";
        var hour = "00";
        var second = "00";
        var min = "00";
        var result = "";

        if (time % 60 != 0) { //
            if (time % 60 >= 10) {
                second = time % 60;
            } else {
                second = "0" + time % 60;
            }
        }

        if (parseInt(time / 60) != 0) { //
            if (parseInt(time / 60) >= 10) {
                min = parseInt(time / 60);
            } else {
                min = "0" + parseInt(time / 60);
            }
        }

        if (parseInt(time / 3600) != 0) { //
            if (parseInt(time / 3600) >= 10) {
                hour = parseInt(time / 3600);
            } else {
                hour = "0" + parseInt(time / 3600);
            }
        }

        result = hour + spit + min + spit + second;

        return result;
    }

    /**
     * 切换背景皮肤
     * @param color
     * @constructor
     */
    function Changecolor(color) {
        document.getElementById("body").style.backgroundImage = color;
        document.getElementById("body").style.backgroundRepeat="no-repeat";
        // document.getElementById("body").style.backgroundAttachment="fixed";
        document.getElementById("body").style.backgroundSize = "cover";

    }

工作照: 

收获和感悟:

  整个过程先交流讨论商量分工,在讨论问题中,彼此互相探讨启发给对方以灵感,体会到了不能太局限于自我的思想对有些问题不能太执拗。代码逻辑有时混淆,需要逆向思考才能走出“胡同”。同时也意识到了自己还有很多东西不懂,以后要更加主动,更加努力。

 

posted on 2018-10-24 21:26  少年zzy  阅读(229)  评论(2编辑  收藏  举报

导航