예제 #1
0
        public List <QuestionPackData> CreateAllQuestionPacks()
        {
            previousPacksIDs_letters.Clear();
            previousPacksIDs_words.Clear();
            var packs = new List <QuestionPackData>();

            // @note: all packs are created together in this builder, as a speed-up
            // Choose all letters we want to focus on
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, getMaxData: true,
                                                           useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_letters);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var availableLetters = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetAllLetters(parameters.letterFilters), selectionParams1);

            // Keep a list of letters we tried
            var availableLettersWithForms = new HashSet <LetterData>(new StrictLetterDataComparer(LetterEqualityStrictness.WithActualForm));

            // Add forms too (cannot be found in the SelectData call)
            availableLettersWithForms.UnionWith(vocabularyHelper.ExtractLettersWithForms(availableLetters));

            for (int pack_i = 0; pack_i < nPacks; pack_i++)
            {
                packs.Add(CreateSingleQuestionPackData(availableLettersWithForms));
            }
            return(packs);
        }
예제 #2
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            // Get a question phrase at random
            int nToUse           = 1;
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, nToUse, useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var usablePhrases = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetPhrasesByCategory(Database.PhraseDataCategory.Question, parameters.wordFilters, parameters.phraseFilters), selectionParams1);
            var question = usablePhrases[0];

            // Get the linked reply phrase
            var reply = vocabularyHelper.GetLinkedPhraseOf(question);

            var correctAnswers = new List <Database.PhraseData>();

            correctAnswers.Add(reply);

            // Get random wrong phrases
            var selectionParams2 = new SelectionParameters(parameters.correctSeverity, nWrong,
                                                           useJourney: parameters.useJourneyForWrong,
                                                           packListHistory: PackListHistory.NoFilter,
                                                           journeyFilter: SelectionParameters.JourneyFilter.CurrentJourney);

            selectionParams2.AssignJourney(parameters.insideJourney);

            var wrongPhrases = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetPhrasesNotIn(parameters.wordFilters, parameters.phraseFilters, question, reply), selectionParams2);

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nQuestion: " + question;
                debugString += "\nCorrect Answers: " + correctAnswers.Count;
                foreach (var l in correctAnswers)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Answers: " + wrongPhrases.Count;
                foreach (var l in wrongPhrases)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctAnswers, wrongPhrases));
        }
예제 #3
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, nCorrect,
                                                           useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var correctLetters = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetAllLetters(parameters.letterFilters), selectionParams1);

            var selectionParams2 = new SelectionParameters(parameters.wrongSeverity, nWrong,
                                                           useJourney: parameters.useJourneyForWrong,
                                                           packListHistory: PackListHistory.NoFilter);

            selectionParams2.AssignJourney(parameters.insideJourney);
            var wrongLetters = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetLettersNotIn(LetterEqualityStrictness.Letter, parameters.letterFilters, correctLetters.ToArray()),
                selectionParams2
                );

            var question = firstCorrectIsQuestion ? correctLetters[0] : null;

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nCorrect Letters: " + correctLetters.Count;
                foreach (var l in correctLetters)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Letters: " + wrongLetters.Count;
                foreach (var l in wrongLetters)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctLetters, wrongLetters));
        }
예제 #4
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, nCorrect,
                                                           useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var correctWords = teacher.VocabularyAi.SelectData(() => words_cache, selectionParams1);

            wrongWords_cache.Clear();
            wrongWords_cache.AddRange(vocabularyHelper.GetWordsNotInOptimized(parameters.wordFilters, correctWords));

            var selectionParams2 = new SelectionParameters(parameters.wrongSeverity, nWrong, useJourney: parameters.useJourneyForWrong, packListHistory: PackListHistory.NoFilter);

            selectionParams2.AssignJourney(parameters.insideJourney);
            var wrongWords = teacher.VocabularyAi.SelectData(() => wrongWords_cache, selectionParams2);

            var question = firstCorrectIsQuestion ? correctWords[0] : null;

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nCorrect Words: " + correctWords.Count;
                foreach (var l in correctWords)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Words: " + wrongWords.Count;
                foreach (var l in wrongWords)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctWords, wrongWords));
        }
