public Wheel(WheelPattern pattern, int index, GameObject wheel)
        {
            Pattern = pattern;
            Index   = index;
            myWheel = wheel;

            UpdateLabel();
        }
    private Wheel GetBonusWheel()
    {
        int u      = 0;
        var serial = bombInfo.GetSerialNumber();

        foreach (char c in serial)
        {
            if ("13579".Contains(c.ToString()))
            {
                u++;
            }
            else if ("AEIOU".Contains(c.ToString()))
            {
                u += 2;
            }
        }

        int w    = bombInfo.GetBatteryCount();
        var inds = bombInfo.GetOnIndicators();

        foreach (var _ in inds)
        {
            w--;
        }

        int uIndex, wIndex;

        if (u == 1 || u == 3)
        {
            uIndex = 0;
        }
        else if (u == 2 || u == 4 || u == 5)
        {
            uIndex = 1;
        }
        else
        {
            uIndex = 2;
        }
        if (w <= 0)
        {
            wIndex = 0;
        }
        else if (w == 1 || w == 2)
        {
            wIndex = 1;
        }
        else if (w == 3)
        {
            wIndex = 2;
        }
        else
        {
            wIndex = 3;
        }

        // Get the wheel
        WheelPattern pattern = BONUS_WHEELS[wIndex, uIndex];         // No mating

        // Spinny amount
        int spin = bombInfo.GetStrikes() - bombInfo.GetSolvedModuleNames().Count;

        // Wheelio
        return(new Wheel(pattern, spin, null));
    }
    // Use this for initialization
    void Start()
    {
        bombInfo = GetComponent <KMBombInfo>();
        wheels   = new Wheel[wheelBodies.Length];

        var sb = new StringBuilder();

        // Generate the wheels
        var bonusPattern            = GetBonusWheel().Pattern;
        var possibleSolution        = false;
        var patterns                = new WheelPattern[wheelBodies.Length + 1];
        var oops_help_infinite_loop = false;

        do
        {
            Debug.Log("Making the wheel patterns...");
            for (int c = 0; c < wheelBodies.Length; c++)
            {
                var          premadeWheelIdx = Random.Range(0, POSSIBLE_WHEELS.Length);
                WheelPattern pattern         = POSSIBLE_WHEELS[premadeWheelIdx];
                patterns[c] = pattern;
            }
            patterns[patterns.Length - 1] = bonusPattern;
            possibleSolution = TestIfWheelComboIsPossible(patterns);
        } while (!possibleSolution && !oops_help_infinite_loop);
        // Nice, now make them into real wheels
        for (int c = 0; c < wheelBodies.Length; c++)
        {
            Wheel wheel = new Wheel(patterns[c], Random.Range(0, patterns[c].Size), wheelBodies[c]);

            // Make the buttons spin the wheel
            int saveIndex = c;             // Save the value of c for the closure
            upButtons[c].OnInteract += delegate() {
                PressSpinnyButton(saveIndex, true);
                return(false);                // don't bubble down to children
            };
            downButtons[c].OnInteract += delegate() {
                PressSpinnyButton(saveIndex, false);
                return(false);
            };

            wheels[c] = wheel;

            sb.Append("Wheel #"); sb.Append(c); sb.Append(" : "); sb.Append(wheel.ToString()); sb.Append('\n');
        }

        // Make the submit button do a thing
        submitButton.OnInteract += delegate() {
            GetComponent <KMAudio>().PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.ButtonPress, transform);
            GetComponent <KMSelectable>().AddInteractionPunch();
            if (moduleSolved)
            {
                return(false);                          // done
            }
            var testTheseWheels = new Wheel[wheels.Length + 1];
            wheels.CopyTo(testTheseWheels, 0);
            testTheseWheels[wheels.Length] = GetBonusWheel();
            var _sb = new StringBuilder();
            foreach (Wheel w in testTheseWheels)
            {
                _sb.Append(w.ToString());
                _sb.Append('\n');
            }
            Debug.Log(_sb.ToString());
            var success = TestWheelCombo(testTheseWheels);
            if (success)
            {
                GetComponent <KMBombModule>().HandlePass();                // yay
            }
            else
            {
                GetComponent <KMBombModule>().HandleStrike();                // boo
            }
            return(false);
        };

        // Debug info!
        Debug.Log("Thread the Needle:\n" + sb.ToString());

        GetComponent <KMBombModule>().OnActivate += () => isActive = true;
    }
    // Use this for initialization
    void Start()
    {
        moduleId = moduleIdCounter++;
        bombInfo = GetComponent <KMBombInfo>();
        wheels   = new Wheel[wheelBodies.Length];

        var sb = new StringBuilder();

        // Generate the wheels
        var bonusPattern            = GetBonusWheel().Pattern;
        var possibleSolution        = false;
        var patterns                = new WheelPattern[wheelBodies.Length + 1];
        var oops_help_infinite_loop = false;

        do
        {
            Debug.LogFormat("<Thread the Needle #{0}> Generating the wheel patterns...", moduleId);
            for (int c = 0; c < wheelBodies.Length; c++)
            {
                var          premadeWheelIdx = Random.Range(0, POSSIBLE_WHEELS.Length);
                WheelPattern pattern         = POSSIBLE_WHEELS[premadeWheelIdx];
                patterns[c] = pattern;
            }
            patterns[patterns.Length - 1] = bonusPattern;
            possibleSolution = TestIfWheelComboIsPossible(patterns);
        } while (!possibleSolution && !oops_help_infinite_loop);
        Debug.LogFormat("<Thread the Needle #{0}> Wheel patterns generated!", moduleId);
        // Nice, now make them into real wheels
        for (int c = 0; c < wheelBodies.Length; c++)
        {
            Wheel wheel = new Wheel(patterns[c], Random.Range(0, patterns[c].Size), wheelBodies[c]);

            // Make the buttons spin the wheel
            int saveIndex = c;             // Save the value of c for the closure
            upButtons[c].OnInteract += delegate() {
                PressSpinnyButton(saveIndex, true);
                return(false);                // don't bubble down to children
            };
            downButtons[c].OnInteract += delegate() {
                PressSpinnyButton(saveIndex, false);
                return(false);
            };

            wheels[c] = wheel;

            sb.Append("Wheel #"); sb.Append(c + 1); sb.Append(": "); sb.Append(wheel.ToString()); sb.Append('\n');
        }
        Wheel bonus = GetBonusWheel();

        sb.Append("Wheel #6 (Bonus): "); sb.Append(bonus.ToString());

        // Make the submit button do a thing
        submitButton.OnInteract += delegate() {
            GetComponent <KMAudio>().PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.ButtonPress, submitButton.transform);
            submitButton.AddInteractionPunch();
            if (moduleSolved || !isActive)
            {
                return(false);                                       // done
            }
            var testTheseWheels = new Wheel[wheels.Length + 1];
            wheels.CopyTo(testTheseWheels, 0);
            testTheseWheels[wheels.Length] = GetBonusWheel();
            var _sb = new StringBuilder();
            int ct  = 0;
            foreach (Wheel w in testTheseWheels)
            {
                _sb.Append("Wheel #");
                _sb.Append(ct + 1);
                if (ct == 5)
                {
                    _sb.Append(" (Bonus)");
                }
                _sb.Append(": ");
                _sb.Append(w.ToString());
                _sb.Append('\n');
                ct++;
            }
            Debug.LogFormat("[Thread the Needle #{0}] Submitted Wheels ({1} strike{2}, {3} solve{4})", moduleId, bombInfo.GetStrikes(), bombInfo.GetStrikes() != 1 ? "s" : "", bombInfo.GetSolvedModuleNames().Count, bombInfo.GetSolvedModuleNames().Count != 1 ? "s" : "");
            for (int i = 0; i < testTheseWheels.Length; i++)
            {
                Debug.LogFormat("[Thread the Needle #{0}] {1}", moduleId, _sb.ToString().Split('\n')[i]);
            }
            var success = TestWheelCombo(testTheseWheels, true);
            if (success)
            {
                moduleSolved = true;
                GetComponent <KMBombModule>().HandlePass(); // yay
            }
            else
            {
                GetComponent <KMBombModule>().HandleStrike();                // boo
            }
            return(false);
        };

        // Debug info!
        Debug.LogFormat("[Thread the Needle #{0}] Generated Wheels", moduleId);
        for (int i = 0; i < wheelBodies.Length + 1; i++)
        {
            Debug.LogFormat("[Thread the Needle #{0}] {1}", moduleId, sb.ToString().Split('\n')[i]);
        }

        GetComponent <KMBombModule>().OnActivate += () => isActive = true;
    }