Exemplo n.º 1
0
        public async Task EnterAsync()
        {
            if (!await _usersWordsService.HasWordsFor(Chat.User))
            {
                await Chat.SendMessageAsync(Chat.Texts.NeedToAddMoreWordsBeforeLearning);

                return;
            }

            var startupScoreUpdate = _usersWordsService.UpdateCurrentScoreForRandomWords(Chat.User, _examSettings.MaxLearningWordsCountInOneExam * 2);
            var typing             = Chat.SendTyping();

            var c = Rand.RandomIn(_examSettings.MinLearningWordsCountInOneExam,
                                  _examSettings.MaxLearningWordsCountInOneExam);
            await startupScoreUpdate;
            await typing;
            var   learningWords
                = await _usersWordsService.GetWordsForLearningWithPhrasesAsync(Chat.User, c, 3);

            var learningWordsCount = learningWords.Length;

            if (learningWords.Average(w => w.AbsoluteScore) <= WordLeaningGlobalSettings.FamiliarWordMinScore)
            {
                var sb = new StringBuilder($"{Emojis.Learning} " + Chat.Texts.LearningCarefullyStudyTheListMarkdown + "\r\n\r\n```\r\n");

                foreach (var pairModel in learningWords.Shuffle())
                {
                    sb.AppendLine($"{pairModel.Word.EscapeForMarkdown()}\t\t:{pairModel.AllTranslationsAsSingleString.EscapeForMarkdown()}");
                }
                sb.AppendLine($"\r\n```\r\n\\.\\.\\. {Chat.Texts.thenClickStartMarkdown}");
                await Chat.SendMarkdownMessageAsync(sb.ToString(), new[] { new[] { new InlineKeyboardButton
                                                                                   {
                                                                                       CallbackData = "/startExamination",
                                                                                       Text         = Chat.Texts.StartButton
                                                                                   }, new InlineKeyboardButton
                                                                                   {
                                                                                       CallbackData = BotCommands.Start,
                                                                                       Text         = Chat.Texts.CancelButton,
                                                                                   } } });

                var userInput = await Chat.WaitInlineKeyboardInput();

                if (userInput != "/startExamination")
                {
                    return;
                }
            }
            var started = DateTime.Now;

            var learningAndAdvancedWords
                = (await _usersWordsService.AppendAdvancedWordsToExamList(
                       Chat.User, learningWords, _examSettings));

            var distinctLearningWords = learningAndAdvancedWords.Distinct().ToArray();

            var originWordsScore = new Dictionary <string, double>();

            foreach (var word in distinctLearningWords)
            {
                if (!originWordsScore.ContainsKey(word.Word))
                {
                    originWordsScore.Add(word.Word, word.AbsoluteScore);
                }
            }

            var gamingScoreBefore = Chat.User.GamingScore;

            var            questionsCount     = 0;
            var            questionsPassed    = 0;
            var            wordQuestionNumber = 0;
            QuestionResult lastExamResult     = null;

            foreach (var word in learningAndAdvancedWords)
            {
                var allLearningWordsWereShowedAtLeastOneTime = wordQuestionNumber < learningWordsCount;
                var question =
                    QuestionSelector.Singletone.GetNextQuestionFor(allLearningWordsWereShowedAtLeastOneTime, word);
                wordQuestionNumber++;

                var learnList = learningWords;

                if (!learningWords.Contains(word))
                {
                    learnList = learningWords.Append(word).ToArray();
                }

                if (wordQuestionNumber > 1 && question.NeedClearScreen)
                {
                    await WriteDontPeakMessage(lastExamResult?.ResultsBeforeHideousText);
                }

                Chat.User.OnAnyActivity();
                var originRate = word.Score;

                var questionMetric = new QuestionMetric(word, question.Name);
                var result         = await PassWithRetries(question, word, learnList, wordQuestionNumber);

                switch (result.Results)
                {
                case ExamResult.Passed:
                    var succTask = _usersWordsService.RegisterSuccess(word);
                    questionsCount++;
                    questionsPassed++;
                    questionMetric.OnExamFinished(word.Score, true);
                    Botlog.SaveQuestionMetricInfo(questionMetric, Chat.ChatId);
                    await succTask;
                    Chat.User.OnQuestionPassed(word.Score - originRate);
                    break;

                case ExamResult.Failed:
                    var failureTask = _usersWordsService.RegisterFailure(word);
                    questionMetric.OnExamFinished(word.Score, false);
                    Botlog.SaveQuestionMetricInfo(questionMetric, Chat.ChatId);
                    questionsCount++;
                    await failureTask;
                    Chat.User.OnQuestionFailed(word.Score - originRate);
                    break;

                case ExamResult.Retry:
                case ExamResult.Impossible:
                    throw new NotSupportedException(result.Results.ToString());
                }

                if (!string.IsNullOrWhiteSpace(result.OpenResultsText))
                {
                    await Chat.SendMarkdownMessageAsync(result.OpenResultsText);
                }

                lastExamResult = result;

                Botlog.RegisterExamInfo(Chat.User.TelegramId, started, questionsCount, questionsPassed);
            }

            Chat.User.OnLearningDone();
            var updateUserTask           = _userService.Update(Chat.User);
            var finializeScoreUpdateTask = _usersWordsService.UpdateCurrentScoreForRandomWords(Chat.User, 10);

            //info after examination
            await SendExamResultToUser(
                distinctLearningWords : distinctLearningWords,
                originWordsScore : originWordsScore,
                questionsPassed : questionsPassed,
                questionsCount : questionsCount,
                learningWords : learningWords,
                gamingScoreBefore : gamingScoreBefore);

            await updateUserTask;
            await finializeScoreUpdateTask;
        }
