Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.
To
C# class. It evaluates recursively for addition and multiplication, left-to-right for chained die rolls
Edits:
.Replace(" ","")
on each call.Trim()
on int.TryParse
insteadif
statementMinified: (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));
}