예제 #5
0
        private QuestionPackData CreateSingleQuestionPackData(WordDataCategory dataCategory)
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            // Ordered words
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, getMaxData: true,
                                                           useJourney: parameters.useJourneyForCorrect);

            selectionParams1.AssignJourney(parameters.insideJourney);
            parameters.wordFilters.allowedCategories = new[] { dataCategory };
            var words = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetAllWords(parameters.wordFilters),
                selectionParams1
                );

            // sort by id
            words.Sort((x, y) => int.Parse(x.SortValue) - int.Parse(y.SortValue));
            if (skipWordZero)
            {
                words.RemoveAt(0);
            }

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "Words: " + words.Count;
                foreach (var w in words)
                {
                    debugString += " " + w;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            if (maxAnswers > 0)
            {
                words = words.GetRange(0, Mathf.Min(words.Count, maxAnswers));
            }

            return(QuestionPackData.CreateFromCorrect(null, words));
        }
예제 #6
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            parameters.wordFilters.allowedCategories = null; // Reset forced category

            // Get a phrase
            int nToUse           = 1;
            var selectionParams1 =
                new SelectionParameters(parameters.correctSeverity, nToUse, useJourney: parameters.useJourneyForCorrect,
                                        packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var usablePhrases = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetAllPhrases(
                    parameters.wordFilters,
                    parameters.phraseFilters), selectionParams1);
            var question = usablePhrases.RandomSelectOne();

            // Get words related to the phrase
            var             correctWords = new List <WordData>();
            List <WordData> relatedWords = new List <WordData>();

            var phraseWords = vocabularyHelper.GetWordsInPhrase(question, parameters.wordFilters);

            relatedWords.AddRange(phraseWords);

            if (usePhraseAnswersIfFound && question.Answers.Length > 0)
            {
                var answerWords = vocabularyHelper.GetAnswersToPhrase(question, parameters.wordFilters);
                correctWords.AddRange(answerWords);
                relatedWords.AddRange(answerWords);
            }
            else
            {
                correctWords.AddRange(phraseWords);
            }

            // Choose the word/s we want to use
            if (!useAllCorrectWords)
            {
                correctWords = correctWords.RandomSelect(nCorrect);
            }

            // Get wrong words from the same category of the correct one
            parameters.wordFilters.allowedCategories = new[] { correctWords[0].Category };
            var selectionParams2 =
                new SelectionParameters(parameters.correctSeverity, nWrong, useJourney: parameters.useJourneyForCorrect,
                                        packListHistory: PackListHistory.NoFilter,
                                        journeyFilter: parameters.JourneyFilter);
            var wrongWords = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetWordsNotIn(parameters.wordFilters, relatedWords.ToArray()),
                selectionParams2
                );

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nQuestion: " + question;
                debugString += "\nCorrect Answers: " + correctWords.Count;
                foreach (var l in correctWords)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Answers: " + wrongWords.Count;
                foreach (var l in wrongWords)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctWords, wrongWords));
        }
