Evaluate dice rolling notation strings

前端 未结 14 1639
甜味超标
甜味超标 2021-01-30 14:55

Rules

Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.

To

14条回答
  •  误落风尘
    2021-01-30 15:12

    C# class. It evaluates recursively for addition and multiplication, left-to-right for chained die rolls

    Edits:

    • Removed .Replace(" ","") on each call
    • Added .Trim() on int.TryParse instead
    • All work is now done in single method
    • If die face count is not specified, assumes 6 (see Wiki article)
    • Refactored redundant call to parse left side of "d"
    • Refactored unnecessary if statement

    Minified: (411 bytes)

    class D{Random r=new Random();public int R(string s){int t=0;var a=s.Split('+');if(a.Count()>1)foreach(var b in a)t+=R(b);else{var m=a[0].Split('*');if(m.Count()>1){t=1;foreach(var n in m)t*=R(n);}else{var d=m[0].Split('d');if(!int.TryParse(d[0].Trim(),out t))t=0;int f;for(int i=1;i

    Expanded form:

        class D
        {
            /// Our Random object.  Make it a first-class citizen so that it produces truly *random* results
            Random r = new Random();
    
            /// Roll
            /// string to be evaluated
            /// result of evaluated string
            public int R(string s)
            {
                int t = 0;
    
                // Addition is lowest order of precedence
                var a = s.Split('+');
    
                // Add results of each group
                if (a.Count() > 1)
                    foreach (var b in a)
                        t += R(b);
                else
                {
                    // Multiplication is next order of precedence
                    var m = a[0].Split('*');
    
                    // Multiply results of each group
                    if (m.Count() > 1)
                    {
                        t = 1; // So that we don't zero-out our results...
    
                        foreach (var n in m)
                            t *= R(n);
                    }
                    else
                    {
                        // Die definition is our highest order of precedence
                        var d = m[0].Split('d');
    
                        // This operand will be our die count, static digits, or else something we don't understand
                        if (!int.TryParse(d[0].Trim(), out t))
                            t = 0;
    
                        int f;
    
                        // Multiple definitions ("2d6d8") iterate through left-to-right: (2d6)d8
                        for (int i = 1; i < d.Count(); i++)
                        {
                            // If we don't have a right side (face count), assume 6
                            if (!int.TryParse(d[i].Trim(), out f))
                                f = 6;
    
                            int u = 0;
    
                            // If we don't have a die count, use 1
                            for (int j = 0; j < (t == 0 ? 1 : t); j++)
                                u += r.Next(1, f);
    
                            t += u;
                        }
                    }
                }
    
                return t;
            }
        }
    

    Test cases:

        static void Main(string[] args)
        {
            var t = new List();
            t.Add("2d6");
            t.Add("2d6d6");
            t.Add("2d8d6 + 4d12*3d20");
            t.Add("4d12");
            t.Add("4*d12");
            t.Add("4d"); // Rolls 4 d6
    
            D d = new D();
            foreach (var s in t)
                Console.WriteLine(string.Format("{0}\t{1}", d.R(s), s));
        }
    

提交回复
热议问题