一. 创作工具:
unity
二. 简单计算器的介绍:
此简单计算器仅实现了加减乘除的功能,输入计算的表达式再输入“=” 就能在Result那里显示结果,点击Restart就清零重新开始进行运算;另外,在代码中运用栈的逻辑实现了运算的优先级,即乘法和除法运算的优先级自动高于加法和减法,计算器会自动判断先进行优先级高的运算。
B站游戏演示链接:3D游戏编程与设计第三次作业之自制简单计算器_哔哩哔哩_bilibili
3D游戏编程与设计第三次作业之自制简单计算器
三. 代码+逻辑解释:
代码严格分为三部分,并且满足三部分之间的约束关系:
首先,定义一些实体以及初始化作为游戏模型
首先定义输入input和输出result,都定义为字符串的类型,input用来获取用户输入的计算表达式,result用来输出表达式的计算结果。
// Entities and their states / Model
private string input = "";
private string result = "";
private int m;
然后,给出一些可以修改游戏模型的组件/控件。
代码思路:
1. 先运用函数将输入的表达式用'+'、'-'、'*'、'/'四个运算符拆分,拆分出操作数和运算符(但这个split函数没法正确拆分出运算符,如果拆分出来的操作数不是一位数的话这个函数拆分的运算符就会出错,比如拆成'6/'),所以单独运用了正则表达式[-+*/]来匹配操作符,匹配到的操作符就添加到操作符列表中去,再通过遍历将操作符列表中的操作符都添加到数组中去方便后面使用。
2. 这里如果操作数小于2或者没有运算符的话就会输出“操作数不足”的提示结果。
3. 接下来的优先级设计就要运用到栈了,一个栈是操作数栈,一个栈是运算符栈,先按顺序压入两个操作数和一个运算符,然后开始进行循环判断,如果运算符栈的栈顶的元素是'*'或者'/'的话就把栈顶运算符弹出,然后操作数栈弹出两个操作数进行'*'或者'/'的操作,得到的结果再压入操作数栈中,然后还要再压入一个操作数和一个运算符;如果栈顶元素是'+'或者'-'的话就根据flag的值进行判断(当操作符里面只有'+'或者'-'的情况下flag值变为1;当所有的'*'或者'/'都弹出栈了只剩'+'或者'-'的情况下flag的值也变为1),如果flag值不为1的话遇到'+'或者'-'就直接压入运算符栈中,并且把下一个操作数压入操作数栈中;如果flag值为0的话就弹出两个操作数和一个运算符进行'+'或者'-'运算并且把结果压入栈中。
简单来说,就是利用栈实现优先运算乘法和除法。
4. 最终当运算符栈空了之后就可以结束循环。
5. 结束循环后栈顶的元素就是最终表达式的结果。
6. 如果判断到除数为0就要直接返回“除数不为0”的提示。
private string Calculate(string expression)
{
Stack <float> number=new Stack<float> ();
Stack <string> alphbet=new Stack<string> ();
float result = 0;
string[] operands = expression.Split(new char[] { '+', '-', '*', '/' });
//string[] operators = expression.Split(operands, StringSplitOptions.RemoveEmptyEntries);
string operatorPattern = @"[-+*/]";
List<string> operatorList = new List<string>();
MatchCollection operatorMatches = Regex.Matches(expression, operatorPattern);
// 将匹配到的操作符添加到操作符列表
foreach (Match match in operatorMatches)
{
operatorList.Add(match.Value);
}
string[] operators = operatorList.ToArray();
// float[] operands=new float[100];
if(operands.Length<2 |operators.Length==0){
return "操作数不足";
}
//先放入两个操作数和一个操作符
number.Push(float.Parse(operands[0]));
number.Push(float.Parse(operands[1]));
alphbet.Push(operators[0]);
int m=operands.Length;
int n=operators.Length;
Console.WriteLine("m和n的值是"+m+","+n);
print(m);
int flag=0;
int flga2=0;
print(operators.Length);
for(int l=0;l<n;l+=1){
if(operators[l]=="*"|operators[l]=="/")flga2=1;
print(operators[l]);
}
if(flga2==0)flag=1;
int i=1,j=0;
while(alphbet.Count!=0){
if(alphbet.Peek()=="*"|alphbet.Peek()=="/"){
float x1=number.Pop();
float x2=number.Pop();
if(alphbet.Peek()=="*")number.Push(x1*x2);
else {
if(x1!=0)number.Push(x2/x1);
else return "除数不为0";
}
alphbet.Pop();
i++;j++;
if(i<m&&j<n){
number.Push(float.Parse(operands[i]));
alphbet.Push(operators[j]);
if(i==m-1&&j==n-1)flag=1;
}
else{
flag=1;
}
}
else{
i++;j++;
if(i<m&&j<n){
number.Push(float.Parse(operands[i]));
alphbet.Push(operators[j]);
}
else{
if(flag==1){
float x1=number.Pop();
float x2=number.Pop();
if(alphbet.Peek()=="+")number.Push(x1+x2);
else number.Push(x1-x2);
alphbet.Pop();
}
}
}
}
result=number.Peek();
return result.ToString();
}
最后,游戏循环调用的系统处理程序OnGUI提供了游戏的用户界面视图。
利用GUI.Box创建大的矩形框,再用GUI.Button创建按钮,创建0-9的按钮以及加减乘除按钮以及“=”按钮和清零按钮,输入和输出对应于输入的表达式和输出的结果。
void OnGUI()
{
GUI.Box(new Rect(200, 10, 450, 450), "");
if (GUI.Button(new Rect(460, 400, 100, 30), "Restart"))
{
Init();
}
if (GUI.Button(new Rect(255, 50, 70, 70), "7"))
{
input += "7";
}
if (GUI.Button(new Rect(335, 50, 70, 70), "8"))
{
input += "8";
}
if (GUI.Button(new Rect(415, 50, 70, 70), "9"))
{
input += "9";
}
if (GUI.Button(new Rect(495, 50, 70, 70), "+"))
{
input += "+";
}
if (GUI.Button(new Rect(255, 130, 70, 70), "4"))
{
input += "4";
}
if (GUI.Button(new Rect(335, 130, 70, 70), "5"))
{
input += "5";
}
if (GUI.Button(new Rect(415, 130, 70, 70), "6"))
{
input += "6";
}
if (GUI.Button(new Rect(495, 130, 70, 70), "-"))
{
input += "-";
}
if (GUI.Button(new Rect(255, 210, 70, 70), "1"))
{
input += "1";
}
if (GUI.Button(new Rect(335, 210, 70, 70), "2"))
{
input += "2";
}
if (GUI.Button(new Rect(415, 210, 70, 70), "3"))
{
input += "3";
}
if (GUI.Button(new Rect(495, 210, 70, 70), "*"))
{
input += "*";
}
if (GUI.Button(new Rect(255, 290, 70, 70), "0"))
{
input += "0";
}
if (GUI.Button(new Rect(335, 290, 70, 70), "."))
{
input += ".";
}
if (GUI.Button(new Rect(415, 290, 70, 70), "="))
{
result = Calculate(input);
}
if (GUI.Button(new Rect(495, 290, 70, 70), "/"))
{
input += "/";
}
GUI.Label(new Rect(255, 380, 310, 30), "Input: "+input);
GUI.Label(new Rect(255, 400, 310, 30), "Result: " + result);
}