Example #1
0
        private async Task <TriviaCategory[]> GetCategoryOptions()
        {
            try
            {
                var categories = await QuestionAPI.GetCategories();

                var playedCategories = DBGame.GetPlayedCategories();
                var allOptions       = categories.Where(x => !playedCategories.Contains(x.Id)).ToList();

                var options = new TriviaCategory[Constants.CategoryChoiceOptions];
                for (int i = 0; i < Constants.CategoryChoiceOptions; i++)
                {
                    var o = allOptions[R.Next(allOptions.Count)];
                    options[i] = o;
                    allOptions.Remove(o);
                }
                return(options);
            }
            catch (Exception e)
            {
                await Bot.LogError(e);

                return(null);
            }
        }
Example #2
0
        public async Task Play()
        {
            try
            {
                var currentPlayer = DBGame.Round % 2 == 0 ? DBPlayer1 : DBPlayer2;
                var opponent      = currentPlayer == DBPlayer2 ? DBPlayer1 : DBPlayer2;

                if (!DBGame.PlayedPending) // IF: Pending questions, ELSE: New round questions
                {
                    var category = (await QuestionAPI.GetCategories()).FirstOrDefault(x => x.Id == DBGame.GetCurrentCategory());
                    var cName    = category?.Name ?? $"Unknown category ({category.Id})";

                    var m = await Bot.SendMessage($"Round {DBGame.Round - 1} Category: {cName}", currentPlayer.TelegramId);

                    // TODO cancel the game if m == null?

                    for (int qNr = 1; qNr <= 3; qNr++)
                    {
                        var q        = DBGame.GetCurrentQuestion(qNr);
                        var question = $"Round {DBGame.Round - 1}, Question {qNr}: " + q.Question;
                        var options  = new List <string> {
                            q.CorrectAnswer
                        };
                        options.AddRange(q.IncorrectAnswers.Take(3));
                        options = options.OrderBy(x => R.NextDouble()).ToList();
                        var correctId = options.IndexOf(q.CorrectAnswer);

                        Choice     = -1;
                        WaitingFor = currentPlayer.TelegramId;

                        m = await Bot.SendQuiz(currentPlayer.TelegramId, question, options, correctId);

                        if (m != null)
                        {
                            Program.PlayingDuels.Add(m.Poll.Id, this);
                        }
                        // TODO cancel the game otherwise?

                        for (int i = 0; i < Constants.AnswerTime + 3; i++)
                        {
                            await Task.Delay(1000);

                            if (Choice != -1)
                            {
                                break;
                            }
                        }
                        WaitingFor = 0;
                        Program.PlayingDuels.Remove(m.Poll.Id);

                        if (Choice == correctId)
                        {
                            var yet   = currentPlayer == DBPlayer1 ? DBGame.Player1Correct : DBGame.Player2Correct;
                            var flags = (Question)yet;
                            flags |= GetQuestionFlag(DBGame.Round - 1, qNr);
                            if (currentPlayer == DBPlayer1)
                            {
                                DBGame.Player1Correct = (int)flags;
                            }
                            else
                            {
                                DBGame.Player2Correct = (int)flags;
                            }
                        }
                        Choice = -1;
                    }
                    DBGame.PlayedPending = true;

                    if (DBGame.Round == 7)
                    {
                        var finished = DBGame.ToFinishedGame();
                        var winner   = finished.WinnerId;

                        finished.InsertDB();
                        DBGame.DeleteDB();

                        if (winner == DBPlayer1.Id)
                        {
                            DBPlayer1.Score += 3;
                            DBPlayer2.Score  = Math.Max(0, DBPlayer2.Score - 1);
                        }
                        else if (winner == DBPlayer2.Id)
                        {
                            DBPlayer1.Score  = Math.Max(0, DBPlayer1.Score - 1);
                            DBPlayer2.Score += 3;
                        }
                        else
                        {
                            DBPlayer1.Score += 1;
                            DBPlayer2.Score += 1;
                        }

                        if (((Question)DBGame.Player1Correct).GetUniqueFlags().Count == 18)
                        {
                            DBPlayer1.PerfectGames++;
                        }

                        if (((Question)DBGame.Player2Correct).GetUniqueFlags().Count == 18)
                        {
                            DBPlayer2.PerfectGames++;
                        }

                        DBPlayer1.UpdateScoreDB();
                        DBPlayer2.UpdateScoreDB();

                        await SendGameEndMessages();
                    }
                    else
                    {
                        DBGame.SaveDB();
                        await SendGameMessage(currentPlayer, opponent, true, false);
                    }
                }
                else
                {
                    var categories = await GetCategoryOptions();

                    var question = $"Round {DBGame.Round} - Which category would you like to play?";

                    Choice     = -1;
                    WaitingFor = currentPlayer.TelegramId;
                    var m = await Bot.SendPoll(currentPlayer.TelegramId, question, categories.Select(x => x.Name));

                    if (m != null)
                    {
                        Program.PlayingDuels.Add(m.Poll.Id, this);
                    }
                    // TODO cancel the game otherwise?

                    for (int i = 0; i < Constants.AnswerTime + 3; i++)
                    {
                        await Task.Delay(1000);

                        if (Choice != -1)
                        {
                            break;
                        }
                    }
                    WaitingFor = 0;
                    Program.PlayingDuels.Remove(m.Poll.Id);

                    TriviaCategory category;
                    if (Choice == -1)
                    {
                        category = categories[R.Next(Constants.CategoryChoiceOptions)];
                        await Bot.SendMessage("Time's up! I chose this category: " + category.Name, currentPlayer.TelegramId);
                    }
                    else
                    {
                        category = categories[Choice];
                    }

                    Choice = -1;

                    var questions = await QuestionAPI.GetQuestions(category.Id);

                    DBGame.SetCurrentCategory(category.Id);
                    DBGame.SetCurrentQuestions(questions);
                    DBGame.SaveDB();

                    for (int qNr = 1; qNr <= 3; qNr++)
                    {
                        var q = questions[qNr - 1];
                        question = $"Round {DBGame.Round}, Question {qNr}: " + q.Question;
                        var options = new List <string> {
                            q.CorrectAnswer
                        };
                        options.AddRange(q.IncorrectAnswers.Take(3));
                        options = options.OrderBy(x => R.NextDouble()).ToList();
                        var correctId = options.IndexOf(q.CorrectAnswer);

                        Choice     = -1;
                        WaitingFor = currentPlayer.TelegramId;

                        m = await Bot.SendQuiz(currentPlayer.TelegramId, question, options, correctId);

                        if (m != null)
                        {
                            Program.PlayingDuels.Add(m.Poll.Id, this);
                        }
                        else
                        {
                            var text = "I could not send out a quiz to one of this game's players! This game sadly has to be cancelled.";
                            await Bot.SendMessage(text, currentPlayer.TelegramId);

                            await Bot.SendMessage(text, opponent.TelegramId);

                            DBGame.ToFinishedGame().InsertDB();
                            DBGame.DeleteDB();
                            return;
                        }

                        for (int i = 0; i < Constants.AnswerTime + 3; i++)
                        {
                            await Task.Delay(1000);

                            if (Choice != -1)
                            {
                                break;
                            }
                        }
                        WaitingFor = 0;
                        Program.PlayingDuels.Remove(m.Poll.Id);

                        if (Choice == correctId)
                        {
                            var yet   = currentPlayer == DBPlayer1 ? DBGame.Player1Correct : DBGame.Player2Correct;
                            var flags = (Question)yet;
                            flags |= GetQuestionFlag(DBGame.Round, qNr);
                            if (currentPlayer == DBPlayer1)
                            {
                                DBGame.Player1Correct = (int)flags;
                            }
                            else
                            {
                                DBGame.Player2Correct = (int)flags;
                            }
                        }
                        Choice = -1;
                    }
                    DBGame.Round++;
                    DBGame.PlayedPending = false;
                    DBGame.SaveDB();

                    await SendGameMessage(currentPlayer, opponent, true, true);
                    await SendGameMessage(opponent, currentPlayer, false, false);
                }
            }
            catch (Exception e)
            {
                await Bot.LogError(e);
            }
        }