예제 #1
0
파일: DiceRoll.cs 프로젝트: Sukasa/Ruby
        // TODO this function seriously needs refactoring at this point - repeated code, super long, etc.

        void DiceRoll(string NumDiceCode, string SidesCode, string Modifier)
        {
            int NumDice;
            int Sides;

            Tuple <string, float>[] Modifiers;

            // Can we get the number of dice?
            if (!int.TryParse(NumDiceCode, out NumDice))
            {
                SayInChannel(CantDoThat);
                return;
            }

            if (NumDice > 16)
            {
                SayInChannel(OutOfRange);
                return;
            }

            // Are we rolling standard dice?
            if (int.TryParse(SidesCode, out Sides))
            {
                try
                {
                    Modifiers = ModifierRegex.Matches(Modifier).Cast <Match>().Select(x => new Tuple <string, float>(x.Groups[2].Value, float.Parse(x.Groups[3].Value))).ToArray();
                }
                catch
                {
                    SayInChannel(CantDoThat);
                    return;
                }

                if (Sides == 2 && Modifiers.Length == 0)
                {
                    SidesCode = "{Heads,Tails}";
                    goto HeadsTails; // Special case for coins
                }

                if (Sides < 2)
                {
                    SayInChannel(CantDoThat);
                    return;
                }

                if (Sides > 100)
                {
                    SayInChannel(OutOfRange);
                    return;
                }

                if (NumDice == 1)
                {
                    float Sum2 = RNG.Next(Sides) + 1;

                    foreach (var Mod in Modifiers)
                    {
                        switch (Mod.Item1)
                        {
                        case "*":
                            Sum2 *= Mod.Item2;
                            break;

                        case "-":
                            Sum2 -= Mod.Item2;
                            break;

                        case "\\":
                        case "/":
                            Sum2 /= Mod.Item2;
                            break;

                        case "+":
                            Sum2 += Mod.Item2;
                            break;
                        }
                    }

                    Sum2 = (float)Math.Floor(Sum2);
                    SayInChannel(string.Format(DiceRollText[RNG.Next(DiceRollText.Length)] + " {0}.", Sum2));

                    return;
                }

                DieRoll[] Rolls = new DieRoll[NumDice];
                for (int i = 0; i < NumDice; i++)
                {
                    Rolls[i] = new DieRoll(RNG.Next(Sides) + 1);
                }

                // TODO Apply modifiers
                if (Modifiers.Length > 0)
                {
                    if (Modifiers[0].Item1.ToLower() == "top")
                    {
                        int ToRemove = NumDice - (int)Modifiers[0].Item2;
                        while (ToRemove >= 1)
                        {
                            Rolls.First(x => x.Valid && x.Value == Rolls.Where(y => y.Valid).Min(y => y.Value)).Valid = false;
                            ToRemove--;
                        }
                    }

                    if (Modifiers[0].Item1.ToLower() == "bottom")
                    {
                        int ToRemove = NumDice - (int)Modifiers[0].Item2;
                        while (ToRemove >= 1)
                        {
                            Rolls.First(x => x.Valid && x.Value == Rolls.Where(y => y.Valid).Max(y => y.Value)).Valid = false;
                            ToRemove--;
                        }
                    }
                }

                float Sum = (int)Rolls.Where(x => x.Valid).Select(x => x.Value).Sum();

                foreach (var Mod in Modifiers)
                {
                    switch (Mod.Item1)
                    {
                    case "*":
                        Sum *= Mod.Item2;
                        break;

                    case "-":
                        Sum -= Mod.Item2;
                        break;

                    case "\\":
                    case "/":
                        Sum /= Mod.Item2;
                        break;

                    case "+":
                        Sum += Mod.Item2;
                        break;
                    }
                }

                Sum = (float)Math.Floor(Sum);

                SayInChannel(string.Format("{0} {1}. ({2})",
                                           DiceRollText[RNG.Next(DiceRollText.Length)],
                                           Sum,
                                           string.Join(", ", Rolls.Where(x => x.Valid).Select(x => x.ToString()))));

                return;
            }

HeadsTails:

            // Are we rolling a custom die style?
            if (SidesCheck.IsMatch(SidesCode))
            {
                // Roll custom die
                string[] CustomSides = SideRegex.Matches(SidesCode).Cast <Match>().Select(x => x.Groups[1].Value).ToArray();

                string[] Rolls = new string[NumDice];
                for (int i = 0; i < NumDice; i++)
                {
                    Rolls[i] = CustomSides[RNG.Next(CustomSides.Length)];
                }

                SayInChannel(string.Format(DiceRollText[RNG.Next(DiceRollText.Length)] + " {0}.", string.Join(", ", Rolls.Select(x => x))));
                return;
            }

            // Nope, no idea what we're rolling.
            SayInChannel(CantDoThat);
        }