Пример #1
0
        public async Task <IActionResult> CreateQuiz([FromBody][Bind("Topic", "Category", "Description", "ImagePath", "Questions")] Quiz quiz)
        {
            if (quiz.Id != 0)
            {
                return(BadRequest("Invalid ID"));
            }

            quiz.Category = QuizUtil.CategoryFromIndex(int.TryParse(quiz.Category, out var i) ? i : (int?)null);

            if (quiz.Category == null)
            {
                return(BadRequest("Invalid category!"));
            }
            if (!QuizUtil.QuestionsValid(quiz.Questions))
            {
                return(BadRequest("Invalid question format!"));
            }
            if (!ModelState.IsValid)
            {
                return(BadRequest("Invalid quiz format!"));
            }

            quiz.OwnerUsername = _um.GetUserName(User);

            _db.Add(quiz);
            await _db.SaveChangesAsync();

            var user = await _um.GetUserAsync(User);

            user.MyQuizzes.Add(quiz);
            await _um.UpdateAsync(user);

            return(Ok());
        }
Пример #2
0
        public async Task <IActionResult> UpdateQuiz([FromBody][Bind("Topic", "Category", "Description", "ImagePath", "Questions")] Quiz quizForm)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest("Model state not valid!"));
            }

            var quiz = await _db.Quizzes
                       .Where(q => q.Id == quizForm.Id)
                       .Include(q => q.Questions)
                       .FirstOrDefaultAsync();

            if (quiz == null)
            {
                return(BadRequest("Quiz not found!"));
            }
            if (quiz.OwnerId != _um.GetUserId(User))
            {
                return(BadRequest("You are not the owner of this quiz!"));
            }
            if (!QuizUtil.QuestionsValid(quiz.Questions))
            {
                return(BadRequest("Question format not valid!"));
            }

            if (await _db.QuizzesTaken.AnyAsync(q => q.Quiz == quiz))
            {
                return(BadRequest("You cannot edit this quiz because someone has already taken it. You can however delete it, and create a new."));
            }

            try
            {
                if (quizForm.Category != quiz.Category)
                {
                    quiz.Category = QuizUtil.CategoryFromIndex(int.TryParse(quiz.Category, out var i) ? i : (int?)null);
                    if (quiz.Category == null)
                    {
                        return(BadRequest("Invalid category!"));
                    }
                }

                quiz.Topic       = quizForm.Topic;
                quiz.Description = quizForm.Description;
                quiz.ImagePath   = quizForm.ImagePath;

                _db.Questions.RemoveRange(quiz.Questions);
                quiz.Questions = quizForm.Questions;

                await _db.SaveChangesAsync();
            } catch (DbUpdateConcurrencyException) {
                return(BadRequest("Woopsie! Database error! :("));
            }

            return(Ok());
        }
Пример #3
0
        public async Task <IActionResult> CheckAnswer(int?quizId, int?questionId, char guessAlternative)
        {
            if (quizId == null || questionId == null || guessAlternative == 0)
            {
                return(BadRequest());
            }

            var question = await _db.Questions.FindAsync(questionId);

            if (question == null)
            {
                return(BadRequest());
            }

            var userId   = _um.GetUserId(User);
            var xpGained = 0;
            var bonus    = 0;

            // If user is authorized
            if (userId != null)
            {
                var user = await _db.Users
                           .Include(u => u.QuestionsTaken)
                           .Include(u => u.QuizzesTaken)
                           .Include(u => u.MyQuizzes)
                           .SingleOrDefaultAsync(u => u.Id == userId);

                // Check if user has answered this question before
                if (!user.QuestionsTaken.Exists(q => q.QuestionId == questionId))
                {
                    // Check answer by alternative
                    var answeredCorrectly = guessAlternative == question.CorrectAlternative;
                    var timer             = DateTime.Now - user.LastQuestionStarted;
                    var timerSec          = (int)Math.Round(timer.TotalSeconds);
                    var isOwner           = user.MyQuizzes.Any(q => q.Id == quizId);

                    // If answered within time frame
                    if (answeredCorrectly && timerSec >= 0 && timerSec <= 15 && !isOwner)
                    {
                        xpGained = QuizUtil.XpGainedFromQuestion(question.Difficulty);
                        bonus    = (int)(xpGained * (((15f - timerSec) / 15f * 100f) / 100f));
                        AddExperience(user, xpGained + bonus);
                    }

                    AddQuestionTaken(user, question, answeredCorrectly, xpGained, bonus, timer, guessAlternative);
                }

                // Check if all the questions of the quiz has been answered
                UpdateQuizTaken(user, quizId, questionId);
            }

            return(Ok(new { correctAlternative = question.CorrectAlternative, xpGained, bonus }));
        }