Exemplo n.º 2
0
        public async Task EnterAsync(User user)
        {
            if (!await _usersWordsService.HasWords(user))
            {
                await _chatIo.SendMessageAsync("You need to add some more words before examination");

                return;
            }

            //Randomization and jobs
            //if (RandomTools.Rnd.Next() % 30 == 0)
            //    await _usersWordsService.AddMutualPhrasesToVocabAsync(user, 10);
            // else

            var startupScoreUpdate = _usersWordsService.UpdateCurrentScore(user, _examSettings.MaxLearningWordsCountInOneExam * 2);
            var typing             = _chatIo.SendTyping();

            var c = Random.RandomIn(_examSettings.MinLearningWordsCountInOneExam,
                                    _examSettings.MaxLearningWordsCountInOneExam);
            await startupScoreUpdate;
            await typing;
            var   learningWords
                = await _usersWordsService.GetWordsForLearningWithPhrasesAsync(user, c, 3);

            var learningWordsCount = learningWords.Length;

            if (learningWords.Average(w => w.AbsoluteScore) <= 4)
            {
                var sb = new StringBuilder("Examination\r\n");

                foreach (var pairModel in learningWords.Randomize())
                {
                    sb.AppendLine($"{pairModel.Word}\t\t:{pairModel.TranslationAsList}");
                }
                await _chatIo.SendMessageAsync(sb.ToString(), new InlineKeyboardButton
                {
                    CallbackData = "/startExamination",
                    Text         = "Start"
                }, new InlineKeyboardButton
                {
                    CallbackData = "/start",
                    Text         = "Cancel",
                });

                var userInput = await _chatIo.WaitInlineKeyboardInput();

                if (userInput != "/startExamination")
                {
                    return;
                }
            }
            var started = DateTime.Now;

            var learningAndAdvancedWords
                = await _usersWordsService.AppendAdvancedWordsToExamList(user, learningWords, _examSettings);

            var        questionsCount  = 0;
            var        questionsPassed = 0;
            var        i = 0;
            ExamResult?lastExamResult = null;

            foreach (var word in learningAndAdvancedWords)
            {
                var allLearningWordsWereShowedAtLeastOneTime = i < learningWordsCount;
                var exam = QuestionSelector.Singletone.GetNextQuestionFor(allLearningWordsWereShowedAtLeastOneTime, word);
                i++;
                var retryFlag = false;
                do
                {
                    retryFlag = false;
                    var sw             = Stopwatch.StartNew();
                    var questionMetric = new QuestionMetric(word, exam.Name);

                    var learnList = learningWords;

                    if (!learningWords.Contains(word))
                    {
                        learnList = learningWords.Append(word).ToArray();
                    }

                    if (i > 1 && exam.NeedClearScreen && lastExamResult != ExamResult.Impossible)
                    {
                        await WriteDontPeakMessage();

                        if (lastExamResult == ExamResult.Passed)
                        {
                            await WritePassed();
                        }
                    }

                    var result = await exam.Pass(_chatIo, _usersWordsService, word, learnList);

                    sw.Stop();
                    questionMetric.ElaspedMs = (int)sw.ElapsedMilliseconds;
                    switch (result)
                    {
                    case ExamResult.Impossible:
                        exam      = QuestionSelector.Singletone.GetNextQuestionFor(i == 0, word);
                        retryFlag = true;
                        break;

                    case ExamResult.Passed:
                        await WritePassed();

                        Botlog.SaveQuestionMetric(questionMetric);
                        questionsCount++;
                        questionsPassed++;
                        break;

                    case ExamResult.Failed:
                        await WriteFailed();

                        questionMetric.Result = 0;
                        Botlog.SaveQuestionMetric(questionMetric);
                        questionsCount++;
                        break;

                    case ExamResult.Retry:
                        retryFlag = true;
                        break;

                    case ExamResult.Exit: return;
                    }

                    lastExamResult = result;
                } while (retryFlag);
                Botlog.RegisterExamAsync(user.TelegramId, started, questionsCount, questionsPassed);
            }
            var finializeScoreUpdateTask = _usersWordsService.UpdateCurrentScore(user, 10);

            var doneMessage = new StringBuilder($"Learning done:  {questionsPassed}/{questionsCount}\r\n");

            foreach (var pairModel in learningAndAdvancedWords.Distinct())
            {
                doneMessage.Append(pairModel.Word + " - " + pairModel.TranslationAsList + "  (" +
                                   pairModel.AbsoluteScore + ")\r\n");
            }

            await _chatIo.SendMessageAsync(doneMessage.ToString());
        }