public async Task GetGameReportAsync() { if (!this.Manager.TryGet(this.Context.Channel.Id, out GameState currentGame) || currentGame?.ReaderId == null || !(this.Context.Channel is IGuildChannel guildChannel)) { return; } IEnumerable <PhaseScore> phaseScores = await currentGame.GetPhaseScores(); // If there's been no buzzes in the last question, don't show it in the report (could be end of the packet) PhaseScore lastQuestion = phaseScores.LastOrDefault(); if (lastQuestion?.ScoringSplitsOnActions?.Any() != true) { phaseScores = phaseScores.SkipLast(1); } IEnumerable <ScoringSplit> splits = phaseScores .SelectMany(pairs => pairs.ScoringSplitsOnActions.Select(pair => pair.Split)); HighestPointsLevel highestPointsLevel = FindHighestPointLevel(splits); // Because we only have the scoring splits here, we have to rely on buzzes having a team ID bool hasTeams = phaseScores .Any(scoresInPhase => scoresInPhase.ScoringSplitsOnActions.Any(pair => pair.Action.Buzz.TeamId != null)); IReadOnlyDictionary <string, string> teamIdToName = await currentGame.TeamManager.GetTeamIdToNames(); int scoresByQuestionCount = phaseScores.Count(); int questionsReported = await this.Context.Channel.SendAllEmbeds( phaseScores, () => new EmbedBuilder() { Title = GameReportTitle, Color = Color.Gold }, (phaseScore, index) => GetEmbedFieldForPhase( currentGame, phaseScore, teamIdToName, highestPointsLevel, index, index == scoresByQuestionCount - 1)); if (questionsReported > 0) { return; } EmbedBuilder embedBuilder = new EmbedBuilder() { Title = GameReportTitle, Color = Color.Gold, Description = "No questions read or answered yet." }; await this.Context.Channel.SendMessageAsync(embed : embedBuilder.Build()); }
protected override IResult <IEnumerable <ValueRange> > GetUpdateRangesForBonus( PhaseScore phaseScore, string[] teamIds, string sheetName, int row, int phasesCount) { Verify.IsNotNull(phaseScore, nameof(phaseScore)); List <ValueRange> ranges = new List <ValueRange>(); if (phaseScore.BonusScores?.Any() == true) { int bonusScoresIndex = Array.IndexOf(teamIds, phaseScore.BonusTeamId); if (bonusScoresIndex < 0) { return(new FailureResult <IEnumerable <ValueRange> >( $"Unknown bonus team in phase {row - this.FirstPhaseRow + 1}. Cannot accurately create a scoresheet.")); } int bonusTotal = phaseScore.BonusScores.Sum(); if (bonusTotal != 0 && bonusTotal != 10 && bonusTotal != 20 && bonusTotal != 30) { return(new FailureResult <IEnumerable <ValueRange> >( $"Invalid bonus value in phase {row - this.FirstPhaseRow + 1}. Value must be 0/10/20/30, but it was {bonusTotal}")); } SpreadsheetColumn bonusColumn = this.BonusColumns.Span[bonusScoresIndex]; ranges.Add(CreateUpdateSingleCellRequest(sheetName, bonusColumn, row, bonusTotal)); } else if (row != this.FirstPhaseRow + phasesCount - 1 || phaseScore.ScoringSplitsOnActions.Any()) { // We need to find if anyone got it correct, and if so, what team they are on. Fill that bonus // column with 0. ScoringSplitOnScoreAction split = phaseScore.ScoringSplitsOnActions .FirstOrDefault(split => split.Action.Score > 0); if (split != null) { // TODO: See if there's a better way to get the individual's team (add it when we add the buzz?) // Risk is if there's a team name that is the same as someone's ID // If it's an individual who is a team, then the teamId will be null, but their user ID may be a // team ID. int bonusIndex = Array.IndexOf( teamIds, split.Action.Buzz.TeamId ?? split.Action.Buzz.UserId.ToString(CultureInfo.InvariantCulture)); if (bonusIndex < 0 || bonusIndex >= 2) { return(new FailureResult <IEnumerable <ValueRange> >( $"Unknown bonus team in phase {row - this.FirstPhaseRow + 1}. Cannot accurately create a scoresheet.")); } ranges.Add(CreateUpdateSingleCellRequest(sheetName, this.BonusColumns.Span[bonusIndex], row, 0)); } } return(new SuccessResult <IEnumerable <ValueRange> >(ranges)); }
protected override IResult <IEnumerable <ValueRange> > GetUpdateRangesForBonus( PhaseScore phaseScore, string[] teamIds, string sheetName, int row, int phasesCount) { Verify.IsNotNull(phaseScore, nameof(phaseScore)); List <ValueRange> ranges = new List <ValueRange>(); if (phaseScore.BonusScores?.Any() == true) { int bonusPartCount = phaseScore.BonusScores.Count(); if (bonusPartCount != 3) { return(new FailureResult <IEnumerable <ValueRange> >( $"Non-three part bonus in phase {row - this.FirstPhaseRow + 1}. Number of parts: {bonusPartCount}. These aren't supported for the scoresheet.")); } int bonusScoresIndex = Array.IndexOf(teamIds, phaseScore.BonusTeamId); if (bonusScoresIndex < 0) { return(new FailureResult <IEnumerable <ValueRange> >( $"Unknown bonus team in phase {row - this.FirstPhaseRow + 1}. Cannot accurately create a scoresheet.")); } SpreadsheetColumn bonusColumn = this.BonusColumns.Span[bonusScoresIndex]; ranges.Add(CreateUpdateCellsAlongRowRequest( sheetName, bonusColumn, row, phaseScore.BonusScores.Select(score => score > 0).ToArray())); SpreadsheetColumn otherBonusColumn = this.BonusColumns.Span[this.BonusColumns.Length - bonusScoresIndex - 1]; ranges.Add(CreateUpdateCellsAlongRowRequest( sheetName, otherBonusColumn, row, ClearedBonusArray)); } else { // Clear the bonus columns for (int i = 0; i < this.BonusColumns.Span.Length; i++) { ranges.Add(CreateUpdateCellsAlongRowRequest( sheetName, this.BonusColumns.Span[i], row, ClearedBonusArray)); } } return(new SuccessResult <IEnumerable <ValueRange> >(ranges)); }
protected override IResult <IEnumerable <ValueRange> > GetAdditionalUpdateRangesForTossup( PhaseScore phaseScore, string[] teamIds, string sheetName, int row, int phasesCount) { Verify.IsNotNull(phaseScore, nameof(phaseScore)); if (row == this.FirstPhaseRow + phasesCount - 1 && !phaseScore.ScoringSplitsOnActions.Any()) { // We're in the last phase, and nothing has happened, so it's a placeholder phase for any future // scoring actions. This shouldn't be put into the scoresheet. return(new SuccessResult <IEnumerable <ValueRange> >(Enumerable.Empty <ValueRange>())); } // If the question went dead, put in "DT" in the first bonus column to indicate that the question was read if (phaseScore.ScoringSplitsOnActions.All(split => split.Action.Score <= 0)) { List <ValueRange> ranges = new List <ValueRange>(); ranges.Add(CreateUpdateSingleCellRequest(sheetName, this.BonusColumns.Span[0], row, "DT")); return(new SuccessResult <IEnumerable <ValueRange> >(ranges)); } return(new SuccessResult <IEnumerable <ValueRange> >(Enumerable.Empty <ValueRange>())); }
protected abstract IResult <IEnumerable <ValueRange> > GetAdditionalUpdateRangesForTossup( PhaseScore phaseScore, string[] teamIds, string sheetName, int row, int phasesCount);
protected override IResult <IEnumerable <ValueRange> > GetAdditionalUpdateRangesForTossup( PhaseScore phaseScore, string[] teamIds, string sheetName, int row, int phasesCount) { return(new SuccessResult <IEnumerable <ValueRange> >(Enumerable.Empty <ValueRange>())); }