Hola, estoy trabajando en este juego de matemáticas y para mi última escena hice lo que se siente como un montón de código repetitivo, pero no estoy seguro de si hay una manera de simplificarlo, he vinculado a continuación, así que tal vez algunos programadores más experimentados podrían haberlo hecho. algunas soluciones más elegantes! Por ejemplo, estoy tratando de generar cada permutación de algo como (a[]b)²[]c[]d donde los corchetes serán reemplazados por +,-,* o /. Lo que he estado haciendo es simplemente crear un porcentaje aleatorio si las declaraciones para elegir una versión específica como "(a+b)²/cd". ¿Existe posiblemente un enfoque menos legible y de "fuerza bruta" que lo que he estado haciendo?
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))*cd; input.text = "("+a+"+"+b+")"+"²"+"("+c+")"+"-"+d+"="; Debug.Log("Problem ID: 79"); } // 50% of being (ab)²(c)[]d } else { // 50% of being (ab)²(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 (ab)²(c)-d } else { ans = ((int) Mathf.Pow((float) a- (float) b, 2))*cd; input.text = "("+a+"-"+b+")"+"²"+"("+c+")"+"-"+d+"="; Debug.Log("Problem ID: 81"); }(Pastebin a continuación para obtener más contexto) https://pastebin.pl/view/d1bfb99e
Aplaudo su deseo de hacer que su código sea más legible. La idea básica es dividir (a) definir, (b) elegir y (c) aplicar sus operadores.
Paso 1: Usted define los Operator . Cada Operator combina una operación matemática (p. ej., Add sería (a, b) => a + b ) y un símbolo (p. ej., Add sería "+" ).
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), "-"); Paso 2: luego elige aleatoriamente sus operadores (utilicé System.Random , ya que no estoy familiarizado con Unity, pero no dude en reemplazarlo con el generador de números aleatorios de su elección):
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."); } }Paso 3: Los aplicas:
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}"); Agregar un nuevo operador (por ejemplo, Multiply ) o una nueva variante del problema (por ejemplo (Add, Multiply, 82) ) ahora es solo una línea de código.
Divida el cálculo en partes -a a±b , square * c y ±d . Calcúlelos por separado y multiplíquelos para obtener el resultado final. Para el texto, puede usar la interpolación de cadenas
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"; También tenga en cuenta que UnityEngine.Random.Range(0,101) > 50 no es exactamente una probabilidad del 50 %. Probablemente quiso decir UnityEngine.Random.Range(1,101) > 50 en su lugar, pero yo solo usaría UnityEngine.Random.Range(0,2) == 0 .
Los ID del problema se pueden aplanar generando 2 bits aleatorios y agregando el número de 2 bits codificado por esos bits a 78:
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";Sin embargo, este truco no es particularmente legible en mi opinión.