roll command is now object-oriented and pretty-prints output
This commit is contained in:
parent
1c6603be0a
commit
48799dc0a7
3 changed files with 75 additions and 46 deletions
52
Command.cs
52
Command.cs
|
@ -8,54 +8,14 @@ namespace Dungeoneer {
|
||||||
// don't do anything with empty expressions
|
// don't do anything with empty expressions
|
||||||
if(args.Count == 0)
|
if(args.Count == 0)
|
||||||
return;
|
return;
|
||||||
var expression = "";
|
|
||||||
|
|
||||||
var diePattern = new Regex(@"\d+d\d+");
|
// create new parsed expression object and pretty-print
|
||||||
|
var roll = new RollExpression(args);
|
||||||
// reassemble split args and substitute die notation
|
var result = roll.Result;
|
||||||
foreach(string arg in args) {
|
if(result == null)
|
||||||
string part;
|
|
||||||
|
|
||||||
var dieCheck = diePattern.Match(arg);
|
|
||||||
if(dieCheck.Success) {
|
|
||||||
var parts = arg.Split('d');
|
|
||||||
var first = parts[0];
|
|
||||||
var second = parts[1];
|
|
||||||
|
|
||||||
int count;
|
|
||||||
int sides;
|
|
||||||
try {
|
|
||||||
count = int.Parse(first);
|
|
||||||
sides = int.Parse(second);
|
|
||||||
} catch {
|
|
||||||
Console.WriteLine("'{arg}' is not a valid dice expression");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var rolls = "( ";
|
|
||||||
for(int i = 0; i < count; i++) {
|
|
||||||
string result;
|
|
||||||
var roll = Util.Roll(sides);
|
|
||||||
if(i < count - 1)
|
|
||||||
result = $"{roll} + ";
|
|
||||||
else
|
|
||||||
result = $"{roll} ";
|
|
||||||
rolls += result;
|
|
||||||
}
|
|
||||||
rolls += ")";
|
|
||||||
part = rolls;
|
|
||||||
} else
|
|
||||||
part = arg;
|
|
||||||
expression += $"{part} ";
|
|
||||||
}
|
|
||||||
|
|
||||||
dynamic output;
|
|
||||||
try { output = Scripting.Expr($"eval('{expression}')"); }
|
|
||||||
catch {
|
|
||||||
Console.WriteLine("invalid expression");
|
Console.WriteLine("invalid expression");
|
||||||
return;
|
else
|
||||||
}
|
Console.WriteLine($"{roll.Print}\n => {result}");
|
||||||
Console.WriteLine($"{expression}\n=> {output}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
16
Format.cs
Normal file
16
Format.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
namespace Dungeoneer {
|
||||||
|
|
||||||
|
public static class Format {
|
||||||
|
|
||||||
|
public const string Reset = "\x1b[0m";
|
||||||
|
|
||||||
|
public const string Black = "\x1b[30m";
|
||||||
|
public const string Red = "\x1b[31m";
|
||||||
|
public const string Green = "\x1b[32m";
|
||||||
|
public const string Yellow = "\x1b[33m";
|
||||||
|
public const string Blue = "\x1b[34m";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
53
Util.cs
53
Util.cs
|
@ -1,4 +1,5 @@
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Dungeoneer {
|
namespace Dungeoneer {
|
||||||
|
|
||||||
|
@ -10,5 +11,57 @@ namespace Dungeoneer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue