示例#1
0
        public static MinMax CalculateDiceRoll(DiceRoll diceRoll)
        {
            // check if dice roll is too large
            foreach (var die in diceRoll.Dice)
            {
                if (Math.Pow(die.DiceType, die.TotalDiceAmount) > int.MaxValue) // basically >2.5billion
                {
                    Printer.PrintError("Dice roll too large to calculate in a decent amount of time");
                    return(new MinMax(0, 0, 0));
                }
            }

            var calcs = CalculateMinAndMaxValues(diceRoll);
            var min   = calcs.First().Key;
            var max   = calcs.Last().Key;

            float tempAvg = 0f;

            foreach (var item in calcs)
            {
                tempAvg += item.Key * item.Value.Percentage;
            }
            var avg = (float)Math.Round(tempAvg / 100, 3);

            // round percentages to three decimals after finding average
            foreach (var item in calcs)
            {
                item.Value.Percentage = (float)Math.Round(item.Value.Percentage, 3);
            }

            return(new MinMax(min, avg, max, calcs));
        }
示例#2
0
        public static int RollDice(DiceRoll diceRoll, int?seed = null)
        {
            var rolls          = GetDiceRolls(diceRoll.Dice, seed);
            var rollBeforeMods = AddRolls(rolls);
            var roll           = AddModifiers(rollBeforeMods, diceRoll.Modifiers);

            return(roll);
        }
示例#3
0
        public static void Print(string line, DiceRoll result)
        {
            string separator = new string('-', line.Length);

            Console.WriteLine($"\n  {line}\n  {separator}");

            var    die         = result.Dice.First();
            string lineToPrint = $"  {die.TotalDiceAmount}d{die.DiceType}";
            var    mod         = result.Modifiers.First();

            if (mod.Number != 0)
            {
                lineToPrint += $" {mod.Operation} {mod.Number}";
            }
            lineToPrint += "\n";
            Console.WriteLine(lineToPrint);
        }
示例#4
0
        private static Dictionary <int, Calculations> CalculateMinAndMaxValues(DiceRoll diceRoll)
        {
            var summedMatrix = new List <int>();

            foreach (var die in diceRoll.Dice)
            {
                var dice = new List <int>();
                for (int i = 0; i < die.TotalDiceAmount; i++)
                {
                    dice.Add(die.DiceType);
                }

                int rows          = (int)Math.Pow(die.DiceType, die.TotalDiceAmount);
                var partialMatrix = new List <int> [rows];
                var diceIndex     = 0;
                var rowIndex      = 0;
                CalculateRecursively(dice, ref diceIndex, partialMatrix, ref rowIndex, colList: new List <int>());

                // TODO: merge with DiceRoller.GetDiceRolls
                if (die.KeepAmount != 0 && die.KeepAmount < die.TotalDiceAmount)
                {
                    foreach (var row in partialMatrix)
                    {
                        row.Sort();
                        var amtToRemove = die.TotalDiceAmount - die.KeepAmount;
                        if (die.KeepHigh)
                        {
                            row.RemoveRange(0, amtToRemove);
                        }
                        else
                        {
                            row.RemoveRange(die.KeepAmount, amtToRemove);
                        }
                    }
                }

                // add together each row of the partial matrix,
                // turning it negative if the die operation is subtract
                var dieSumMatrix = partialMatrix.Select(row =>
                {
                    var sum = 0;
                    foreach (var num in row)
                    {
                        sum += num;
                    }
                    if (die.Operation == Operation.Subtract)
                    {
                        sum *= -1;
                    }
                    return(sum);
                });

                if (summedMatrix.Count == 0)
                {
                    summedMatrix.AddRange(dieSumMatrix);
                }
                else
                {
                    var tempSummedMatrix = new List <int>();
                    foreach (var item in summedMatrix)
                    {
                        foreach (var item2 in dieSumMatrix)
                        {
                            tempSummedMatrix.Add(item + item2);
                        }
                    }
                    summedMatrix = tempSummedMatrix;
                }
            }

            var calcs = new Dictionary <int, Calculations>();

            // calculate frequency of each dice num
            foreach (var num in summedMatrix)
            {
                var key = (int)AddModifiers(num, diceRoll.Modifiers);
                if (calcs.ContainsKey(key))
                {
                    calcs[key].Frequency++;
                }
                else
                {
                    calcs.Add(key, new Calculations(1, 0));
                }
            }

            // put dice nums in order from lowest to highest
            calcs = calcs.OrderBy(kvp => kvp.Key).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            // calculate percentages
            var totalNums = calcs.Values.Sum(v => v.Frequency);

            foreach (var calc in calcs)
            {
                var pct = (calc.Value.Frequency * 100f) / totalNums;
                calc.Value.Percentage = pct;
            }

            return(calcs);
        }