Beispiel #1
0
 private bool CheckRequiredNumberReached <T>(List <T> dataList, SelectionParameters selectionParams, int nAfterBuilder)
 {
     return((!selectionParams.getMaxData && dataList.Count >= selectionParams.nRequired) ||
            (selectionParams.getMaxData && dataList.Count >= nAfterBuilder));
 }
Beispiel #2
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));
        }
Beispiel #3
0
        public List <T> SelectData <T>(System.Func <List <T> > builderSelectionFunction, SelectionParameters selectionParams, bool isTest = false, bool canReturnZero = false) where T : IVocabularyData
        {
            // skip if we require 0 values
            if (selectionParams.nRequired == 0 && !selectionParams.getMaxData)
            {
                return(new List <T>());
            }

            if (ConfigAI.VerboseDataSelection)
            {
                debugString_selectData  = "";
                debugString_selectData += ConfigAI.FormatTeacherReportHeader("Data Selection: " + typeof(T).Name);
            }

            // (1) Filtering based on the builder's logic
            var dataList      = builderSelectionFunction();
            int nAfterBuilder = dataList.Count;

            if (ConfigAI.VerboseDataFiltering)
            {
                debugString_selectData += ("\n  Builder: " + dataList.Count);
            }

            // (2) Filtering based on journey
            if (selectionParams.useJourney && !ConfigAI.ForceJourneyIgnore)
            {
                switch (selectionParams.journeyFilter)
                {
                case SelectionParameters.JourneyFilter.CurrentJourney:
                    dataList = dataList.FindAll(x => currentJourneyContents.Contains(x));
                    break;

                case SelectionParameters.JourneyFilter.UpToFullCurrentStage:
                    dataList = dataList.FindAll(x => currentJourneyContents.Contains(x) || currentStageContents.Contains(x));
                    break;
                }
            }
            if (selectionParams.severity == SelectionSeverity.AllRequired)
            {
                if (!CheckRequiredNumberReached(dataList, selectionParams, nAfterBuilder))
                {
                    throw new Exception("The teacher could not find " + selectionParams.nRequired + " data instances after applying the journey logic.");
                }
            }
            if (ConfigAI.VerboseDataFiltering)
            {
                debugString_selectData += ("\n  Journey: " + dataList.Count);
            }
            //Debug.Log("Journey: " + dataList.ToDebugStringNewline());

            // (3) Filtering based on pack-list history
            switch (selectionParams.packListHistory)
            {
            case PackListHistory.NoFilter:
                // we do not care which are picked, in this case
                break;

            case PackListHistory.ForceAllDifferent:
                // filter only by those that have not been found already in this pack, if possible
                dataList = dataList.FindAll(x => !selectionParams.filteringIds.Contains(x.GetId()));
                if (!CheckRequiredNumberReached(dataList, selectionParams, nAfterBuilder))
                {
                    UnityEngine.Debug.Log(debugString_selectData);
                    throw new System.Exception("The teacher could not find " + selectionParams.nRequired + " data instances after applying the pack-history logic.");
                }
                break;

            case PackListHistory.RepeatWhenFull:
                // reset the previous pack list if needed
                var tmpDataList = dataList.FindAll(x => !selectionParams.filteringIds.Contains(x.GetId()));
                if (tmpDataList.Count < selectionParams.nRequired)
                {
                    // reset and re-pick
                    selectionParams.filteringIds.Clear();
                    dataList = dataList.FindAll(x => !selectionParams.filteringIds.Contains(x.GetId()));
                }
                else
                {
                    dataList = tmpDataList;
                }
                break;
            }
            if (ConfigAI.VerboseDataFiltering)
            {
                debugString_selectData += ("\n  History: " + dataList.Count);
            }
            //Debug.Log("History: " + dataList.ToDebugStringNewline());
            //if(selectionParams.filteringIds != null) Debug.Log("Filtered ids:: " + selectionParams.filteringIds.ToDebugStringNewline());

            // (4) Priority filtering based on current focus
            List <T> priorityFilteredList = null;

            if (!isTest && !selectionParams.getMaxData)
            {
                HashSet <T> priorityFilteredHash = new HashSet <T>();
                string      s          = ConfigAI.FormatTeacherReportHeader("Priority Filtering");
                int         nBefore    = selectionParams.nRequired;
                int         nRemaining = selectionParams.nRequired;
                AddToHashSetFilteringByContents(currentPlaySessionContents, dataList, priorityFilteredHash, ref nRemaining);

                s += "\n Required: " + nRemaining + " " + typeof(T).Name.ToString();
                s += "\n" + (nBefore - nRemaining) + " from PS";
                if (nRemaining > 0)
                {
                    nBefore = nRemaining;
                    AddToHashSetFilteringByContents(currentLearningBlockContents, dataList, priorityFilteredHash, ref nRemaining);
                    s += "\n" + (nBefore - nRemaining) + " from LB";
                }
                if (nRemaining > 0)
                {
                    nBefore = nRemaining;
                    AddToHashSetFilteringByContents(currentStageContents, dataList, priorityFilteredHash, ref nRemaining);
                    s += "\n" + (nBefore - nRemaining) + " from ST";
                }
                if (nRemaining > 0)
                {
                    nBefore = nRemaining;
                    AddToHashSetFilteringByContents(currentJourneyContents, dataList, priorityFilteredHash, ref nRemaining);
                    s += "\n" + (nBefore - nRemaining) + " from the current Journey";
                }
                // @note: when journey filtering is disabled, we may still have to get some data from the rest of the journey
                if (nRemaining > 0 && !selectionParams.useJourney)
                {
                    nBefore = nRemaining;
                    AddToHashSetFilteringByContents(progressionContents.AllContents, dataList, priorityFilteredHash, ref nRemaining);
                    s += "\n" + (nBefore - nRemaining) + " from the complete contents.";
                }

                if (ConfigAI.VerboseDataFiltering)
                {
                    ConfigAI.AppendToTeacherReport(s);
                }
                priorityFilteredList = new List <T>();
                priorityFilteredList.AddRange(priorityFilteredHash);
                if (ConfigAI.VerboseDataFiltering)
                {
                    debugString_selectData += ("\n  Priority: " + priorityFilteredList.Count);
                }
            }
            else
            {
                priorityFilteredList = dataList;
            }
            //Debug.Log("Priority: " + priorityFilteredList.ToDebugStringNewline());

            // (5) Weighted selection on the remaining number
            List <T> selectedList = null;

            if (selectionParams.getMaxData)
            {
                selectedList = priorityFilteredList;
            }
            else
            {
                selectedList = WeightedDataSelect(priorityFilteredList, selectionParams.nRequired, selectionParams.severity);
            }
            if (ConfigAI.VerboseDataFiltering)
            {
                debugString_selectData += ("\n  Selection: " + selectedList.Count);
            }
            //if (selectedList.Count > 0) Debug.Log("Selection: " + selectedList.ToDebugStringNewline());

            if (ConfigAI.VerboseDataFiltering && !isTest)
            {
                foreach (var selectedEntry in selectedList)
                {
                    debugString_selectData += "   [" + selectedEntry + "]";
                }
                ConfigAI.AppendToTeacherReport(debugString_selectData);
            }

            if (selectedList.Count == 0)
            {
                if (canReturnZero)
                {
                    return(selectedList);
                }

                throw new System.Exception("The teacher could not find any data with the current filters. The game does not seem to be playable at the selected play session."
                                           + "\n" + debugString_selectData);
            }

            // Update the filtering ids
            if (selectionParams.packListHistory != PackListHistory.NoFilter)
            {
                selectionParams.filteringIds.AddRange(selectedList.ConvertAll <string>(x => x.GetId()).ToArray());
            }

            // Reorder the selected data based on intrinsic difficulty
            if (selectionParams.sortDataByDifficulty)
            {
                selectedList.Sort((x, y) => (int)(x.GetIntrinsicDifficulty() - y.GetIntrinsicDifficulty()));
            }

            return(selectedList);
        }
Beispiel #4
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));
        }