static void Main(string[] args) { // Skapar två tärningsobjekt. Die die1 = new Die(); Die die2 = new Die(); // Kastar de två tärningarna och skriver ut // resultatet av tärningskasten. for (int i = 0; i < 1000; ++i) { Console.WriteLine("1: {0}\t2: {1}", die1.Roll(), die2.Roll()); } // Skriver ut resultatet av det senaste // kastet med den första tärningen. Console.WriteLine(die1); }
public void AddNewDie(int sides) { Die d = new Die(sides); this.Dice.Add(d); }
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); }
/// <summary> /// Roll a single die for its quantity and return an array with the results /// </summary> /// <param name="die"></param> /// <returns></returns> private List <int> RollDie(Die die) { List <int> dieRolls = new List <int>(); RollDelegate callback = this.Standard; int sides = die.Sides; // Ensure roll quantity is valid die.Quantity = (die.Quantity > 0) ? die.Quantity : 1; // Check for non-numerical dice formats if (die.Fudge) { // We have a fudge dice. Set the callback to fudge callback = this.Fudge; // Set the sides to the correct value for the fudge type if (die.FudgeString.Length < 2 || !int.TryParse(die.FudgeString[1].ToString(), out sides)) { // Well, it's not a number. Use default sides = 2; } } else if (die.SidesString == "%") { // It's a percentile sides = 100; } if (sides > 0) { List <int> rerolls; int rollCount = 0; int rerollIndex = 0; int roll = 0; // Loop through and roll for the quantity for (int i = 0; i < die.Quantity; ++i) { rerolls = new List <int> (); rollCount = 0; roll = 0; rerollIndex = 0; // Roll the die once, then check if it exploded and keep rolling until it stops do { rerollIndex = rerolls.Count; // Get total roll on this die roll = callback.Invoke(sides); // Add the roll to our list //rerolls[rerollIndex] = rerolls[rerollIndex] + roll; rerolls.Add(roll); // Subtract 1 from penetrated rolls (only consecutive rolls, after initial roll are not subtracted) if (die.Penetrate && rollCount > 0) { rerolls[rerollIndex]--; } rollCount++; } while (die.Explode && IsComparePoint(die.ComparePoint, roll)); // Add the rolls dieRolls.AddRange(rerolls); } } return(dieRolls); }
internal void RequestDiceRoll() { while (_dicecount > Dice.Count) Dice.Add(new Die(SelectedDieType)); while (_dicecount < Dice.Count) Dice.RemoveAt(Dice.Count - 1); foreach (var die in Dice) die.Roll(); while (BonusDice > 0 && App.Rules.RuleOfSixesEnabled) { var d = new Die(SelectedDieType); Dice.Add(d); d.Roll(); BonusDice--; } var badCount = 0; var hitCount = 0; foreach (var die in Dice) { if (die.Value >= App.Rules.HitThreshold) hitCount++; else if (die.Value == 1) badCount++; } if (badCount >= Math.Max((Dice.Count / 2.0) - (GremlinsEnabledSwitch ? GremlinsCount : 0), 0)) { if (hitCount == 0) HitStatus = "CRITICAL GLITCH!"; else HitStatus = string.Format("Glitch, {0} Hits", hitCount); HitStatusColor = App.Brushes.GlitchColor; } else { HitStatus = string.Format("{0} Hits!", hitCount); HitStatusColor = App.Brushes.NormalColor; } PropertyChanged(this, new PropertyChangedEventArgs("HitStatus")); PropertyChanged(this, new PropertyChangedEventArgs("HitStatusColor")); }