Пример #4
0
        /// <summary>
        /// バインドします。
        /// </summary>
        public override void Bind(QuizModel model)
        {
            // キーボードのバインド
            var keyboardButtons = keyboardBase.GetComponentsInChildren <Button>().ToList();
            var deleteButton    = keyboardButtons.Find(x => x.name == DeleteButtonObjectName);

            {
                // 入力ボタン
                foreach (var button in keyboardButtons.Where(x => x.name != DeleteButtonObjectName))
                {
                    button.OnClickAsObservable().Subscribe(_ => {
                        var text     = button.GetComponentInChildren <Text>();
                        _input.Value = QuizUtil.Convert($"{Input}{text.text}", WordEnum);
                    }).AddTo(button);
                }

                // 削除ボタン
                deleteButton.OnClickAsObservable().Subscribe(_ => {
                    if (!string.IsNullOrEmpty(Input))
                    {
                        if (Input.Length >= 8)
                        {
                            _input.Value = Input.Substring(0, 7);
                        }
                        else
                        {
                            _input.Value = Input.Substring(0, Input.Length - 1);
                        }
                    }
                }).AddTo(deleteButton);
            }

            // 入力文字列の反映
            _input.Subscribe(input => {
                for (int index = 0; index < TypingTexts.Count && index < input.Length; index++)
                {
                    TypingTexts[index].text = input[index].ToString();
                }
                for (int index = input.Length; index < TypingTexts.Count; index++)
                {
                    TypingTexts[index].text = string.Empty;
                }
            }).AddTo(this);

            // OKボタン
            okButton.OnClickAsObservable().Subscribe(_ => {
                var answer = new string(Input.Take(8).ToArray());
                model.PushAnswer(answer);
            }).AddTo(okButton);
        }
Пример #5
0
        /// <summary>
        /// スコアを変更します。
        /// </summary>
        public void ChangeScore(int before, int after)
        {
            if (before < after)
            {
                var upScore = after - before;
                this.score.text = $"<color=yellow>(+{upScore})</color>{after}点";
            }
            else
            {
                this.score.text = $"{after}点";
            }

            var rank = QuizUtil.GetQuizRank(after);

            this.rank.text = rank.ToString();

            var rankRatio = QuizUtil.GetRankRatio(after);

            nextRankBackground.fillAmount = rankRatio;
        }
