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); } }
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); } }