是否可以减少基于if语句的重复排列



你好,我正在做这个数学游戏,在我的最后一个场景中,我做了很多重复的代码,但我不确定是否有简化它的方法,我在下面链接了,所以一些经验丰富的程序员可能会有一些更优雅的解决方案!例如,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:定义Operators。每个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±bsquare * 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并不是特别容易理解这个技巧。

相关内容

  • 没有找到相关文章

最新更新