你好,我正在做这个数学游戏,在我的最后一个场景中,我做了很多重复的代码,但我不确定是否有简化它的方法,我在下面链接了,所以一些经验丰富的程序员可能会有一些更优雅的解决方案!例如,Im试图生成类似(a[]b(²[]c[]d的每个排列,其中括号将被+、-、*或/代替。我一直在做的只是创建随机的百分比if语句来选择一个特定的版本,比如";(a+b(²/c-d";是否可能存在一个较小的";暴力";和可读的方法,那么我一直在做什么?
if(UnityEngine.Random.Range(0,101)>50){
// 50% of being (a+b)²(c)+d
if(UnityEngine.Random.Range(0,101)>50){
ans = ((int) Mathf.Pow((float) a+ (float) b, 2))*c+d;
input.text = "("+a+"+"+b+")"+"²"+"("+c+")"+"+"+d+"=";
Debug.Log("Problem ID: 78");
// 50% of being (a+b)²(c)-d
} else {
ans = ((int) Mathf.Pow((float) a+ (float) b, 2))*c-d;
input.text = "("+a+"+"+b+")"+"²"+"("+c+")"+"-"+d+"=";
Debug.Log("Problem ID: 79");
}
// 50% of being (a-b)²(c)[]d
} else {
// 50% of being (a-b)²(c)+d
if(UnityEngine.Random.Range(0,101)>50){
ans = ((int) Mathf.Pow((float) a- (float) b, 2))*c+d;
input.text = "("+a+"-"+b+")"+"²"+"("+c+")"+"+"+d+"=";
Debug.Log("Problem ID: 80");
// 50% of being (a-b)²(c)-d
} else {
ans = ((int) Mathf.Pow((float) a- (float) b, 2))*c-d;
input.text = "("+a+"-"+b+")"+"²"+"("+c+")"+"-"+d+"=";
Debug.Log("Problem ID: 81");
}
(粘贴在下面以获取更多上下文(https://pastebin.pl/view/d1bfb99e
我赞同您希望让代码更可读的愿望。基本思想是拆分(a(定义、(b(选择和(c(应用运算符。
-
步骤1:定义
Operator
s。每个Operator
组合了一个数学运算(例如Add
将是(a, b) => a + b
(和一个符号(例如Add
将是"+"
(。class Operator { public Func<int, int, int> Calculate { get; } public string Symbol { get; } public Operator(Func<int, int, int> calculate, string symbol) { Calculate = calculate; Symbol = symbol; } } private Operator Add = new Operator((a, b) => (a + b), "+"); private Operator Subtract = new Operator((a, b) => (a - b), "-");
-
步骤2:然后你随机选择你的运算符(我使用了
System.Random
,因为我不熟悉Unity,但可以随意用你选择的随机数生成器替换它(:var rnd = new Random(); private (Operator op1, Operator op2, int problemId) RandomlyChooseProblem() { switch (rnd.Next(4)) { case 0: return (Add, Add, 78); case 1: return (Add, Subtract, 79); case 2: return (Subtract, Add, 80); case 3: return (Subtract, Subtract, 81); default: throw new InvalidOperationException("This should not happen."); } }
-
步骤3:应用它们:
var (op1, op2, problemId) = RandomlyChooseProblem(); ans = op2.Calculate((int)Math.Pow(op1.Calculate(a, b), 2) * c, d); input.text = $"(a{op1.Symbol}b)²*c{op2.Symbol}d"); Debug.Log($"Problem ID: {problemId}");
添加新的运算符(例如Multiply
(或新的问题变体(例如(Add, Multiply, 82)
(现在只是一行代码。
将计算分解为a±b
、square * c
和±d
。将它们分别计算,相乘得到最终结果。对于文本,可以使用字符串插值
float ans;
string operator1;
string operator2;
if (UnityEngine.Random.Range(0,101)>50) {
ans = (float) a + (float) b;
operator1 = "+";
} else {
ans = (float) a - (float) b;
operator1 = "-";
}
ans = (int)(ans * ans) * c;
if (UnityEngine.Random.Range(0,101)>50) {
ans += d;
operator2 = "+";
} else {
ans -= d;
operator2 = "-";
}
input.text = $"(a{operator1}b)²(c){operator2}d";
还要注意,UnityEngine.Random.Range(0,101) > 50
并不是50%的概率。你可能是指UnityEngine.Random.Range(1,101) > 50
,但我只是用UnityEngine.Random.Range(0,2) == 0
。
可以通过生成2个随机比特,并将这些比特编码的2比特数添加到78:来对问题ID进行平坦化
float ans;
string operator1;
string operator2;
int random1 = UnityEngine.Random.Range(0,2);
int random2 = UnityEngine.Random.Range(0,2);
if (random1 == 0) {
ans = (float) a + (float) b;
operator1 = "+";
} else {
ans = (float) a - (float) b;
operator1 = "-";
}
ans = (int)(ans * ans) * c;
if (random2 == 0) {
ans += d;
operator2 = "+";
} else {
ans -= d;
operator2 = "-";
}
int problemID = 78 + random1 + random2 * 2;
Debug.Log($"Problem ID: {problemID}");
input.text = $"(a{operator1}b)²(c){operator2}d";
不过,IMO并不是特别容易理解这个技巧。