这个作业要求在哪里 | https://bbs.csdn.net/topics/617294583 |
---|---|
这个作业的目标 | 完成一个具有可视化界面的计算器 |
其他参考文献 | https://blog.csdn.net/qq_33911878/article/details/118441400 |
Gitcode项目地址
https://gitcode.net/m0_70182538/unity
界面展示
PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 20 | 20 |
Estimate | 估计这个任务需要多少时间 | 20 | 10 |
Development | 开发 | 300 | 240 |
Analysis | 需求分析 (包括学习新技术) | 200 | 180 |
Design Spec | 生成设计文档 | 15 | 20 |
Design Review | 设计复审 | 5 | 5 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 0 | 0 |
Design | 具体设计 | 180 | 180 |
Coding | 具体编码 | 180 | 180 |
Code Review | 代码复审 | 60 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 180 | 120 |
Reporting | 报告 | 60 | 100 |
Test Repor | 测试报告 | 120 | 90 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1430 | 1330 |
解题思路描述
“完成一个有图形化界面的计算机”在拿到这个作业题目后我首先有点发懵,因为在我的印象中曾经并没有过开发图形化界面的经历,但是在经过短暂的思考后,我意识到可以使用unity引擎为载体,使用c#语言和unity自带的button组件来实现题目的要求,并且unity作为通用的引擎,将成品打包成exe等可执行文件也是十分方便
问题1
如何实现可视化界面
问题2
如何将项目打包导出
接口设计和实现过程
unity作为成熟的引擎,自带了button组件,可通过对按键的点击来形成输入
通过对button的相对路径访问来绑定button的功能
BtnReset.onClick.AddListener(() => OperationDispose("CE"));
BtnDelete = GameObject.Find("CanvaBs/Background/删除").GetComponent<Button>();
关键代码展示
这部分定义了计算机所展示的各种按钮,并且通过它们在unity的画布中的相对路径与c#中定义的代码一一绑定。
并且定义了textcomputeprogress来展示输入的表达式,textcomputeresult来展示计算后的结果。此外,用定runstate义了一次简易计算的四个阶段:清零(或默认),输入第一个操作数,输入操作符,输入第二个操作数(可无),计算结果
private Text TextComputeProcess;//计算过程
private Text TextComputeResult;//计算结果
//基础运算符
private Button BtnReset;
private Button BtnDelete;
private Button BtnAdd;
private Button BtnSub;
private Button BtnMul;
private Button BtnDiv;
private Button BtnEqual;
//三角函数
private Button Btnsin;
private Button Btncos;
private Button Btntan;
//幂运算
private Button Btnpower;
//关闭
private Button BtnClose;
private Button Btn0, Btn1, Btn2, Btn3, Btn4, Btn5, Btn6, Btn7, Btn8, Btn9;
private Button BtnPoint, BtnPm;
private string calculateString = "0";//计算数
private string m_operation = "";//操作数
private bool pmState = false;//正负状态
private int RUNSTATE = 0;//0 默认 1 输入数字 2 输入操作符 3 输入操作符再输入数字 4 计算结果后
这段代码定义了各种操作符的按钮按下后对operationdispose的更改,后续对于如何计算的核心就在于operationdispose的字符串内容
case "+":
if (RUNSTATE == 0)
TextComputeProcess.text = "0 + ";
else
{
TextComputeProcess.text = TextComputeResult.text + " + ";
m_operation = "+";
RUNSTATE = 2;
}
break;
case "-":
if (RUNSTATE == 0)
TextComputeProcess.text = "0 - ";
else
{
TextComputeProcess.text = TextComputeResult.text + " - ";
m_operation = "-";
RUNSTATE = 2;
}
break;
case "*":
{
TextComputeProcess.text = TextComputeResult.text + " * ";
m_operation = "*";
RUNSTATE = 2;
}
break;
case "/":
{
TextComputeProcess.text = TextComputeResult.text + " / ";
m_operation = "/";
RUNSTATE = 2;
}
break;
//三角函数
case "s":
{
TextComputeProcess.text = " sin " + TextComputeResult.text;
m_operation = "s";
RUNSTATE = 3;
}
break;
case "c":
{
TextComputeProcess.text = " cos " + TextComputeResult.text;
m_operation = "c";
RUNSTATE = 3;
}
break;
case "t":
{
TextComputeProcess.text = " tan " + TextComputeResult.text;
m_operation = "t";
RUNSTATE = 3;
}
break;
//幂次方
case "^":
{
TextComputeProcess.text = TextComputeResult.text + " ^ ";
m_operation = "^";
RUNSTATE = 2;
}
break;
当按下等于号后,对输入的数字和符号进行运算
case "=":
if (RUNSTATE == 0)
TextComputeProcess.text = "0 = ";
else
{
if (RUNSTATE == 3)
{
double result;
switch (m_operation)
{
case "+":
result = double.Parse(calculateString) + double.Parse(TextComputeResult.text);
TextComputeProcess.text = calculateString + " + " + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "-":
result = double.Parse(calculateString) - double.Parse(TextComputeResult.text);
TextComputeProcess.text = calculateString + " - " + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "*":
result = double.Parse(calculateString) * double.Parse(TextComputeResult.text);
TextComputeProcess.text = calculateString + " * " + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "/":
result = double.Parse(calculateString) / double.Parse(TextComputeResult.text);
TextComputeProcess.text = calculateString + " / " + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "^":
result = Math.Pow(double.Parse(calculateString) , double.Parse(TextComputeResult.text));
TextComputeProcess.text = calculateString + " ^ " + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "s":
result = Math.Round ((Math.Sin ( Math.PI * (double.Parse(TextComputeResult.text) / 180 ) ) ) , 5 );
TextComputeProcess.text = "sin" + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "c":
result = Math.Round ((Math.Cos ( Math.PI * (double.Parse(TextComputeResult.text) / 180 ) ) ) , 5 );
TextComputeProcess.text = "cos" + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
case "t":
result = Math.Round ((Math.Tan ( Math.PI * (double.Parse(TextComputeResult.text) / 180 ) ) ) , 5 );
TextComputeProcess.text = "tan" + TextComputeResult.text + " = ";
TextComputeResult.text = result.ToString();
RUNSTATE = 4;
break;
default:
break;
}
}
else
{
TextComputeProcess.text = TextComputeResult.text + " = ";
}
}
break;
性能改进
在完成了基础的功能后,我引入system库中的math类,完成了附加功能中基本的三角函数,幂次方计算等科学计算功能,并且对输入的流程进行了优化,其主要体现为
在输入多个操作符时,后输入的操作符会覆盖前一个输入的操作符,并将原来的第二个操作数变成第一个操作数
if (RUNSTATE == 0)
{
TextComputeResult.text = num;
RUNSTATE = 1;
}
else if (RUNSTATE == 1)
{
pmState = false;
TextComputeResult.text += num;
}
else if (RUNSTATE == 2)
{
calculateString = TextComputeResult.text;
TextComputeResult.text = "";
TextComputeResult.text += num;
RUNSTATE = 3;
}
else if (RUNSTATE == 3)
{
TextComputeResult.text += num;
}
else if (RUNSTATE == 4)
{
OperationDispose("CE");
TextComputeResult.text = num;
RUNSTATE = 1;
}
break;
单元测试
对于单元测试,我分别对每个运算符都进行了测试,结果都通过。
以下是加法部分的
public void Testadd(int a, int b)
{
// arrange
int a = 2;
int b = 3;
// act
int res = new Add().Testadd(a, b);
// assert
Assert.AreEqual(a + b, res);
}
异常处理
对于除0,tan90°等情况,会分别显示infinity和无穷大,但是在0/0的时候,显示的内容是nan,此外若得出的结果或输入的数字长度>显示框的大小,则会省略超出的部分
心得体会
在这次作业中我学会了如何开发一个简单的计算器,此前没有过c#经验的我在对c#进行短暂的学习后成功完成了一个具有加减乘除,三角函数,幂次运算的计算器,并且利用unity便于导入素材和调整素材形状,颜色等特点,美化了计算器的外观,添加了按键音,让其看起来有种日常生活中使用的计算器的美感。在完成基础功能后对一些可能出现的错误进行了预处理,在计算出错时展示可能出现错误的内容。这些对我的变成技能和对软件工程的理解和领悟有了较大的帮助。
此外,在这个项目中我也有不足之处,如在构建计算机时就没考虑过较长的计算式的计算,只考虑到了 操作数+操作符+操作数 的计算模式,这在后来进行异常处理的时候只能使用覆盖的操作来处理连续输入多个数字进行运算的情况。在未来,我会将在这个项目中得到的经验总结并加以运用到未来的作业中去,努力提升自己的业务水平