예제 #7
0
        private QuestionPackData CreateSingleQuestionPackData(int inRoundPackIndex, HashSet <LetterData> availableLettersWithForms)
        {
            var teacher = AppManager.I.Teacher;

            /*bool useJourneyForLetters = parameters.useJourneyForCorrect;
             * // @note: we also force the journey if the packs must be used together, as the data filters for journey clash with the new filter
             * if (packsUsedTogether)
             * {
             *  useJourneyForLetters = false;
             * }*/

            int SAFE_COUNT = 0;

            while (true)
            {
                var commonLetter = availableLettersWithForms.ToList().RandomSelectOne();

                var correctLetters = new List <LetterData>();
                correctLetters.Add(commonLetter);
                availableLettersWithForms.Remove(commonLetter);
                currentRound_letters.Add(commonLetter);
                //Debug.Log(availableLettersWithForms.ToDebugStringNewline());

                // Find words with that letter
                // Check if it has enough words
                var selectionParams2 =
                    new SelectionParameters(SelectionSeverity.AllRequired, nCorrect,
                                            useJourney: parameters.useJourneyForCorrect,
                                            packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_words);
                selectionParams2.AssignJourney(parameters.insideJourney);
                List <WordData> wordsWithCommonLetter = null;
                try {
                    wordsWithCommonLetter = teacher.VocabularyAi.SelectData(
                        () => FindWordsWithCommonLetter(commonLetter), selectionParams2);
                } catch (Exception) {
                    //Debug.LogWarning(e);
                    SAFE_COUNT++;
                    if (SAFE_COUNT == 100)
                    {
                        throw new Exception("Could not find enough data for WordsWithLetter");
                    }
                    continue;
                }
                var correctWords = wordsWithCommonLetter;
                currentRound_words.AddRange(correctWords);

                // Get words without the letter (only for the first pack of a round)
                var wrongWords = new List <WordData>();
                if (inRoundPackIndex == 0)
                {
                    var selectionParams3 =
                        new SelectionParameters(parameters.wrongSeverity, nWrong,
                                                useJourney: parameters.useJourneyForWrong,
                                                packListHistory: PackListHistory.NoFilter,
                                                journeyFilter: parameters.JourneyFilter);
                    selectionParams3.AssignJourney(parameters.insideJourney);

                    wrongWords = teacher.VocabularyAi.SelectData(
                        () => FindWrongWords(correctWords), selectionParams3);
                    currentRound_words.AddRange(wrongWords);
                }


                /*
                 * // Get a letter
                 * var usableLetters = teacher.VocabularyAi.SelectData(
                 * () => FindLettersThatAppearInWords(atLeastNWords: nCorrect),
                 * new SelectionParameters(parameters.correctSeverity, 1, useJourney: useJourneyForLetters,
                 *      packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_letters));
                 * var commonLetter = usableLetters[0];
                 * currentRound_letters.Add(commonLetter);
                 */
                /*
                 *  // Get words with the letter
                 *  // (but without the previous letters)
                 *  var correctWords = teacher.VocabularyAi.SelectData(
                 *      () => FindWordsWithCommonLetter(commonLetter),
                 *      new SelectionParameters(parameters.correctSeverity, nCorrect,
                 *          useJourney: parameters.useJourneyForCorrect,
                 *          packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_words));
                 *  currentRound_words.AddRange(correctWords);
                 *
                 *  // Get words without the letter (only for the first pack of a round)
                 *  var wrongWords = new List<WordData>();
                 *  if (inRoundPackIndex == 0)
                 *  {
                 *      wrongWords = teacher.VocabularyAi.SelectData(
                 *          () => FindWrongWords(correctWords),
                 *          new SelectionParameters(parameters.wrongSeverity, nWrong,
                 *              useJourney: parameters.useJourneyForWrong,
                 *              packListHistory: PackListHistory.NoFilter,
                 *              journeyFilter: SelectionParameters.JourneyFilter.CurrentJourney));
                 *      currentRound_words.AddRange(wrongWords);
                 *  }
                 */
                var pack = QuestionPackData.Create(commonLetter, correctWords, wrongWords);

                if (ConfigAI.VerboseQuestionPacks)
                {
                    string debugString = "--------- TEACHER: question pack result ---------";
                    debugString += "\nQuestion: " + commonLetter;
                    debugString += "\nCorrect Answers: " + correctWords.Count;
                    foreach (var l in correctWords)
                    {
                        debugString += " " + l;
                    }
                    debugString += "\nWrong Answers: " + wrongWords.Count;
                    foreach (var l in wrongWords)
                    {
                        debugString += " " + l;
                    }
                    ConfigAI.AppendToTeacherReport(debugString);
                }

                return(pack);
            }
        }
