67 lines
1.6 KiB
C#
67 lines
1.6 KiB
C#
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<string> 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<string> 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|