0

my problem is the next, i'm trying to make a method to do a mathematical operation parsed from string, for example string operation = "20-2/2" and the result = 19

the objective is to do a field that the user can write the mathematical expression to calculate a Stat modifier (a stat used in tabletop games)

this is the code that i was able to make (sorry for the Spanish names, im from Latam)

public int id = 0;

public int Stat = 20;

public bool ejecutarComprobacion = false;

public string textoStatString;
//public string textoMultiStringCalculation = "(Stat - 10) / 2";
public string textoMultiStringCalculation = "s - 10 / 2";
public int resultado;
public string textoMultiString;
public string textoValueString;

public TMP_InputField textoStatImput;
public TMP_Text textoMulti;
public TMP_Text textoValue;

public GameObject panelValue;

public bool tieneMulti = true;
public bool multiArriba = true;

void Update()
{
    if (ejecutarComprobacion) {
        parseMathOperation();
        ejecutarComprobacion = false;
    }   
}

public void parseMathOperation() {

    string operadoresPermitidos = "-+/*";
    string numeros = "0123456789";

    //reseteo el resultado
    resultado = 0;

    //en esta variable guardo el numero capturado
    int numeroCapturado = 0;

    //estas son para capturar operaciones y numeros
    char operacionCapturada = ' ';
    string numeroCompleto = "";

    //estas son para capturar los estados de las operaciones (si es negativo, si es mas largo el nui)
    bool negativo = false;
    bool operacion = false;
    bool Comprobado = false;

    //Debug.Log("Operacion : " + textoMultiStringCalculation);

    for (int i = 0; i < textoMultiStringCalculation.Length; i++)
    {
        if (numeros.IndexOf(textoMultiStringCalculation[i]) != -1) {
            //Debug.Log(textoMultiStringCalculation[i] + " es Numero");
            Comprobado = false;

            numeroCompleto = "";

            while (Comprobado == false) {

                numeroCompleto += textoMultiStringCalculation[i];

                if (i + 1 >= textoMultiStringCalculation.Length)
                {
                    //Debug.Log("numero : " + numeroCompleto);
                    Comprobado = true;
                }
                else {

                    if (numeros.IndexOf(textoMultiStringCalculation[i + 1]) != -1)
                    {
                        i++;
                        Comprobado = false;
                    }
                    else
                    {
                        //Debug.Log("numero : " + numeroCompleto);
                        Comprobado = true;
                    }
                }
            }

            if (operacion == false)
            {

                if (negativo == true)
                {
                    int.TryParse("-" + numeroCompleto, out numeroCapturado);
                    resultado += numeroCapturado;
                    negativo = false;
                }
                else
                {
                    int.TryParse(numeroCompleto, out numeroCapturado);
                    resultado += numeroCapturado;
                }
            }
            else
            {
                int.TryParse(numeroCompleto, out numeroCapturado);
                resultado = operar(resultado, operacionCapturada, numeroCapturado);
            }

        }
        else if (operadoresPermitidos.IndexOf(textoMultiStringCalculation[i]) != -1)
        {
            //Debug.Log(textoMultiStringCalculation[i] + " es operador");
            if (resultado == 0)
            {
                negativo = true;
            }
            else {
                operacion = true;
                operacionCapturada = textoMultiStringCalculation[i];
            }

        } else if (textoMultiStringCalculation[i] == ' ')
        {
            // Debug.Log(textoMultiStringCalculation[i] + " es espacio");

        } else if (textoMultiStringCalculation[i] == 's')
        {
            //Debug.Log(textoMultiStringCalculation[i] + " es stat(" + Stat + ")");
            if (operacion == false)
            {

                if (negativo == true)
                {
                    resultado -= Stat;
                    negativo = false;
                }
                else
                {
                    //Debug.Log("resultado += Stat(" + Stat + ")");
                    resultado += Stat;
                }
            }
            else
            {
                resultado = operar(resultado, operacionCapturada, Stat);
            }

        }
    }

    if (resultado < 0)
    {
        textoMultiString = "" + resultado;
    }
    else {
        textoMultiString = "+" + resultado;
    }
   
}

public int operar(int parametro1, char charOperacion, int parametro2) {

    switch (charOperacion) {
        case '-':
            return parametro1- parametro2;
        case '+':
            return parametro1 + parametro2;
        case '/':
            return parametro1 / parametro2;
        case '*':
            return parametro1 * parametro2;
    }

        return 0;
}

it's almost there, "s" is the stat (in this case 20) but im having a problem, the operations are not in "Mathematical" order

Example

"(20 - 10) / 2" = 5 => parsed as Error (im not parsing "(" or ")" yet)

"20 - 10 / 2" = 15 => parsed as "20 - 10" = 10 | 10/2 = 5 | result = 5 (this is incorrect)

i don't know how to continue to make it capable to do combined mathematical operation from the correct order

  • I don´t know if you can reference `System.Data` in Unity but if so, you could just go: `double result = Convert.ToDouble(new DataTable().Compute("(20-10)/2", null));` – Alex B. Sep 09 '20 at 06:52
  • see the duplicate link. In particular [this answer](https://stackoverflow.com/a/11029886/7111561) suggests exactly that – derHugo Sep 09 '20 at 07:02

1 Answers1

0

There is a small and simple trick to compute the given expression:

DataTable table = new DataTable();
double d = (double)table.Compute("(20 - 10) / 2", null);
Roman Ryzhiy
  • 1,046
  • 6
  • 5