예제 #8
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            //Debug.Log(FindLettersThatAppearInWords(maxWordLength: maximumWordLength).ToDebugStringNewline());

            // First, choose a letter (base only, due to filters)
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, 1, useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_letters);

            selectionParams1.AssignJourney(parameters.insideJourney);

            var eligibleLetters = teacher.VocabularyAi.SelectData(() => FindLettersThatAppearInWords(maxWordLength: maximumWordLength), selectionParams1);
            //Debug.Log(eligibleLetters.ToDebugStringNewline());

            // Choose one letter randomly from the eligible ones
            var chosenLetter = eligibleLetters.RandomSelectOne();
            //Debug.Log("Chosen: " + chosenLetter);

            // Find a word with the letter (strict)
            var selectionParams2 = new SelectionParameters(parameters.correctSeverity, 1, useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_words);

            selectionParams2.AssignJourney(parameters.insideJourney);
            var usableWords = teacher.VocabularyAi.SelectData(
                () => FindWordsWithLetterStrict(chosenLetter, maximumWordLength), selectionParams2);

            var question = usableWords[0];
            // Get the correct form inside the word
            //Debug.Log("Word is: " + question.ToString());
            //Debug.Log("Letters: " + vocabularyHelper.GetLettersInWord(question).ToDebugString());
            //Debug.Log("Letters correct: " + vocabularyHelper.GetLettersInWord(question, removeAccents).Where(l => l.IsSameLetterAs(chosenLetter, LetterEqualityStrictness.LetterBase)).ToDebugString());
            var chosenLetterWithForm = vocabularyHelper.GetLettersInWord(question, keepBasesOnly).Where(l => l.IsSameLetterAs(chosenLetter, LetterEqualityStrictness.LetterBase)).ToList().RandomSelectOne();
            //chosenLetterWithForm = vocabularyHelper.ExtractLettersWithForms(chosenLetterWithForm);
            //Debug.Log("Correct form: " + chosenLetterWithForm + " form is " + chosenLetterWithForm.Form);

            // Place the correct alteration in the correct list
            var correctAnswers = new List <LetterData>();

            correctAnswers.Add(chosenLetterWithForm);

            // Place some alterations in the wrong list
            List <LetterData> baseLetters;

            if (letterAlterationFilters.differentBaseLetters)
            {
                baseLetters = AppManager.I.VocabularyHelper.GetAllLetters(parameters.letterFilters);
            }
            else
            {
                baseLetters = eligibleLetters;
            }

            // Filter out unknown letters
            var filteredBaseLetters = teacher.VocabularyAi.SelectData(
                () => baseLetters,
                new SelectionParameters(parameters.wrongSeverity, getMaxData: true, useJourney: true,
                                        packListHistory: PackListHistory.NoFilter)
                );
            //Debug.LogWarning("Filtered bases: " + filteredBaseLetters.ToDebugStringNewline());

            var alterationsPool = AppManager.I.VocabularyHelper.GetAllLetterAlterations(filteredBaseLetters, letterAlterationFilters);
            var wrongAnswers    = new List <LetterData>();

            //Debug.Log("N Alterations before remove correct: " + alterationsPool.Count + " " + alterationsPool.ToDebugString());

            // Remove the correct alteration (making sure to get the actual form)
            for (int i = 0; i < alterationsPool.Count; i++)
            {
                if (alterationsPool[i].IsSameLetterAs(chosenLetterWithForm, LetterEqualityStrictness.WithVisualForm))
                {
                    alterationsPool.RemoveAt(i);
                }
            }

            //Debug.Log("N Alterations after remove correct: " + alterationsPool.Count + " " + alterationsPool.ToDebugString());
            wrongAnswers.AddRange(alterationsPool.RandomSelect(nWrongs));

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nQuestion: " + question;
                debugString += "\nCorrect Answers: " + correctAnswers.Count;
                foreach (var l in correctAnswers)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Answers: " + wrongAnswers.Count;
                foreach (var l in wrongAnswers)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctAnswers, wrongAnswers));
        }
