using System.Security.Cryptography; using System.Text.RegularExpressions; namespace Dungeoneer { public static class Util { public static int Roll(int sides) { return RandomNumberGenerator.GetInt32(sides) + 1; } } public class RollExpression { private IList Parts; public string Print { get; private set; } public string Expression { get; private set; } public dynamic Result { get { try { return Scripting.Expr($"eval('{Expression}')"); } catch { return null; } } } private const string DieFormat = "\x1b[34;1m"; private static readonly Regex DiePattern = new Regex(@"(\d+)d(\d+)"); public RollExpression(IList parts) { this.Parts = parts; this.Print = ""; this.Expression = ""; // build expression from string parts foreach(string piece in Parts) { // die expression substitution var dieCheck = DiePattern.Match(piece); if(dieCheck.Success) { // get /(d+)/ capture group values var count = int.Parse(dieCheck.Groups[1].Value); var sides = int.Parse(dieCheck.Groups[2].Value); // and build roll outcomes this.Print += $"{DieFormat}( "; this.Expression += "( "; for(int i = 0; i < count; i++) { var roll = Util.Roll(sides); if(i < count - 1) { this.Print += $"{roll}, "; this.Expression += $"{roll} + "; } else { var part = $"{roll} "; this.Print += $"{roll} ){Format.Reset} "; this.Expression += $"{roll} ) "; } } } else { var part = $"{piece} "; this.Expression += part; this.Print += part; } } } } }