/// <summary>
        /// One of the AI's secondary logic algorithms. This one infers which characters in which spots
        /// might be responsible for a bull, by comparing similar guesses.
        /// </summary>
        /// <returns>A list of AISpots that most likely have bulls.</returns>
        private List <AISpot> AIinferredBulls()
        {
            // The AI needs to be able to look at the board, look at which spots have bulls, and then try to
            // deduce which spots they have in common that are probably responsible for those bulls.
            // Then, look at my list of candidates, and figure out which of those contain these spots in their proper positions.
            List <string> pastGuessesWith2Bulls = new List <string>();
            List <AISpot> unfilteredBullSpots   = new List <AISpot>();
            List <AISpot> inferredBullSpots     = new List <AISpot>();

            // Loop through the player's list of results labels.
            for (int i = 0; i < this.gameControl.ActivePlayer.ListOfResults.Count(); i++)
            {
                // If there are are more than two bulls on this label...
                // Look at the row next to this label. What's the corresponding guess in the player's guess list?
                // Add this guess to the new list.
                if (Regex.Matches(this.gameControl.ActivePlayer.ListOfResults[i].Text, "🐂").Count > 1)
                {
                    pastGuessesWith2Bulls.Add(this.gameControl.ActivePlayer.Guesses[i]);
                }
            }

            // If there are at least two guesses with at least two bulls, compare each guess to find similarities.
            if (pastGuessesWith2Bulls.Count() > 1)
            {
                Console.WriteLine("Found " + pastGuessesWith2Bulls.Count() + " past guesses with 2 bulls.");
                // For each member of this list...
                for (int i = 0; i < pastGuessesWith2Bulls.Count(); i++)
                {
                    // Compare it to all other members of this list...
                    for (int j = 0; j < pastGuessesWith2Bulls.Count(); j++)
                    {
                        // And see if they have any chars in common.
                        for (int k = 0; k < this.gameControl.CodeLength; k++)
                        {
                            if (pastGuessesWith2Bulls[i][k] == pastGuessesWith2Bulls[j][k])
                            {
                                // Note: It's okay (though not ideal) to include self-matches with those that match others in here.
                                AISpot bullSpot = new AISpot();
                                bullSpot.Name  = k.ToString();
                                bullSpot.Value = pastGuessesWith2Bulls[i][k].ToString();

                                // Add them to the master list that will later be returned from this method.
                                unfilteredBullSpots.Add(bullSpot);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("Found " + unfilteredBullSpots.Count + " unfiltered bull spots.");

            foreach (AISpot i in unfilteredBullSpots)
            {
                int matchCounter = 0;
                foreach (AISpot j in unfilteredBullSpots)
                {
                    if (i.Name == j.Name && i.Value == j.Value)
                    {
                        matchCounter++;
                        if (matchCounter > 1)
                        {
                            // Console.WriteLine("Found a self match?");
                            inferredBullSpots.Add(i);
                        }
                    }
                }
            }
            Console.WriteLine("Permutations with inferred bull matches: " + inferredBullSpots.Count);
            return(inferredBullSpots);
        }
        /// <summary>
        /// One of the AI's secondary logic algorithms. This one deduces which characters in which spots
        /// are not responsible for any bulls, by comparison, which can then be ruled out from future
        /// consideration.
        /// </summary>
        /// <returns>A list of AISpots that do not have bulls.</returns>
        private List <AISpot> AIdeducedNoBulls()
        {
            /*
             * Just as we can infer the position of where a bull is located, we can rule out positions where
             * we are sure a bull is not. Sometimes the main AI is satisfied with cow after cow instead of
             * trying to get more bulls. This should curb that tendency.
             */

            List <string> pastGuessesWith2Cows = new List <string>();
            List <AISpot> preFilteredCows      = new List <AISpot>();
            List <AISpot> deducedNoBullSpots   = new List <AISpot>();

            // Loop through the player's list of results labels.
            for (int i = 0; i < this.gameControl.ActivePlayer.ListOfResults.Count(); i++)
            {
                if (Regex.Matches(this.gameControl.ActivePlayer.ListOfResults[i].Text, "🐄").Count > 1 &&
                    Regex.Matches(this.gameControl.ActivePlayer.ListOfResults[i].Text, "🐂").Count == 0)
                {
                    pastGuessesWith2Cows.Add(this.gameControl.ActivePlayer.Guesses[i]);
                }
            }

            List <AISpot> unfilteredCowSpots = new List <AISpot>();

            // If there are at least two guesses with at least two cows, compare each guess to find similarities.
            if (pastGuessesWith2Cows.Count() > 1)
            {
                Console.WriteLine("Found " + pastGuessesWith2Cows.Count + " past guesses with two cows and no bulls.");

                // For each member of this list...
                for (int i = 0; i < pastGuessesWith2Cows.Count(); i++)
                {
                    // Compare it to all other members of this list...
                    for (int j = 0; j < pastGuessesWith2Cows.Count(); j++)
                    {
                        // And see if they have any chars in common.
                        for (int k = 0; k < this.gameControl.CodeLength; k++)
                        {
                            if (pastGuessesWith2Cows[i][k] == pastGuessesWith2Cows[j][k])
                            {
                                AISpot noBullSpot = new AISpot();
                                noBullSpot.Name  = k.ToString();
                                noBullSpot.Value = pastGuessesWith2Cows[i][k].ToString();

                                unfilteredCowSpots.Add(noBullSpot);
                            }
                        }
                    }
                }
            }

            Console.WriteLine("Found " + unfilteredCowSpots.Count + " unfilted cow spots.");

            foreach (AISpot i in unfilteredCowSpots)
            {
                int matchCounter = 0;
                foreach (AISpot j in unfilteredCowSpots)
                {
                    if (i.Name == j.Name && i.Value == j.Value)
                    {
                        matchCounter++;
                        if (matchCounter > 1)
                        {
                            deducedNoBullSpots.Add(i);
                        }
                    }
                }
            }

            Console.WriteLine("Permutations that match deduction of where bulls are not: " + deducedNoBullSpots.Count());
            return(deducedNoBullSpots);
        }
        private async void FindPossibleBullsOrCows()
        {
            int myBullsCount = 0;
            int guessCounter = 0;

            // Loop through every previous guess.
            foreach (string guess in this.gameControl.ActivePlayer.Guesses)
            {
                if (this.gameControl.ActivePlayer.MyInputList.Count() > 0)
                {
                    await this.UpdateBotMouth("Considering " + this.gameControl.ActivePlayer.MyInputList.Count() + " possibilities.");

                    List <AISpot> permSpots  = new List <AISpot>();
                    List <AISpot> guessSpots = new List <AISpot>();

                    // For each guess, loop through every permutation in MyInputList.
                    foreach (string perm in this.gameControl.ActivePlayer.MyInputList)
                    {
                        // Compare the permutation to the guess.
                        // Turn each of the two strings into a list of AISpots.

                        for (int i = 0; i < this.gameControl.CodeLength; i++)
                        {
                            AISpot tempPermSpot = new AISpot();
                            tempPermSpot.Name  = "a" + i;
                            tempPermSpot.Value = perm.Substring(i, 1);
                            permSpots.Add(tempPermSpot);
                        }

                        for (int i = 0; i < this.gameControl.CodeLength; i++)
                        {
                            AISpot tempGuessSpot = new AISpot();
                            tempGuessSpot.Name  = "b" + i;
                            tempGuessSpot.Value = guess.Substring(i, 1);
                            guessSpots.Add(tempGuessSpot);
                        }

                        myBullsCount = 0;

                        // Compare spots. A match means this character might be responsible for either a bull or a cow.
                        for (int k = 0; k < this.gameControl.CodeLength; k++)
                        {
                            if (guessSpots[k].Value == permSpots[k].Value)
                            {
                                myBullsCount++;
                                guessSpots[k].Value = string.Empty;
                                permSpots[k].Value  = string.Empty;
                            }
                        }

                        // See if this permutation gets the same number of bulls as what we just had.
                        // If so, add it to the new OUTPUT list.
                        if (myBullsCount == Regex.Matches(this.gameControl.ActivePlayer.ListOfResults[guessCounter].Text, "🐂").Count)
                        {
                            this.gameControl.ActivePlayer.MyOutputList.Add(perm);
                        }
                        permSpots.Clear();
                        guessSpots.Clear();
                    } // end cycling through input list.
                }

                if (this.gameControl.ActivePlayer.MyOutputList.Count() > 0)
                {
                    // Assuming MyOutputList has multiple guess candidates inside, clear out the inputList
                    // and put the output list into it. This way, next time it analyzes the previous turn
                    // it will be re-sorting a previously sorted list to further eliminate possiblities.
                    this.gameControl.ActivePlayer.MyInputList.Clear();
                    foreach (string myValue in this.gameControl.ActivePlayer.MyOutputList)
                    {
                        this.gameControl.ActivePlayer.MyInputList.Add(myValue);
                    }

                    this.gameControl.ActivePlayer.MyOutputList.Clear();
                }
                else
                {
                    MessageBox.Show("Congratulations! BessieBot's brain is broken in such a way \n that should not even be possible. \n");
                }

                guessCounter++;
            }
        }