예제 #9
0
        private QuestionPackData CreateSingleQuestionPackData(int inRoundPackIndex)
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            // Choose a single eligible word
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, 1, useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs_words);

            selectionParams1.AssignJourney(parameters.insideJourney);
            var usableWords = teacher.VocabularyAi.SelectData(
                () => FindEligibleWords(maxWordLength: maximumWordLength),
                selectionParams1
                );
            var wordQuestion = usableWords[0];

            currentRound_words.Add(wordQuestion);
            //UnityEngine.Debug.LogWarning("Chosen word: " + wordQuestion);

            // Get letters of that word
            var wordLetters = vocabularyHelper.GetLettersInWord(wordQuestion, removeAccents);

            //UnityEngine.Debug.LogWarning("Found letters: " + wordLetters.ToArray().ToDebugString());

            bool useJourneyForLetters = parameters.useJourneyForCorrect;

            // @note: we force journey in this case to be off so that all letters can be found
            // @note: we also force the journey if the packs must be used together, as the data filters for journey clash with the new filter
            if (useAllCorrectLetters || packsUsedTogether)
            {
                useJourneyForLetters = false;
            }

            // Get some letters (from that word)
            var selectionParams2 = new SelectionParameters(parameters.correctSeverity, nCorrect,
                                                           getMaxData: useAllCorrectLetters,
                                                           useJourney: useJourneyForLetters, filteringIds: previousPacksIDs_letters);

            selectionParams2.AssignJourney(parameters.insideJourney);
            var correctLetters = teacher.VocabularyAi.SelectData(
                () => FindCorrectLetters(wordQuestion, wordLetters), selectionParams2);

            currentRound_letters.AddRange(correctLetters);

            // Get some wrong letters (not from that word, nor other words, nor previous letters)
            // Only for the first pack of the round
            var wrongLetters = new List <LetterData>();

            if (inRoundPackIndex == 0)
            {
                wrongLetters = teacher.VocabularyAi.SelectData(
                    () => FindWrongLetters(wordQuestion, wordLetters),
                    new SelectionParameters(
                        parameters.wrongSeverity, nWrong, useJourney: parameters.useJourneyForWrong,
                        journeyFilter: SelectionParameters.JourneyFilter.CurrentJourney));
                currentRound_letters.AddRange(wrongLetters);
            }

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nQuestion: " + wordQuestion;
                debugString += "\nCorrect Answers: " + correctLetters.Count;
                foreach (var l in correctLetters)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Answers: " + wrongLetters.Count;
                foreach (var l in wrongLetters)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(wordQuestion, correctLetters, wrongLetters));
        }
예제 #10
0
        private QuestionPackData CreateSingleQuestionPackData()
        {
            var teacher          = AppManager.I.Teacher;
            var vocabularyHelper = AppManager.I.VocabularyHelper;

            // First, get all letters (only base letters, tho, due to forced letter filters)
            int nBaseLettersRequired = 1;

            if (letterAlterationFilters.differentBaseLetters)
            {
                nBaseLettersRequired = nCorrect + nWrong;
            }
            var selectionParams1 = new SelectionParameters(parameters.correctSeverity, nRequired: nBaseLettersRequired,
                                                           useJourney: parameters.useJourneyForCorrect,
                                                           packListHistory: parameters.correctChoicesHistory, filteringIds: previousPacksIDs);

            selectionParams1.AssignJourney(parameters.insideJourney);

            var chosenLetters = teacher.VocabularyAi.SelectData(
                () => vocabularyHelper.GetAllLetters(parameters.letterFilters), selectionParams1);
            var baseLetters = chosenLetters;

            // Then, find all the different variations and add them to a pool
            var letterPool = vocabularyHelper.GetAllLetterAlterations(baseLetters, letterAlterationFilters);

            // Choose randomly from that pool
            var correctAnswers = letterPool.RandomSelect(nCorrect);
            var wrongAnswers   = letterPool;

            foreach (LetterData data in correctAnswers)
            {
                wrongAnswers.Remove(data);
            }

            if (avoidWrongLettersWithSameSound)
            {
                wrongAnswers.RemoveAll(wrongLetter => correctAnswers.Any(correctLetter => correctLetter.PhonemeSound.Equals(wrongLetter.PhonemeSound)));
            }

            wrongAnswers = wrongAnswers.RandomSelect(Mathf.Min(nWrong, wrongAnswers.Count));

            var question = correctAnswers[0];

            if (ConfigAI.VerboseQuestionPacks)
            {
                string debugString = "--------- TEACHER: question pack result ---------";
                debugString += "\nQuestion: " + question;
                debugString += "\nCorrect Answers: " + correctAnswers.Count;
                foreach (var l in correctAnswers)
                {
                    debugString += " " + l;
                }
                debugString += "\nWrong Answers: " + wrongAnswers.Count;
                foreach (var l in wrongAnswers)
                {
                    debugString += " " + l;
                }
                ConfigAI.AppendToTeacherReport(debugString);
            }

            return(QuestionPackData.Create(question, correctAnswers, wrongAnswers));
        }