Skip to content

Commit

Permalink
[MTGOSDK/API/Play] Tournament: Fix round, endtime calculation
Browse files Browse the repository at this point in the history
Re-compute the number of rounds and end-time based on the type of tournament elimination style and by the number of players in the event.
  • Loading branch information
Qonfused committed Jan 5, 2025
1 parent f98ab7b commit 018f365
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
61 changes: 59 additions & 2 deletions MTGOSDK/src/API/Play/Tournaments/Tournament.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,36 @@ public sealed class Tournament(dynamic tournament) : Event
/// <summary>
/// The time the event is scheduled to end.
/// </summary>
public DateTime EndTime => @base.ScheduledEndTime;
/// <remarks>
/// This is a rough approximation of the end time, based on the current number
/// of players in the tournament. The actual end time may be earlier than this
/// time if a round finishes early.
/// </remarks>
public DateTime EndTime
{
get
{
DateTime endTime = StartTime.AddMinutes(
// Minutes per round + 2 minutes between rounds.
((2 * Unbind(@base).MatchTimeLimit) * TotalRounds) +
(2 * (TotalRounds - 1)) +
// Minutes for deckbuilding.
Try<int>(() => Unbind(@base).MinutesForDeckbuilding)
);

// Round up to the nearest 10 minutes.
return endTime.AddMinutes(10 - (endTime.Minute % 10));
}
}

/// <summary>
/// The number of rounds in the tournament.
/// </summary>
public int TotalRounds => @base.TotalRounds;
public int TotalRounds =>
EliminationStyle == TournamentEliminationStyle.Swiss
? Math.Max(@base.TotalRounds, Math.Max(GetNumberOfRounds(TotalPlayers),
GetNumberOfRounds(MinimumPlayers)))
: @base.TotalRounds;

//
// ITournament wrapper properties
Expand All @@ -54,6 +78,15 @@ public sealed class Tournament(dynamic tournament) : Event
public TournamentState State =>
Cast<TournamentState>(Unbind(@base).State);

/// <summary>
/// The kind of elimination style used in the tournament
/// (i.e. "Swiss", "SingleElimination")
/// </summary>
public TournamentEliminationStyle EliminationStyle =>
Try(() => Cast<TournamentEliminationStyle>(
Unbind(@base).TournamentEliminationStyle),
fallback: TournamentEliminationStyle.Swiss);

/// <summary>
/// The time remaining in the current round or tournament phase.
/// </summary>
Expand Down Expand Up @@ -91,6 +124,30 @@ public sealed class Tournament(dynamic tournament) : Event
.OrderByDescending(s => s.Rank)
.ToList();

//
// ITournament wrapper methods
//

/// <summary>
/// Computes the number of rounds for a given size tournament.
/// </summary>
/// <param name="players">The number of players in the tournament.</param>
/// <returns>The number of rounds required for the given number of players.</returns>
public static int GetNumberOfRounds(int players) =>
players switch
{
>= 2 and <= 3 => 2,
>= 4 and <= 8 => 3,
>= 9 and <= 16 => 4,
>= 17 and <= 32 => 5,
>= 33 and <= 64 => 6,
>= 65 and <= 128 => 7,
>= 129 and <= 226 => 8,
>= 227 and <= 409 => 9,
>= 410 => 10,
_ => 1
};

//
// ITournament wrapper events
//
Expand Down
13 changes: 13 additions & 0 deletions MTGOSDK/src/API/Play/Tournaments/TournamentEliminationStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/** @file
Copyright (c) 2024, Cory Bennett. All rights reserved.
SPDX-License-Identifier: Apache-2.0
**/

namespace MTGOSDK.API.Play.Tournaments;

public enum TournamentEliminationStyle
{
Invalid,
Swiss,
SingleElimination
}

0 comments on commit 018f365

Please sign in to comment.