using System.Security.Cryptography; using System.Text.RegularExpressions; using Dungeoneer.Lexing; namespace Dungeoneer { public class RollResult { public dynamic Value { get; private set; } private RollResult() { Value = null; } public RollResult(string expression) { Value = Scripting.Expr($"eval('{expression}')"); } internal static class Style { internal const string Default = "\x1b[1m"; internal const string BoolTrue = "\x1b[32;1m"; internal const string BoolFalse = "\x1b[31;1m"; } public override string ToString() { string style; switch(Value) { case bool boolValue: style = boolValue ? Style.BoolTrue : Style.BoolFalse; break; default: style = Style.Default; break; } return $"{style}{Value}{Format.Reset}"; } public static RollResult Wrap(dynamic value) { var output = new RollResult(); output.Value = value; return output; } } public class RollExpression { private IList Parts; public string Print { get; private set; } public string Expression { get; private set; } public RollResult Result { get { try { return new RollResult(Expression); } catch { return null; } } } 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 = DiceToken.Match(piece); if(dieCheck.Success) { var token = new DiceToken(dieCheck); this.Print += $"{token} "; this.Expression += $"{token.Value} "; } else { var part = $"{piece} "; this.Expression += part; this.Print += part; } } } } public static class RollMacro { public static void Pool(IList args) { DiceToken? dice = null; int? dc = null; for(int i = 1; i < args.Count; i++) { string arg = args[i]; var dieCheck = DiceToken.Match(arg); if(dieCheck.Success) dice = new DiceToken(dieCheck); else dc = int.Parse(arg); } var rolls = dice.Result; bool success = false; foreach(var roll in rolls) if(roll > dc.Value) { success = true; break; } var result = RollResult.Wrap(success); Console.WriteLine($"{dice}\n => {result}"); } } }