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

2
  • 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)); Commented Sep 9, 2020 at 6:52
  • see the duplicate link. In particular this answer suggests exactly that Commented Sep 9, 2020 at 7:02

1 Answer 1

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);
Sign up to request clarification or add additional context in comments.

4 Comments

it works, im testing now, ill only need to replace the "s" in the string with the "Stat" value and do that what i'm looking for, without this complex string reading behavior
i need to test if compile in Web gl or in a standalone ap, but in the editor is working
@AgustínZero1 str = str.Replace("Stat", "125");
@RomanRyzhiy rather something like str = str.Replace("s", Stat.ToString()); ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.