Пример #6
0
        private static async Task AddRandomQuizzes(int amount)
        {
            // Get questions from open trivia DB API
            for (var i = 0; i < amount; i++)
            {
                dynamic randomQuestion = await GetObjectFromApi("https://opentdb.com/", "api.php?amount=10");

                if (randomQuestion == null || randomQuestion.response_code != 0)
                {
                    continue;
                }

                var apiQuestions = new List <Question>();

                foreach (var q in randomQuestion.results)
                {
                    if (q == null)
                    {
                        continue;
                    }
                    // TODO: Should strings be json stringified?
                    string   text        = HttpUtility.HtmlDecode((string)q.question);
                    string   qType       = q.type;
                    string   qDifficulty = q.difficulty;
                    string   answer      = HttpUtility.HtmlDecode((string)q.correct_answer);
                    Question question;

                    if (qType == "multiple")
                    {
                        string[] alternatives =
                        {
                            answer,
                            HttpUtility.HtmlDecode((string)q.incorrect_answers[0]),
                            HttpUtility.HtmlDecode((string)q.incorrect_answers[1]),
                            HttpUtility.HtmlDecode((string)q.incorrect_answers[2])
                        };
                        var alt = JsonConvert.SerializeObject(alternatives);
                        question = new Question("multiple_choice", text, alt, answer, 'A', qDifficulty, "");
                    }
                    else
                    {
                        question = new Question("true_false", text, null, answer, answer == "true" ? 'T' : 'F', qDifficulty, null);
                    }

                    apiQuestions.Add(question);
                    await _db.Questions.AddRangeAsync(question);

                    await _db.SaveChangesAsync();
                }

                string randomName = Path.GetRandomFileName().Replace(".", "");
                string category   = HttpUtility.HtmlDecode(QuizUtil.CategoryFromIndex(_ran.Next(0, 23)));
                var    ranUser    = await _db.Users.Skip(_ran.Next(0, _db.Users.Count())).FirstAsync();

                var quiz = new Quiz(ranUser, apiQuestions, category, randomName, "Description", "easy")
                {
                    ImagePath = "/images/logo_transparent_notxt.png", Upvotes = _ran.Next(0, 500), Views = _ran.Next(0, 50000)
                };

                await _db.Quizzes.AddRangeAsync(quiz);

                await _db.SaveChangesAsync();
            }
        }
Пример #7
0
 /// <summary>
 /// 残り回答時間ゲージを設定します。
 /// </summary>
 public void SetSlider(Format format, float value)
 {
     Slider.value      = value;
     SliderImage.color = QuizUtil.GetSliderColor(format, value);
 }
Пример #8
0
        /// <summary>
        /// HomeMenuのバインダー
        /// </summary>
        public override void Bind(SceneModel model)
        {
            // 第○問目
            var quizModel = model.FindModel <QuizModel>();

            quizModel.OnChangeCount.Subscribe(count => {
                this.CurrentQuiz = quizModel.CurrentQuiz;
                SetQuiz(count);

                ElapsedSeconds = 0.0f;
            });

            // 解答送信
            quizModel.OnPushAnswer.Subscribe(answer => {
                // 正誤判定&スコア計算
                var isCorrect = CurrentQuiz.CorrectAnswer == answer;
                if (isCorrect)
                {
                    var answerTime   = QuizConfig.LimitSeconds - ElapsedSeconds;
                    var score        = QuizUtil.GetScore(CurrentQuiz, answerTime, false); // TODO:マニアック判定
                    quizModel.Score += score;
                }
                else
                {
                    scorePanel.ChangeScore(quizModel.Score, quizModel.Score);
                }
                GeLogger.Debug($"your answer is {answer}. correctAnswer is {CurrentQuiz.CorrectAnswer}");

                // 正誤表示
                scorePanel.ActivateFalsehoodObject(isCorrect);

                // 画面のリセット
                questionPanel.Reset();
                answerPanel.Reset(CurrentQuiz);

                // 次の問題へ
                sentenceCount = 0;
                quizModel.QuizCount++;
            }).AddTo(this);

            // 解答部分のバインド
            answerPanel.Bind(model);

            // 回答時間
            this.UpdateAsObservable().Subscribe(_ => {
                ElapsedSeconds += Time.deltaTime;
                var value       = 1 - Mathf.Clamp01(ElapsedSeconds / QuizConfig.LimitSeconds);
                questionPanel.SetSlider(CurrentQuiz.Format, value);

                if (ElapsedSeconds >= QuizConfig.LimitSeconds)
                {
                    quizModel.PushAnswer("時間切れ");
                }
            });

            // 問題文の表示
            Observable.Interval(TimeSpan.FromSeconds(QuizConfig.SentenceInterval)).Subscribe(_ => {
                questionPanel.ViewSentence(CurrentQuiz, ref sentenceCount);
            }).AddTo(this);

            // スコア変更
            quizModel.OnChangeScore.Buffer(2, 1).Subscribe(scores => {
                var before = scores[0];
                var after  = scores[1];
                scorePanel.ChangeScore(before, after);
            }).AddTo(this);
        }
