module TournamentSystem::Algorithm::SingleBracket
This module provides algorithms for dealing with single bracket elimination tournament systems.
Public Instance Methods
Guess the next round (starting at 0) for a single bracket tournament.
@param teams_count [Integer] the number of teams @param matches_count [Integer] the number of existing matches @return [Integer] next round number @raise [ArgumentError] when the number of matches does not add up
# File lib/tournament_system/algorithm/single_bracket.rb, line 33 def guess_round(teams_count, matches_count) rounds = total_rounds(teams_count) total_teams = max_teams(rounds) # Make sure we don't have too many matches raise ArgumentError, 'Too many matches' unless total_teams >= matches_count round = rounds - Math.log2(total_teams - matches_count) # Make sure we don't have some weird number of matches raise ArgumentError, 'Invalid number of matches' unless (round % 1).zero? round.to_i end
Calculates the maximum number of teams that can play in a single bracket tournament with a given number of rounds.
@param rounds [Integer] the number of rounds @return [Integer] number of teams that could play
# File lib/tournament_system/algorithm/single_bracket.rb, line 23 def max_teams(rounds) 2**rounds end
@deprecated Please use {Util.padd_teams_pow2} instead.
# File lib/tournament_system/algorithm/single_bracket.rb, line 48 def padd_teams(teams) message = 'NOTE: padd_teams is now deprecated in favour of Util.padd_teams_even.'\ 'It will be removed in the next major version'\ "SingleBracket.padd_teams called from #{Gem.location_of_caller.join(':')}" warn message unless Gem::Deprecate.skip Util.padd_teams_pow2(teams) end
Seed teams for a single bracket tournament.
Seed in a way that teams earlier in teams
always win against later ones, the first team plays the second in the finals, the 3rd and 4th get nocked out in the semi-finals, etc.
Designed to be used with {GroupPairing#adjacent}.
@param teams [Array<Team>] @return [Array<team>] @raise [ArgumentError] when the number of teams is not a power of 2
# File lib/tournament_system/algorithm/single_bracket.rb, line 68 def seed(teams) raise ArgumentError, 'Need power-of-2 teams' unless (Math.log2(teams.length) % 1).zero? teams = teams.map.with_index do |team, index| OpenStruct.new(team: team, index: index) end seed_bracket(teams).map(&:team) end
Calculates the total number of rounds needed for a single bracket tournament with a certain number of teams.
@param teams_count [Integer] the number of teams @return [Integer] number of rounds needed for round robin
# File lib/tournament_system/algorithm/single_bracket.rb, line 14 def total_rounds(teams_count) Math.log2(teams_count).ceil end
Private Instance Methods
Recursively seed the top half of the teams and match teams reversed by index to the bottom half.
# File lib/tournament_system/algorithm/single_bracket.rb, line 81 def seed_bracket(teams) return teams if teams.length <= 2 top_half, bottom_half = teams.each_slice(teams.length / 2).to_a top_half = seed_bracket top_half top_half.map do |team| # match with the team appropriate team in the bottom half match = bottom_half[-team.index - 1] [team, match] end.flatten end