public RollResult RollDice(string notation) { List <object> dice = ParseNotation(notation); RollResult result = CalculateResult(dice); result.OriginalNotation = notation; return(result); }
private RollResult CalculateResult(List <object> dice, string initialSymbol = "+") { string symbol = initialSymbol; if (string.IsNullOrEmpty(initialSymbol)) { symbol = "+"; } int num = 0; RollResult result = new RollResult(); // At this point we have a list of dice (Die), numbers (int) and operators (string) foreach (object element in dice) { if (element is List <object> ) { // It's a parenthesis group RollResult parenthesisGroup = CalculateResult(element as List <object>, symbol); result.RolledNotation += $"({parenthesisGroup.RolledNotation})"; result.Result += parenthesisGroup.Result; } else if (element is Die) { // It's a die, roll it Die d = (Die)element; List <int> rolls = RollDie(d); num = rolls.Sum(); string rollNotation = "["; int compoundSum = 0; if (d.Explode || d.Penetrate) { for (int i = 0; i < rolls.Count; ++i) { // Write comma if needed if (i > 0) { if (d.Compound) { if (!IsComparePoint(d.ComparePoint, rolls[i - 1])) { // Die is exploding/penetrating and last number did not match compare point, add a comma because this is a different roll rollNotation += ","; } } else { // There was a number before, add a coma rollNotation += ","; } } if (!d.Compound) { // Write every number rollNotation += rolls[i].ToString(); } else { // Sum the number, we'll write it when the number doesn't match the compare point (last roll of the chain) compoundSum += rolls[i]; } // Die continues exploding/penetrating and is not compount if (!d.Compound && IsComparePoint(d.ComparePoint, rolls[i])) { // It matches the compare point, add explode/penetrate symbol rollNotation += d.Explode ? "!" : "!p"; } else if (d.Compound && !IsComparePoint(d.ComparePoint, rolls[i])) { // Compound dice has finished exploding/penetrating, write number sum and add appropriate symbol rollNotation += compoundSum.ToString(); if (compoundSum > d.Sides) { rollNotation += d.Explode ? "!!" : "!!p"; } compoundSum = 0; } } } else { // Do a simple parsing of the rolls rollNotation += string.Join(",", rolls); } rollNotation += "]"; if (d.Compound) { // Instead replace } result.RolledNotation += rollNotation; } // It's a string that encodes a number or an operator else if (int.TryParse(element as string, out int temp)) { // It's a number num = temp; result.RolledNotation += num; } else { symbol = element as string; result.RolledNotation += symbol; } if (symbol != "" && num != 0) { // Use last operator to combine with result switch (symbol) { case ("+"): result.Result += num; break; case ("-"): result.Result -= num; break; case ("*"): result.Result *= num; break; case ("/"): case ("\\"): result.Result /= num; break; default: result.Result += num; break; } // And clear the last symbol symbol = ""; num = 0; } } return(result); }