Пример #9
0
        public async Task <IActionResult> GetQuizList(string username, int page, int size, string type, int?categoryIndex, string difficulty, string orderBy, string search)
        {
            if (page < 1 || (size > 20 || size < 0))
            {
                return(BadRequest());
            }

            switch (type)
            {
            case "history" when username != null:
            {
                var query = await _um.Users
                            .Where(u => u.UserName == username)
                            .SelectMany(q => q.QuizzesTaken)
                            .Include(q => q.Quiz).ToListAsync();

                var entries      = query.Skip((page - 1) * size).Take(size).ToList();
                var pages        = (int)Math.Ceiling(decimal.Divide(query.Count, size));
                var authUsername = _um.GetUserName(User);
                var showSummary  = authUsername != null && authUsername == username;

                return(Ok(new { entries, pages, showSummary }));
            }

            case "quizzesBy" when username != null:
            {
                var query = await _db.Quizzes.Where(q => q.OwnerUsername == username).ToListAsync();

                var entries      = query.Skip((page - 1) * size).Take(size).ToList();
                var pages        = (int)Math.Ceiling(decimal.Divide(query.Count, size));
                var authUsername = _um.GetUserName(User);
                var canEdit      = authUsername != null && authUsername == username;

                return(Ok(new { entries, pages, canEdit }));
            }

            case "search":
            {
                var category = QuizUtil.CategoryFromIndex(categoryIndex);
                var query    = await _db.Quizzes.ToListAsync();

                // If category and difficulty is defined, filter the query
                if (category != null)
                {
                    query = query.Where(q => q.Category == category).ToList();
                }
                else if (difficulty != null)
                {
                    query = query.Where(q => q.Difficulty == difficulty).ToList();
                }

                if (search != null)
                {
                    var searchArr        = Regex.Split(search.ToLower(), @"\s+").Where(s => s != string.Empty);
                    var queryUserName    = query.Where(q => searchArr.Any(q.OwnerUsername.ToLower().Contains)).ToList();
                    var queryDescription = query.Where(q => searchArr.Any(q.Description.ToLower().Contains)).ToList();
                    var queryCategory    = query.Where(q => searchArr.Any(q.Category.ToLower().Contains)).ToList();
                    var queryTopic       = query.Where(q => searchArr.Any(q.Topic.ToLower().Contains)).ToList();

                    List <Quiz> searchList = new List <Quiz>();
                    searchList.AddRange(queryTopic);
                    searchList.AddRange(queryUserName);
                    searchList.AddRange(queryDescription);
                    searchList.AddRange(queryCategory);
                    query = searchList.Distinct().ToList();
                }

                if (orderBy != null)
                {
                    if (orderBy == "views")
                    {
                        query = query.OrderByDescending(q => q.Views).ToList();
                    }
                    else if (orderBy == "upvotes")
                    {
                        query = query.OrderByDescending(q => q.Upvotes).ToList();
                    }
                    else if (orderBy == "recent")
                    {
                        query = query.OrderByDescending(q => q.CreationDate).ToList();
                    }
                }

                var entries = query.Skip((page - 1) * size).Take(size).ToList();
                var pages   = (int)Math.Ceiling(decimal.Divide(query.Count, size));

                return(Ok(new { entries, pages }));
            }

            default:
                return(BadRequest("Type not found!"));
            }
        }
Пример #10
0
        /// <summary>
        /// 初期化を行います。
        /// </summary>
        public override void Initialize(QuizEntity quiz)
        {
            Reset();

            WordEnum = QuizUtil.GetWordEnum(quiz.CorrectAnswer);
        }