mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-24 17:04:43 +00:00
Using eager loading in GenerateTournamentMatches and AdvanceWrestler, generating/manipulating in-memory, and doing a single bulk insert or update at the end.
This commit is contained in:
@@ -156,7 +156,7 @@ class Weight < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def calculate_bracket_size
|
def calculate_bracket_size
|
||||||
num_wrestlers = wrestlers.reload.size
|
num_wrestlers = wrestlers.size
|
||||||
return nil if num_wrestlers <= 0 # Handle invalid input
|
return nil if num_wrestlers <= 0 # Handle invalid input
|
||||||
|
|
||||||
# Find the smallest power of 2 greater than or equal to num_wrestlers
|
# Find the smallest power of 2 greater than or equal to num_wrestlers
|
||||||
|
|||||||
@@ -12,21 +12,97 @@ class AdvanceWrestler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def advance_raw
|
def advance_raw
|
||||||
@last_match.reload
|
@last_match = Match.find_by(id: @last_match&.id)
|
||||||
@wrestler.reload
|
@wrestler = Wrestler.includes(:school, :weight).find_by(id: @wrestler.id)
|
||||||
if @last_match && @last_match.finished?
|
return unless @last_match && @wrestler && @last_match.finished?
|
||||||
pool_to_bracket_advancement if @tournament.tournament_type == "Pool to bracket"
|
|
||||||
ModifiedDoubleEliminationAdvance.new(@wrestler, @last_match).bracket_advancement if @tournament.tournament_type.include? "Modified 16 Man Double Elimination"
|
context = preload_advancement_context
|
||||||
DoubleEliminationAdvance.new(@wrestler, @last_match).bracket_advancement if @tournament.tournament_type.include? "Regular Double Elimination"
|
matches_to_advance = []
|
||||||
|
|
||||||
|
if @tournament.tournament_type == "Pool to bracket"
|
||||||
|
matches_to_advance.concat(pool_to_bracket_advancement(context))
|
||||||
|
elsif @tournament.tournament_type.include?("Modified 16 Man Double Elimination")
|
||||||
|
service = ModifiedDoubleEliminationAdvance.new(@wrestler, @last_match, matches: context[:matches])
|
||||||
|
service.bracket_advancement
|
||||||
|
matches_to_advance.concat(service.matches_to_advance)
|
||||||
|
elsif @tournament.tournament_type.include?("Regular Double Elimination")
|
||||||
|
service = DoubleEliminationAdvance.new(@wrestler, @last_match, matches: context[:matches])
|
||||||
|
service.bracket_advancement
|
||||||
|
matches_to_advance.concat(service.matches_to_advance)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
persist_advancement_changes(context)
|
||||||
|
advance_pending_matches(matches_to_advance)
|
||||||
@wrestler.school.calculate_score
|
@wrestler.school.calculate_score
|
||||||
end
|
end
|
||||||
|
|
||||||
def pool_to_bracket_advancement
|
def preload_advancement_context
|
||||||
if @wrestler.weight.all_pool_matches_finished(@wrestler.pool) and (@wrestler.finished_bracket_matches.size < 1)
|
weight = Weight.includes(:matches, :wrestlers).find(@wrestler.weight_id)
|
||||||
PoolOrder.new(@wrestler.weight.wrestlers_in_pool(@wrestler.pool)).getPoolOrder
|
{
|
||||||
|
weight: weight,
|
||||||
|
matches: weight.matches.to_a,
|
||||||
|
wrestlers: weight.wrestlers.to_a
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_advancement_changes(context)
|
||||||
|
persist_matches(context[:matches])
|
||||||
|
persist_wrestlers(context[:wrestlers])
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_matches(matches)
|
||||||
|
timestamp = Time.current
|
||||||
|
updates = matches.filter_map do |m|
|
||||||
|
next unless m.changed?
|
||||||
|
|
||||||
|
{
|
||||||
|
id: m.id,
|
||||||
|
w1: m.w1,
|
||||||
|
w2: m.w2,
|
||||||
|
winner_id: m.winner_id,
|
||||||
|
win_type: m.win_type,
|
||||||
|
score: m.score,
|
||||||
|
finished: m.finished,
|
||||||
|
loser1_name: m.loser1_name,
|
||||||
|
loser2_name: m.loser2_name,
|
||||||
|
finished_at: m.finished_at,
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
end
|
end
|
||||||
PoolAdvance.new(@wrestler).advanceWrestler
|
Match.upsert_all(updates) if updates.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_wrestlers(wrestlers)
|
||||||
|
timestamp = Time.current
|
||||||
|
updates = wrestlers.filter_map do |w|
|
||||||
|
next unless w.changed?
|
||||||
|
|
||||||
|
{
|
||||||
|
id: w.id,
|
||||||
|
pool_placement: w.pool_placement,
|
||||||
|
pool_placement_tiebreaker: w.pool_placement_tiebreaker,
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
Wrestler.upsert_all(updates) if updates.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def advance_pending_matches(matches_to_advance)
|
||||||
|
matches_to_advance.uniq(&:id).each do |match|
|
||||||
|
match.advance_wrestlers
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def pool_to_bracket_advancement(context)
|
||||||
|
matches_to_advance = []
|
||||||
|
wrestlers_in_pool = context[:wrestlers].select { |w| w.pool == @wrestler.pool }
|
||||||
|
if @wrestler.weight.all_pool_matches_finished(@wrestler.pool) && (@wrestler.finished_bracket_matches.size < 1)
|
||||||
|
PoolOrder.new(wrestlers_in_pool).getPoolOrder
|
||||||
|
end
|
||||||
|
service = PoolAdvance.new(@wrestler, @last_match, matches: context[:matches], wrestlers: context[:wrestlers])
|
||||||
|
service.advanceWrestler
|
||||||
|
matches_to_advance.concat(service.matches_to_advance)
|
||||||
|
matches_to_advance
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
class DoubleEliminationAdvance
|
class DoubleEliminationAdvance
|
||||||
|
|
||||||
def initialize(wrestler,last_match)
|
attr_reader :matches_to_advance
|
||||||
|
|
||||||
|
def initialize(wrestler,last_match, matches: nil)
|
||||||
@wrestler = wrestler
|
@wrestler = wrestler
|
||||||
@last_match = last_match
|
@last_match = last_match
|
||||||
|
@matches = matches || @wrestler.weight.matches.to_a
|
||||||
|
@matches_to_advance = []
|
||||||
@next_match_position_number = (@last_match.bracket_position_number / 2.0)
|
@next_match_position_number = (@last_match.bracket_position_number / 2.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -48,7 +52,7 @@ class DoubleEliminationAdvance
|
|||||||
end
|
end
|
||||||
|
|
||||||
if next_match_bracket_position
|
if next_match_bracket_position
|
||||||
next_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?",next_match_bracket_position,next_match_position_number.ceil,@wrestler.weight_id).first
|
next_match = @matches.find { |m| m.bracket_position == next_match_bracket_position && m.bracket_position_number == next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
end
|
end
|
||||||
|
|
||||||
if next_match
|
if next_match
|
||||||
@@ -59,18 +63,16 @@ class DoubleEliminationAdvance
|
|||||||
def update_new_match(match, wrestler_number)
|
def update_new_match(match, wrestler_number)
|
||||||
if wrestler_number == 2 or (match.loser1_name and match.loser1_name.include? "Loser of")
|
if wrestler_number == 2 or (match.loser1_name and match.loser1_name.include? "Loser of")
|
||||||
match.w2 = @wrestler.id
|
match.w2 = @wrestler.id
|
||||||
match.save
|
|
||||||
elsif wrestler_number == 1
|
elsif wrestler_number == 1
|
||||||
match.w1 = @wrestler.id
|
match.w1 = @wrestler.id
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_consolation_bye
|
def update_consolation_bye
|
||||||
bout = @wrestler.last_match.bout_number
|
bout = @wrestler.last_match.bout_number
|
||||||
next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?","Loser of #{bout}","Loser of #{bout}",@wrestler.weight_id)
|
next_match = @matches.find { |m| m.weight_id == @wrestler.weight_id && (m.loser1_name == "Loser of #{bout}" || m.loser2_name == "Loser of #{bout}") }
|
||||||
if next_match.size > 0
|
if next_match
|
||||||
next_match.first.replace_loser_name_with_bye("Loser of #{bout}")
|
replace_loser_name_with_bye(next_match, "Loser of #{bout}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,27 +86,18 @@ class DoubleEliminationAdvance
|
|||||||
|
|
||||||
def losers_bracket_advancement
|
def losers_bracket_advancement
|
||||||
bout = @last_match.bout_number
|
bout = @last_match.bout_number
|
||||||
next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?", "Loser of #{bout}", "Loser of #{bout}", @wrestler.weight_id).first
|
next_match = @matches.find { |m| m.weight_id == @wrestler.weight_id && (m.loser1_name == "Loser of #{bout}" || m.loser2_name == "Loser of #{bout}") }
|
||||||
|
|
||||||
if next_match.present?
|
if next_match.present?
|
||||||
next_match.replace_loser_name_with_wrestler(@wrestler, "Loser of #{bout}")
|
replace_loser_name_with_wrestler(next_match, @wrestler, "Loser of #{bout}")
|
||||||
next_match.reload
|
|
||||||
|
|
||||||
if next_match.loser1_name == "BYE" || next_match.loser2_name == "BYE"
|
if next_match.loser1_name == "BYE" || next_match.loser2_name == "BYE"
|
||||||
next_match.winner_id = @wrestler.id
|
next_match.winner_id = @wrestler.id
|
||||||
next_match.win_type = "BYE"
|
next_match.win_type = "BYE"
|
||||||
next_match.score = ""
|
next_match.score = ""
|
||||||
next_match.finished = 1
|
next_match.finished = 1
|
||||||
# puts "Before save: winner_id=#{next_match.winner_id}"
|
next_match.finished_at = Time.current
|
||||||
|
@matches_to_advance << next_match
|
||||||
# if next_match.save
|
|
||||||
# puts "Save successful: winner_id=#{next_match.reload.winner_id}"
|
|
||||||
# else
|
|
||||||
# puts "Save failed: #{next_match.errors.full_messages}"
|
|
||||||
# end
|
|
||||||
next_match.save
|
|
||||||
|
|
||||||
next_match.advance_wrestlers
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -112,51 +105,69 @@ class DoubleEliminationAdvance
|
|||||||
|
|
||||||
def advance_double_byes
|
def advance_double_byes
|
||||||
weight = @wrestler.weight
|
weight = @wrestler.weight
|
||||||
weight.matches.select{|m| m.loser1_name == "BYE" and m.loser2_name == "BYE" and m.finished != 1}.each do |match|
|
@matches.select{|m| m.weight_id == weight.id && m.loser1_name == "BYE" and m.loser2_name == "BYE" and m.finished != 1}.each do |match|
|
||||||
match.finished = 1
|
match.finished = 1
|
||||||
|
match.finished_at = Time.current
|
||||||
match.score = ""
|
match.score = ""
|
||||||
match.win_type = "BYE"
|
match.win_type = "BYE"
|
||||||
next_match_position_number = (match.bracket_position_number / 2.0).ceil
|
next_match_position_number = (match.bracket_position_number / 2.0).ceil
|
||||||
after_matches = weight.matches.select{|m| m.round > match.round and m.is_consolation_match == match.is_consolation_match }.sort_by{|m| m.round}
|
after_matches = @matches.select{|m| m.weight_id == weight.id && m.round > match.round and m.is_consolation_match == match.is_consolation_match }.sort_by{|m| m.round}
|
||||||
next_matches = weight.matches.select{|m| m.round == after_matches.first.round and m.is_consolation_match == match.is_consolation_match }
|
next if after_matches.empty?
|
||||||
this_round_matches = weight.matches.select{|m| m.round == match.round and m.is_consolation_match == match.is_consolation_match }
|
next_matches = @matches.select{|m| m.weight_id == weight.id && m.round == after_matches.first.round and m.is_consolation_match == match.is_consolation_match }
|
||||||
|
this_round_matches = @matches.select{|m| m.weight_id == weight.id && m.round == match.round and m.is_consolation_match == match.is_consolation_match }
|
||||||
|
next_match = nil
|
||||||
|
|
||||||
if next_matches.size == this_round_matches.size
|
if next_matches.size == this_round_matches.size
|
||||||
next_match = next_matches.select{|m| m.bracket_position_number == match.bracket_position_number}.first
|
next_match = next_matches.select{|m| m.bracket_position_number == match.bracket_position_number}.first
|
||||||
next_match.loser2_name = "BYE"
|
next_match.loser2_name = "BYE" if next_match
|
||||||
next_match.save
|
|
||||||
elsif next_matches.size < this_round_matches.size and next_matches.size > 0
|
elsif next_matches.size < this_round_matches.size and next_matches.size > 0
|
||||||
next_match = next_matches.select{|m| m.bracket_position_number == next_match_position_number}.first
|
next_match = next_matches.select{|m| m.bracket_position_number == next_match_position_number}.first
|
||||||
if next_match.bracket_position_number == next_match_position_number
|
if next_match && next_match.bracket_position_number == next_match_position_number
|
||||||
next_match.loser2_name = "BYE"
|
next_match.loser2_name = "BYE"
|
||||||
else
|
elsif next_match
|
||||||
next_match.loser1_name = "BYE"
|
next_match.loser1_name = "BYE"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next_match.save
|
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_bye_for_placement
|
def set_bye_for_placement
|
||||||
weight = @wrestler.weight
|
weight = @wrestler.weight
|
||||||
fifth_finals = weight.matches.select{|match| match.bracket_position == '5/6'}.first
|
fifth_finals = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == '5/6'}.first
|
||||||
seventh_finals = weight.matches.select{|match| match.bracket_position == '7/8'}.first
|
seventh_finals = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == '7/8'}.first
|
||||||
if seventh_finals
|
if seventh_finals
|
||||||
conso_quarter = weight.matches.select{|match| match.bracket_position == 'Conso Quarter'}
|
conso_quarter = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == 'Conso Quarter'}
|
||||||
conso_quarter.each do |match|
|
conso_quarter.each do |match|
|
||||||
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
||||||
seventh_finals.replace_loser_name_with_bye("Loser of #{match.bout_number}")
|
replace_loser_name_with_bye(seventh_finals, "Loser of #{match.bout_number}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if fifth_finals
|
if fifth_finals
|
||||||
conso_semis = weight.matches.select{|match| match.bracket_position == 'Conso Semis'}
|
conso_semis = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == 'Conso Semis'}
|
||||||
conso_semis.each do |match|
|
conso_semis.each do |match|
|
||||||
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
||||||
fifth_finals.replace_loser_name_with_bye("Loser of #{match.bout_number}")
|
replace_loser_name_with_bye(fifth_finals, "Loser of #{match.bout_number}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replace_loser_name_with_wrestler(match, wrestler, loser_name)
|
||||||
|
if match.loser1_name == loser_name
|
||||||
|
match.w1 = wrestler.id
|
||||||
|
end
|
||||||
|
if match.loser2_name == loser_name
|
||||||
|
match.w2 = wrestler.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_loser_name_with_bye(match, loser_name)
|
||||||
|
if match.loser1_name == loser_name
|
||||||
|
match.loser1_name = "BYE"
|
||||||
|
end
|
||||||
|
if match.loser2_name == loser_name
|
||||||
|
match.loser2_name = "BYE"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
class ModifiedDoubleEliminationAdvance
|
class ModifiedDoubleEliminationAdvance
|
||||||
|
|
||||||
def initialize(wrestler,last_match)
|
attr_reader :matches_to_advance
|
||||||
|
|
||||||
|
def initialize(wrestler,last_match, matches: nil)
|
||||||
@wrestler = wrestler
|
@wrestler = wrestler
|
||||||
@last_match = last_match
|
@last_match = last_match
|
||||||
|
@matches = matches || @wrestler.weight.matches.to_a
|
||||||
|
@matches_to_advance = []
|
||||||
@next_match_position_number = (@last_match.bracket_position_number / 2.0)
|
@next_match_position_number = (@last_match.bracket_position_number / 2.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -25,42 +29,41 @@ class ModifiedDoubleEliminationAdvance
|
|||||||
update_consolation_bye
|
update_consolation_bye
|
||||||
end
|
end
|
||||||
if @last_match.bracket_position == "Quarter"
|
if @last_match.bracket_position == "Quarter"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","Semis",@next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "Semis" && m.bracket_position_number == @next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
elsif @last_match.bracket_position == "Semis"
|
elsif @last_match.bracket_position == "Semis"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","1/2",@next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "1/2" && m.bracket_position_number == @next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
elsif @last_match.bracket_position == "Conso Semis"
|
elsif @last_match.bracket_position == "Conso Semis"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","5/6",@next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "5/6" && m.bracket_position_number == @next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
elsif @last_match.bracket_position == "Conso Quarter"
|
elsif @last_match.bracket_position == "Conso Quarter"
|
||||||
# it's a special bracket where a semi loser is not dropping down
|
# it's a special bracket where a semi loser is not dropping down
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","Conso Semis",@next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "Conso Semis" && m.bracket_position_number == @next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
elsif @last_match.bracket_position == "Bracket Round of 16"
|
elsif @last_match.bracket_position == "Bracket Round of 16"
|
||||||
new_match = Match.where("bracket_position_number = ? and weight_id = ? and round > ? and bracket_position = ?", @next_match_position_number.ceil,@wrestler.weight_id, @last_match.round , "Quarter").sort_by{|m| m.round}.first
|
new_match = @matches.select { |m| m.bracket_position_number == @next_match_position_number.ceil && m.weight_id == @wrestler.weight_id && m.round > @last_match.round && m.bracket_position == "Quarter" }.sort_by(&:round).first
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
elsif @last_match.bracket_position == "Conso Round of 8"
|
elsif @last_match.bracket_position == "Conso Round of 8"
|
||||||
new_match = Match.where("bracket_position_number = ? and weight_id = ? and round > ? and bracket_position = ?", @last_match.bracket_position_number,@wrestler.weight_id, @last_match.round, "Conso Quarter").sort_by{|m| m.round}.first
|
new_match = @matches.select { |m| m.bracket_position_number == @last_match.bracket_position_number && m.weight_id == @wrestler.weight_id && m.round > @last_match.round && m.bracket_position == "Conso Quarter" }.sort_by(&:round).first
|
||||||
update_new_match(new_match, get_wrestler_number)
|
update_new_match(new_match, get_wrestler_number)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_new_match(match, wrestler_number)
|
def update_new_match(match, wrestler_number)
|
||||||
|
return unless match
|
||||||
if wrestler_number == 2 or (match.loser1_name and match.loser1_name.include? "Loser of")
|
if wrestler_number == 2 or (match.loser1_name and match.loser1_name.include? "Loser of")
|
||||||
match.w2 = @wrestler.id
|
match.w2 = @wrestler.id
|
||||||
match.save
|
|
||||||
elsif wrestler_number == 1
|
elsif wrestler_number == 1
|
||||||
match.w1 = @wrestler.id
|
match.w1 = @wrestler.id
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_consolation_bye
|
def update_consolation_bye
|
||||||
bout = @wrestler.last_match.bout_number
|
bout = @wrestler.last_match.bout_number
|
||||||
next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?","Loser of #{bout}","Loser of #{bout}",@wrestler.weight_id)
|
next_match = @matches.find { |m| m.weight_id == @wrestler.weight_id && (m.loser1_name == "Loser of #{bout}" || m.loser2_name == "Loser of #{bout}") }
|
||||||
if next_match.size > 0
|
if next_match
|
||||||
next_match.first.replace_loser_name_with_bye("Loser of #{bout}")
|
replace_loser_name_with_bye(next_match, "Loser of #{bout}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -74,27 +77,18 @@ class ModifiedDoubleEliminationAdvance
|
|||||||
|
|
||||||
def losers_bracket_advancement
|
def losers_bracket_advancement
|
||||||
bout = @last_match.bout_number
|
bout = @last_match.bout_number
|
||||||
next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?", "Loser of #{bout}", "Loser of #{bout}", @wrestler.weight_id).first
|
next_match = @matches.find { |m| m.weight_id == @wrestler.weight_id && (m.loser1_name == "Loser of #{bout}" || m.loser2_name == "Loser of #{bout}") }
|
||||||
|
|
||||||
if next_match.present?
|
if next_match.present?
|
||||||
next_match.replace_loser_name_with_wrestler(@wrestler, "Loser of #{bout}")
|
replace_loser_name_with_wrestler(next_match, @wrestler, "Loser of #{bout}")
|
||||||
next_match.reload
|
|
||||||
|
|
||||||
if next_match.loser1_name == "BYE" || next_match.loser2_name == "BYE"
|
if next_match.loser1_name == "BYE" || next_match.loser2_name == "BYE"
|
||||||
next_match.winner_id = @wrestler.id
|
next_match.winner_id = @wrestler.id
|
||||||
next_match.win_type = "BYE"
|
next_match.win_type = "BYE"
|
||||||
next_match.score = ""
|
next_match.score = ""
|
||||||
next_match.finished = 1
|
next_match.finished = 1
|
||||||
# puts "Before save: winner_id=#{next_match.winner_id}"
|
next_match.finished_at = Time.current
|
||||||
|
@matches_to_advance << next_match
|
||||||
# if next_match.save
|
|
||||||
# puts "Save successful: winner_id=#{next_match.reload.winner_id}"
|
|
||||||
# else
|
|
||||||
# puts "Save failed: #{next_match.errors.full_messages}"
|
|
||||||
# end
|
|
||||||
next_match.save
|
|
||||||
|
|
||||||
next_match.advance_wrestlers
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -102,43 +96,53 @@ class ModifiedDoubleEliminationAdvance
|
|||||||
|
|
||||||
def advance_double_byes
|
def advance_double_byes
|
||||||
weight = @wrestler.weight
|
weight = @wrestler.weight
|
||||||
weight.matches.select{|m| m.loser1_name == "BYE" and m.loser2_name == "BYE" and m.finished != 1}.each do |match|
|
@matches.select{|m| m.weight_id == weight.id && m.loser1_name == "BYE" and m.loser2_name == "BYE" and m.finished != 1}.each do |match|
|
||||||
match.finished = 1
|
match.finished = 1
|
||||||
|
match.finished_at = Time.current
|
||||||
match.score = ""
|
match.score = ""
|
||||||
match.win_type = "BYE"
|
match.win_type = "BYE"
|
||||||
next_match_position_number = (match.bracket_position_number / 2.0).ceil
|
next_match_position_number = (match.bracket_position_number / 2.0).ceil
|
||||||
after_matches = weight.matches.select{|m| m.round > match.round and m.is_consolation_match == match.is_consolation_match }.sort_by{|m| m.round}
|
after_matches = @matches.select{|m| m.weight_id == weight.id && m.round > match.round and m.is_consolation_match == match.is_consolation_match }.sort_by{|m| m.round}
|
||||||
next_matches = weight.matches.select{|m| m.round == after_matches.first.round and m.is_consolation_match == match.is_consolation_match }
|
next if after_matches.empty?
|
||||||
this_round_matches = weight.matches.select{|m| m.round == match.round and m.is_consolation_match == match.is_consolation_match }
|
next_matches = @matches.select{|m| m.weight_id == weight.id && m.round == after_matches.first.round and m.is_consolation_match == match.is_consolation_match }
|
||||||
|
this_round_matches = @matches.select{|m| m.weight_id == weight.id && m.round == match.round and m.is_consolation_match == match.is_consolation_match }
|
||||||
|
next_match = nil
|
||||||
|
|
||||||
if next_matches.size == this_round_matches.size
|
if next_matches.size == this_round_matches.size
|
||||||
next_match = next_matches.select{|m| m.bracket_position_number == match.bracket_position_number}.first
|
next_match = next_matches.select{|m| m.bracket_position_number == match.bracket_position_number}.first
|
||||||
next_match.loser2_name = "BYE"
|
next_match.loser2_name = "BYE" if next_match
|
||||||
next_match.save
|
|
||||||
elsif next_matches.size < this_round_matches.size and next_matches.size > 0
|
elsif next_matches.size < this_round_matches.size and next_matches.size > 0
|
||||||
next_match = next_matches.select{|m| m.bracket_position_number == next_match_position_number}.first
|
next_match = next_matches.select{|m| m.bracket_position_number == next_match_position_number}.first
|
||||||
if next_match.bracket_position_number == next_match_position_number
|
if next_match && next_match.bracket_position_number == next_match_position_number
|
||||||
next_match.loser2_name = "BYE"
|
next_match.loser2_name = "BYE"
|
||||||
else
|
elsif next_match
|
||||||
next_match.loser1_name = "BYE"
|
next_match.loser1_name = "BYE"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
next_match.save
|
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_bye_for_placement
|
def set_bye_for_placement
|
||||||
weight = @wrestler.weight
|
weight = @wrestler.weight
|
||||||
seventh_finals = weight.matches.select{|match| match.bracket_position == '7/8'}.first
|
seventh_finals = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == '7/8'}.first
|
||||||
if seventh_finals
|
if seventh_finals
|
||||||
conso_quarter = weight.matches.select{|match| match.bracket_position == 'Conso Semis'}
|
conso_quarter = @matches.select{|match| match.weight_id == weight.id && match.bracket_position == 'Conso Semis'}
|
||||||
conso_quarter.each do |match|
|
conso_quarter.each do |match|
|
||||||
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
if match.loser1_name == "BYE" or match.loser2_name == "BYE"
|
||||||
seventh_finals.replace_loser_name_with_bye("Loser of #{match.bout_number}")
|
replace_loser_name_with_bye(seventh_finals, "Loser of #{match.bout_number}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replace_loser_name_with_wrestler(match, wrestler, loser_name)
|
||||||
|
match.w1 = wrestler.id if match.loser1_name == loser_name
|
||||||
|
match.w2 = wrestler.id if match.loser2_name == loser_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def replace_loser_name_with_bye(match, loser_name)
|
||||||
|
match.loser1_name = "BYE" if match.loser1_name == loser_name
|
||||||
|
match.loser2_name = "BYE" if match.loser2_name == loser_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
class PoolAdvance
|
class PoolAdvance
|
||||||
|
|
||||||
def initialize(wrestler)
|
attr_reader :matches_to_advance
|
||||||
|
|
||||||
|
def initialize(wrestler, last_match, matches: nil, wrestlers: nil)
|
||||||
@wrestler = wrestler
|
@wrestler = wrestler
|
||||||
@last_match = @wrestler.last_match
|
@last_match = last_match
|
||||||
|
@matches = matches || @wrestler.weight.matches.to_a
|
||||||
|
@wrestlers = wrestlers || @wrestler.weight.wrestlers.to_a
|
||||||
|
@matches_to_advance = []
|
||||||
end
|
end
|
||||||
|
|
||||||
def advanceWrestler
|
def advanceWrestler
|
||||||
@@ -17,15 +22,15 @@ class PoolAdvance
|
|||||||
def poolToBracketAdvancment
|
def poolToBracketAdvancment
|
||||||
pool = @wrestler.pool
|
pool = @wrestler.pool
|
||||||
# This has to always run because the last match in a pool might not be a pool winner or runner up
|
# This has to always run because the last match in a pool might not be a pool winner or runner up
|
||||||
winner = Wrestler.where("weight_id = ? and pool_placement = 1 and pool = ?",@wrestler.weight.id, pool).first
|
winner = @wrestlers.find { |w| w.weight_id == @wrestler.weight.id && w.pool_placement == 1 && w.pool == pool }
|
||||||
runner_up = Wrestler.where("weight_id = ? and pool_placement = 2 and pool = ?",@wrestler.weight.id, pool).first
|
runner_up = @wrestlers.find { |w| w.weight_id == @wrestler.weight.id && w.pool_placement == 2 && w.pool == pool }
|
||||||
if runner_up
|
if runner_up
|
||||||
runner_up_match = Match.where("weight_id = ? and (loser1_name = ? or loser2_name = ?)",@wrestler.weight.id, "Runner Up Pool #{pool}", "Runner Up Pool #{pool}").first
|
runner_up_match = @matches.find { |m| m.weight_id == @wrestler.weight.id && (m.loser1_name == "Runner Up Pool #{pool}" || m.loser2_name == "Runner Up Pool #{pool}") }
|
||||||
runner_up_match.replace_loser_name_with_wrestler(runner_up,"Runner Up Pool #{pool}")
|
replace_loser_name_with_wrestler(runner_up_match, runner_up, "Runner Up Pool #{pool}") if runner_up_match
|
||||||
end
|
end
|
||||||
if winner
|
if winner
|
||||||
winner_match = Match.where("weight_id = ? and (loser1_name = ? or loser2_name = ?)",@wrestler.weight.id, "Winner Pool #{pool}", "Winner Pool #{pool}").first
|
winner_match = @matches.find { |m| m.weight_id == @wrestler.weight.id && (m.loser1_name == "Winner Pool #{pool}" || m.loser2_name == "Winner Pool #{pool}") }
|
||||||
winner_match.replace_loser_name_with_wrestler(winner,"Winner Pool #{pool}")
|
replace_loser_name_with_wrestler(winner_match, winner, "Winner Pool #{pool}") if winner_match
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -45,36 +50,40 @@ class PoolAdvance
|
|||||||
|
|
||||||
def winner_advance
|
def winner_advance
|
||||||
if @wrestler.last_match.bracket_position == "Quarter"
|
if @wrestler.last_match.bracket_position == "Quarter"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","Semis",@wrestler.next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "Semis" && m.bracket_position_number == @wrestler.next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
updateNewMatch(new_match)
|
updateNewMatch(new_match)
|
||||||
end
|
end
|
||||||
if @wrestler.last_match.bracket_position == "Semis"
|
if @wrestler.last_match.bracket_position == "Semis"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","1/2",@wrestler.next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "1/2" && m.bracket_position_number == @wrestler.next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
updateNewMatch(new_match)
|
updateNewMatch(new_match)
|
||||||
end
|
end
|
||||||
if @wrestler.last_match.bracket_position == "Conso Semis"
|
if @wrestler.last_match.bracket_position == "Conso Semis"
|
||||||
new_match = Match.where("bracket_position = ? AND bracket_position_number = ? AND weight_id = ?","5/6",@wrestler.next_match_position_number.ceil,@wrestler.weight_id).first
|
new_match = @matches.find { |m| m.bracket_position == "5/6" && m.bracket_position_number == @wrestler.next_match_position_number.ceil && m.weight_id == @wrestler.weight_id }
|
||||||
updateNewMatch(new_match)
|
updateNewMatch(new_match)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def updateNewMatch(match)
|
def updateNewMatch(match)
|
||||||
|
return unless match
|
||||||
if @wrestler.next_match_position_number == @wrestler.next_match_position_number.ceil
|
if @wrestler.next_match_position_number == @wrestler.next_match_position_number.ceil
|
||||||
match.w2 = @wrestler.id
|
match.w2 = @wrestler.id
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
if @wrestler.next_match_position_number != @wrestler.next_match_position_number.ceil
|
if @wrestler.next_match_position_number != @wrestler.next_match_position_number.ceil
|
||||||
match.w1 = @wrestler.id
|
match.w1 = @wrestler.id
|
||||||
match.save
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def loser_advance
|
def loser_advance
|
||||||
bout = @wrestler.last_match.bout_number
|
bout = @wrestler.last_match.bout_number
|
||||||
next_match = Match.where("(loser1_name = ? OR loser2_name = ?) AND weight_id = ?","Loser of #{bout}","Loser of #{bout}",@wrestler.weight_id)
|
next_match = @matches.find { |m| m.weight_id == @wrestler.weight_id && (m.loser1_name == "Loser of #{bout}" || m.loser2_name == "Loser of #{bout}") }
|
||||||
if next_match.size > 0
|
if next_match
|
||||||
next_match.first.replace_loser_name_with_wrestler(@wrestler,"Loser of #{bout}")
|
replace_loser_name_with_wrestler(next_match, @wrestler, "Loser of #{bout}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replace_loser_name_with_wrestler(match, wrestler, loser_name)
|
||||||
|
match.w1 = wrestler.id if match.loser1_name == loser_name
|
||||||
|
match.w2 = wrestler.id if match.loser2_name == loser_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ class PoolOrder
|
|||||||
end
|
end
|
||||||
|
|
||||||
def getPoolOrder
|
def getPoolOrder
|
||||||
# clear caching for weight for bracket page
|
|
||||||
@wrestlers.first.weight.touch
|
|
||||||
setOriginalPoints
|
setOriginalPoints
|
||||||
while checkForTies(@wrestlers) == true
|
while checkForTies(@wrestlers) == true
|
||||||
getWrestlersOrderByPoolAdvancePoints.each do |wrestler|
|
getWrestlersOrderByPoolAdvancePoints.each do |wrestler|
|
||||||
@@ -18,7 +16,6 @@ class PoolOrder
|
|||||||
getWrestlersOrderByPoolAdvancePoints.each_with_index do |wrestler, index|
|
getWrestlersOrderByPoolAdvancePoints.each_with_index do |wrestler, index|
|
||||||
placement = index + 1
|
placement = index + 1
|
||||||
wrestler.pool_placement = placement
|
wrestler.pool_placement = placement
|
||||||
wrestler.save
|
|
||||||
end
|
end
|
||||||
@wrestlers.sort_by{|w| w.poolAdvancePoints}.reverse!
|
@wrestlers.sort_by{|w| w.poolAdvancePoints}.reverse!
|
||||||
end
|
end
|
||||||
@@ -29,7 +26,6 @@ class PoolOrder
|
|||||||
|
|
||||||
def setOriginalPoints
|
def setOriginalPoints
|
||||||
@wrestlers.each do |w|
|
@wrestlers.each do |w|
|
||||||
matches = w.reload.all_matches
|
|
||||||
w.pool_placement_tiebreaker = nil
|
w.pool_placement_tiebreaker = nil
|
||||||
w.pool_placement = nil
|
w.pool_placement = nil
|
||||||
w.poolAdvancePoints = w.pool_wins.size
|
w.poolAdvancePoints = w.pool_wins.size
|
||||||
|
|||||||
55
app/services/school_services/calculate_school_score.rb
Normal file
55
app/services/school_services/calculate_school_score.rb
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
class CalculateSchoolScore
|
||||||
|
def initialize(school)
|
||||||
|
@school = school
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate
|
||||||
|
school = preload_school_context
|
||||||
|
score = calculate_score_value(school)
|
||||||
|
persist_school_score(school.id, score)
|
||||||
|
score
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate_value
|
||||||
|
school = preload_school_context
|
||||||
|
calculate_score_value(school)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def preload_school_context
|
||||||
|
School
|
||||||
|
.includes(
|
||||||
|
:deductedPoints,
|
||||||
|
wrestlers: [
|
||||||
|
:deductedPoints,
|
||||||
|
{ matches_as_w1: :winner },
|
||||||
|
{ matches_as_w2: :winner },
|
||||||
|
{ weight: [:matches, { tournament: { weights: :wrestlers } }] }
|
||||||
|
]
|
||||||
|
)
|
||||||
|
.find(@school.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate_score_value(school)
|
||||||
|
total_points_scored_by_wrestlers(school) - total_points_deducted(school)
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_points_scored_by_wrestlers(school)
|
||||||
|
school.wrestlers.sum { |wrestler| CalculateWrestlerTeamScore.new(wrestler).totalScore }
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_points_deducted(school)
|
||||||
|
school.deductedPoints.sum(&:points)
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_school_score(school_id, score)
|
||||||
|
School.upsert_all([
|
||||||
|
{
|
||||||
|
id: school_id,
|
||||||
|
score: score,
|
||||||
|
updated_at: Time.current
|
||||||
|
}
|
||||||
|
])
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,33 +3,30 @@ class DoubleEliminationGenerateLoserNames
|
|||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
end
|
end
|
||||||
|
|
||||||
# Entry point: assign loser placeholders and advance any byes
|
# Compatibility wrapper. Returns transformed rows and does not persist.
|
||||||
def assign_loser_names
|
def assign_loser_names(match_rows = nil)
|
||||||
|
rows = match_rows || @tournament.matches.where(tournament_id: @tournament.id).map { |m| m.attributes.symbolize_keys }
|
||||||
@tournament.weights.each do |weight|
|
@tournament.weights.each do |weight|
|
||||||
# only assign loser names if there's conso matches to be had
|
next unless weight.calculate_bracket_size > 2
|
||||||
if weight.calculate_bracket_size > 2
|
|
||||||
assign_loser_names_for_weight(weight)
|
assign_loser_names_in_memory(weight, rows)
|
||||||
advance_bye_matches_championship(weight)
|
assign_bye_outcomes_in_memory(weight, rows)
|
||||||
advance_bye_matches_consolation(weight)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def assign_loser_names_in_memory(weight, match_rows)
|
||||||
|
|
||||||
# Assign loser names for a single weight bracket
|
|
||||||
def assign_loser_names_for_weight(weight)
|
|
||||||
bracket_size = weight.calculate_bracket_size
|
bracket_size = weight.calculate_bracket_size
|
||||||
matches = weight.matches.reload
|
return if bracket_size <= 2
|
||||||
num_placers = @tournament.number_of_placers
|
|
||||||
|
rows = match_rows.select { |row| row[:weight_id] == weight.id }
|
||||||
|
num_placers = @tournament.number_of_placers
|
||||||
|
|
||||||
# Build dynamic round definitions
|
|
||||||
champ_rounds = dynamic_championship_rounds(bracket_size)
|
champ_rounds = dynamic_championship_rounds(bracket_size)
|
||||||
conso_rounds = dynamic_consolation_rounds(bracket_size)
|
conso_rounds = dynamic_consolation_rounds(bracket_size)
|
||||||
first_round = { bracket_position: first_round_label(bracket_size) }
|
first_round = { bracket_position: first_round_label(bracket_size) }
|
||||||
champ_full = [first_round] + champ_rounds
|
champ_full = [first_round] + champ_rounds
|
||||||
|
|
||||||
# Map championship losers into consolation slots
|
|
||||||
mappings = []
|
mappings = []
|
||||||
champ_full[0...-1].each_with_index do |champ_info, i|
|
champ_full[0...-1].each_with_index do |champ_info, i|
|
||||||
map_idx = i.zero? ? 0 : (2 * i - 1)
|
map_idx = i.zero? ? 0 : (2 * i - 1)
|
||||||
@@ -37,128 +34,109 @@ class DoubleEliminationGenerateLoserNames
|
|||||||
|
|
||||||
mappings << {
|
mappings << {
|
||||||
championship_bracket_position: champ_info[:bracket_position],
|
championship_bracket_position: champ_info[:bracket_position],
|
||||||
consolation_bracket_position: conso_rounds[map_idx][:bracket_position],
|
consolation_bracket_position: conso_rounds[map_idx][:bracket_position],
|
||||||
both_wrestlers: i.zero?,
|
both_wrestlers: i.zero?,
|
||||||
champ_round_index: i
|
champ_round_index: i
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Apply loser-name mappings
|
|
||||||
mappings.each do |map|
|
mappings.each do |map|
|
||||||
champ = matches.select { |m| m.bracket_position == map[:championship_bracket_position] }
|
champ = rows.select { |r| r[:bracket_position] == map[:championship_bracket_position] }
|
||||||
.sort_by(&:bracket_position_number)
|
.sort_by { |r| r[:bracket_position_number] }
|
||||||
conso = matches.select { |m| m.bracket_position == map[:consolation_bracket_position] }
|
conso = rows.select { |r| r[:bracket_position] == map[:consolation_bracket_position] }
|
||||||
.sort_by(&:bracket_position_number)
|
.sort_by { |r| r[:bracket_position_number] }
|
||||||
|
conso.reverse! if map[:champ_round_index].odd?
|
||||||
current_champ_round_index = map[:champ_round_index]
|
|
||||||
if current_champ_round_index.odd?
|
|
||||||
conso.reverse!
|
|
||||||
end
|
|
||||||
|
|
||||||
idx = 0
|
idx = 0
|
||||||
# Determine if this mapping is for losers from the first championship round
|
is_first_feed = map[:champ_round_index].zero?
|
||||||
is_first_champ_round_feed = map[:champ_round_index].zero?
|
|
||||||
|
|
||||||
conso.each do |cm|
|
conso.each do |cm|
|
||||||
champ_match1 = champ[idx]
|
champ_match1 = champ[idx]
|
||||||
if champ_match1
|
if champ_match1
|
||||||
if is_first_champ_round_feed && ((champ_match1.w1 && champ_match1.w2.nil?) || (champ_match1.w1.nil? && champ_match1.w2))
|
if is_first_feed && single_competitor_match_row?(champ_match1)
|
||||||
cm.loser1_name = "BYE"
|
cm[:loser1_name] = "BYE"
|
||||||
else
|
else
|
||||||
cm.loser1_name = "Loser of #{champ_match1.bout_number}"
|
cm[:loser1_name] = "Loser of #{champ_match1[:bout_number]}"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cm.loser1_name = nil # Should not happen if bracket generation is correct
|
cm[:loser1_name] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if map[:both_wrestlers] # This is true only if is_first_champ_round_feed
|
if map[:both_wrestlers]
|
||||||
idx += 1 # Increment for the second championship match
|
idx += 1
|
||||||
champ_match2 = champ[idx]
|
champ_match2 = champ[idx]
|
||||||
if champ_match2
|
if champ_match2
|
||||||
# BYE check is only relevant for the first championship round feed
|
if is_first_feed && single_competitor_match_row?(champ_match2)
|
||||||
if is_first_champ_round_feed && ((champ_match2.w1 && champ_match2.w2.nil?) || (champ_match2.w1.nil? && champ_match2.w2))
|
cm[:loser2_name] = "BYE"
|
||||||
cm.loser2_name = "BYE"
|
|
||||||
else
|
else
|
||||||
cm.loser2_name = "Loser of #{champ_match2.bout_number}"
|
cm[:loser2_name] = "Loser of #{champ_match2[:bout_number]}"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cm.loser2_name = nil # Should not happen
|
cm[:loser2_name] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
idx += 1 # Increment for the next consolation match or next pair from championship
|
idx += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 5th/6th place
|
|
||||||
if bracket_size >= 5 && num_placers >= 6 && weight.wrestlers.size > 4
|
if bracket_size >= 5 && num_placers >= 6 && weight.wrestlers.size > 4
|
||||||
conso_semis = matches.select { |m| m.bracket_position == "Conso Semis" }
|
conso_semis = rows.select { |r| r[:bracket_position] == "Conso Semis" }.sort_by { |r| r[:bracket_position_number] }
|
||||||
.sort_by(&:bracket_position_number)
|
m56 = rows.find { |r| r[:bracket_position] == "5/6" }
|
||||||
if conso_semis.size >= 2
|
if conso_semis.size >= 2 && m56
|
||||||
m56 = matches.find { |m| m.bracket_position == "5/6" }
|
m56[:loser1_name] = "Loser of #{conso_semis[0][:bout_number]}"
|
||||||
m56.loser1_name = "Loser of #{conso_semis[0].bout_number}"
|
m56[:loser2_name] = "Loser of #{conso_semis[1][:bout_number]}"
|
||||||
m56.loser2_name = "Loser of #{conso_semis[1].bout_number}" if m56
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 7th/8th place
|
|
||||||
if bracket_size >= 7 && num_placers >= 8 && weight.wrestlers.size > 6
|
if bracket_size >= 7 && num_placers >= 8 && weight.wrestlers.size > 6
|
||||||
conso_quarters = matches.select { |m| m.bracket_position == "Conso Quarter" }
|
conso_quarters = rows.select { |r| r[:bracket_position] == "Conso Quarter" }.sort_by { |r| r[:bracket_position_number] }
|
||||||
.sort_by(&:bracket_position_number)
|
m78 = rows.find { |r| r[:bracket_position] == "7/8" }
|
||||||
if conso_quarters.size >= 2
|
if conso_quarters.size >= 2 && m78
|
||||||
m78 = matches.find { |m| m.bracket_position == "7/8" }
|
m78[:loser1_name] = "Loser of #{conso_quarters[0][:bout_number]}"
|
||||||
m78.loser1_name = "Loser of #{conso_quarters[0].bout_number}"
|
m78[:loser2_name] = "Loser of #{conso_quarters[1][:bout_number]}"
|
||||||
m78.loser2_name = "Loser of #{conso_quarters[1].bout_number}" if m78
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
matches.each(&:save!)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Advance first-round byes in championship bracket
|
def assign_bye_outcomes_in_memory(weight, match_rows)
|
||||||
def advance_bye_matches_championship(weight)
|
|
||||||
matches = weight.matches.reload
|
|
||||||
first_round = matches.map(&:round).min
|
|
||||||
matches.select { |m| m.round == first_round }
|
|
||||||
.sort_by(&:bracket_position_number)
|
|
||||||
.each { |m| handle_bye(m) }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Advance first-round byes in consolation bracket
|
|
||||||
def advance_bye_matches_consolation(weight)
|
|
||||||
matches = weight.matches.reload
|
|
||||||
bracket_size = weight.calculate_bracket_size
|
bracket_size = weight.calculate_bracket_size
|
||||||
first_conso = dynamic_consolation_rounds(bracket_size).first
|
return if bracket_size <= 2
|
||||||
|
|
||||||
matches.select { |m| m.round == first_conso[:round] && m.bracket_position == first_conso[:bracket_position] }
|
rows = match_rows.select { |r| r[:weight_id] == weight.id }
|
||||||
.sort_by(&:bracket_position_number)
|
first_round = rows.map { |r| r[:round] }.compact.min
|
||||||
.each { |m| handle_bye(m) }
|
rows.select { |r| r[:round] == first_round }.each { |row| apply_bye_to_row(row) }
|
||||||
end
|
|
||||||
|
|
||||||
# Mark bye match, set finished, and advance
|
first_conso = dynamic_consolation_rounds(bracket_size).first
|
||||||
def handle_bye(match)
|
if first_conso
|
||||||
if [match.w1, match.w2].compact.size == 1
|
rows.select { |r| r[:round] == first_conso[:round] && r[:bracket_position] == first_conso[:bracket_position] }
|
||||||
match.finished = 1
|
.each { |row| apply_bye_to_row(row) }
|
||||||
match.win_type = 'BYE'
|
|
||||||
if match.w1
|
|
||||||
match.winner_id = match.w1
|
|
||||||
match.loser2_name = 'BYE'
|
|
||||||
else
|
|
||||||
match.winner_id = match.w2
|
|
||||||
match.loser1_name = 'BYE'
|
|
||||||
end
|
|
||||||
match.score = ''
|
|
||||||
match.save!
|
|
||||||
match.advance_wrestlers
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helpers for dynamic bracket labels
|
def apply_bye_to_row(row)
|
||||||
|
return unless single_competitor_match_row?(row)
|
||||||
|
|
||||||
|
row[:finished] = 1
|
||||||
|
row[:win_type] = "BYE"
|
||||||
|
if row[:w1]
|
||||||
|
row[:winner_id] = row[:w1]
|
||||||
|
row[:loser2_name] = "BYE"
|
||||||
|
else
|
||||||
|
row[:winner_id] = row[:w2]
|
||||||
|
row[:loser1_name] = "BYE"
|
||||||
|
end
|
||||||
|
row[:score] = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
def single_competitor_match_row?(row)
|
||||||
|
[row[:w1], row[:w2]].compact.size == 1
|
||||||
|
end
|
||||||
|
|
||||||
def first_round_label(size)
|
def first_round_label(size)
|
||||||
case size
|
case size
|
||||||
when 2 then 'Final'
|
when 2 then "Final"
|
||||||
when 4 then 'Semis'
|
when 4 then "Semis"
|
||||||
when 8 then 'Quarter'
|
when 8 then "Quarter"
|
||||||
else "Bracket Round of #{size}"
|
else "Bracket Round of #{size}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -173,36 +151,36 @@ class DoubleEliminationGenerateLoserNames
|
|||||||
def dynamic_consolation_rounds(size)
|
def dynamic_consolation_rounds(size)
|
||||||
total_log2 = Math.log2(size).to_i
|
total_log2 = Math.log2(size).to_i
|
||||||
return [] if total_log2 <= 1
|
return [] if total_log2 <= 1
|
||||||
|
|
||||||
max_j_val = (2 * (total_log2 - 1) - 1)
|
max_j_val = (2 * (total_log2 - 1) - 1)
|
||||||
(1..max_j_val).map do |j|
|
(1..max_j_val).map do |j|
|
||||||
current_participants = size / (2**((j.to_f / 2).ceil))
|
current_participants = size / (2**((j.to_f / 2).ceil))
|
||||||
{
|
{
|
||||||
bracket_position: consolation_label(current_participants, j, size),
|
bracket_position: consolation_label(current_participants, j, size),
|
||||||
round: j
|
round: j
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def bracket_label(participants)
|
def bracket_label(participants)
|
||||||
case participants
|
case participants
|
||||||
when 2 then '1/2'
|
when 2 then "1/2"
|
||||||
when 4 then 'Semis'
|
when 4 then "Semis"
|
||||||
when 8 then 'Quarter'
|
when 8 then "Quarter"
|
||||||
else "Bracket Round of #{participants}"
|
else "Bracket Round of #{participants}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def consolation_label(participants, j, bracket_size)
|
def consolation_label(participants, j, bracket_size)
|
||||||
max_j_for_bracket = (2 * (Math.log2(bracket_size).to_i - 1) - 1)
|
max_j_for_bracket = (2 * (Math.log2(bracket_size).to_i - 1) - 1)
|
||||||
|
|
||||||
if participants == 2 && j == max_j_for_bracket
|
if participants == 2 && j == max_j_for_bracket
|
||||||
return '3/4'
|
"3/4"
|
||||||
elsif participants == 4
|
elsif participants == 4
|
||||||
return j.odd? ? 'Conso Quarter' : 'Conso Semis'
|
j.odd? ? "Conso Quarter" : "Conso Semis"
|
||||||
else
|
else
|
||||||
suffix = j.odd? ? ".1" : ".2"
|
suffix = j.odd? ? ".1" : ".2"
|
||||||
return "Conso Round of #{participants}#{suffix}"
|
"Conso Round of #{participants}#{suffix}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,29 +1,33 @@
|
|||||||
class DoubleEliminationMatchGeneration
|
class DoubleEliminationMatchGeneration
|
||||||
def initialize(tournament)
|
def initialize(tournament, weights: nil)
|
||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
|
@weights = weights
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_matches
|
def generate_matches
|
||||||
#
|
build_match_rows
|
||||||
# PHASE 1: Generate matches (with local round definitions).
|
end
|
||||||
#
|
|
||||||
@tournament.weights.each do |weight|
|
def build_match_rows
|
||||||
generate_matches_for_weight(weight)
|
rows_by_weight_id = {}
|
||||||
|
|
||||||
|
generation_weights.each do |weight|
|
||||||
|
rows_by_weight_id[weight.id] = generate_match_rows_for_weight(weight)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
align_rows_to_largest_bracket(rows_by_weight_id)
|
||||||
# PHASE 2: Align all rounds to match the largest bracket’s definitions.
|
rows_by_weight_id.values.flatten
|
||||||
#
|
|
||||||
align_all_rounds_to_largest_bracket
|
|
||||||
end
|
end
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# PHASE 1: Generate all matches for each bracket, using a single definition.
|
# PHASE 1: Generate all matches for each bracket, using a single definition.
|
||||||
###########################################################################
|
###########################################################################
|
||||||
def generate_matches_for_weight(weight)
|
def generate_match_rows_for_weight(weight)
|
||||||
bracket_size = weight.calculate_bracket_size
|
bracket_size = weight.calculate_bracket_size
|
||||||
bracket_info = define_bracket_matches(bracket_size)
|
bracket_info = define_bracket_matches(bracket_size)
|
||||||
return unless bracket_info
|
return [] unless bracket_info
|
||||||
|
|
||||||
|
rows = []
|
||||||
|
|
||||||
# 1) Round one matchups
|
# 1) Round one matchups
|
||||||
bracket_info[:round_one_matchups].each_with_index do |matchup, idx|
|
bracket_info[:round_one_matchups].each_with_index do |matchup, idx|
|
||||||
@@ -32,7 +36,7 @@ class DoubleEliminationMatchGeneration
|
|||||||
bracket_pos_number = idx + 1
|
bracket_pos_number = idx + 1
|
||||||
round_number = matchup[:round]
|
round_number = matchup[:round]
|
||||||
|
|
||||||
create_matchup_from_seed(
|
rows << create_matchup_from_seed(
|
||||||
seed1,
|
seed1,
|
||||||
seed2,
|
seed2,
|
||||||
bracket_position,
|
bracket_position,
|
||||||
@@ -49,7 +53,7 @@ class DoubleEliminationMatchGeneration
|
|||||||
round_number = round_info[:round]
|
round_number = round_info[:round]
|
||||||
|
|
||||||
matches_this_round.times do |i|
|
matches_this_round.times do |i|
|
||||||
create_matchup(
|
rows << create_matchup(
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
bracket_position,
|
bracket_position,
|
||||||
@@ -67,7 +71,7 @@ class DoubleEliminationMatchGeneration
|
|||||||
round_number = round_info[:round]
|
round_number = round_info[:round]
|
||||||
|
|
||||||
matches_this_round.times do |i|
|
matches_this_round.times do |i|
|
||||||
create_matchup(
|
rows << create_matchup(
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
bracket_position,
|
bracket_position,
|
||||||
@@ -79,12 +83,14 @@ class DoubleEliminationMatchGeneration
|
|||||||
|
|
||||||
# 5/6, 7/8 placing logic
|
# 5/6, 7/8 placing logic
|
||||||
if weight.wrestlers.size >= 5 && @tournament.number_of_placers >= 6 && matches_this_round == 1
|
if weight.wrestlers.size >= 5 && @tournament.number_of_placers >= 6 && matches_this_round == 1
|
||||||
create_matchup(nil, nil, "5/6", 1, round_number, weight)
|
rows << create_matchup(nil, nil, "5/6", 1, round_number, weight)
|
||||||
end
|
end
|
||||||
if weight.wrestlers.size >= 7 && @tournament.number_of_placers >= 8 && matches_this_round == 1
|
if weight.wrestlers.size >= 7 && @tournament.number_of_placers >= 8 && matches_this_round == 1
|
||||||
create_matchup(nil, nil, "7/8", 1, round_number, weight)
|
rows << create_matchup(nil, nil, "7/8", 1, round_number, weight)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
# Single bracket definition dynamically generated for any power-of-two bracket size.
|
# Single bracket definition dynamically generated for any power-of-two bracket size.
|
||||||
@@ -173,18 +179,18 @@ class DoubleEliminationMatchGeneration
|
|||||||
###########################################################################
|
###########################################################################
|
||||||
# PHASE 2: Overwrite rounds in all smaller brackets to match the largest one.
|
# PHASE 2: Overwrite rounds in all smaller brackets to match the largest one.
|
||||||
###########################################################################
|
###########################################################################
|
||||||
def align_all_rounds_to_largest_bracket
|
def align_rows_to_largest_bracket(rows_by_weight_id)
|
||||||
largest_weight = @tournament.weights.max_by { |w| w.calculate_bracket_size }
|
largest_weight = generation_weights.max_by { |w| w.calculate_bracket_size }
|
||||||
return unless largest_weight
|
return unless largest_weight
|
||||||
|
|
||||||
position_to_round = {}
|
position_to_round = {}
|
||||||
largest_weight.tournament.matches.where(weight_id: largest_weight.id).each do |m|
|
rows_by_weight_id.fetch(largest_weight.id, []).each do |row|
|
||||||
position_to_round[m.bracket_position] ||= m.round
|
position_to_round[row[:bracket_position]] ||= row[:round]
|
||||||
end
|
end
|
||||||
|
|
||||||
@tournament.matches.find_each do |match|
|
rows_by_weight_id.each_value do |rows|
|
||||||
if position_to_round.key?(match.bracket_position)
|
rows.each do |row|
|
||||||
match.update(round: position_to_round[match.bracket_position])
|
row[:round] = position_to_round[row[:bracket_position]] if position_to_round.key?(row[:bracket_position])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -192,8 +198,12 @@ class DoubleEliminationMatchGeneration
|
|||||||
###########################################################################
|
###########################################################################
|
||||||
# Helper methods
|
# Helper methods
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
def generation_weights
|
||||||
|
@weights || @tournament.weights.to_a
|
||||||
|
end
|
||||||
|
|
||||||
def wrestler_with_seed(seed, weight)
|
def wrestler_with_seed(seed, weight)
|
||||||
Wrestler.where("weight_id = ? AND bracket_line = ?", weight.id, seed).first&.id
|
weight.wrestlers.find { |w| w.bracket_line == seed }&.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_matchup_from_seed(w1_seed, w2_seed, bracket_position, bracket_position_number, round, weight)
|
def create_matchup_from_seed(w1_seed, w2_seed, bracket_position, bracket_position_number, round, weight)
|
||||||
@@ -208,14 +218,15 @@ class DoubleEliminationMatchGeneration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_matchup(w1, w2, bracket_position, bracket_position_number, round, weight)
|
def create_matchup(w1, w2, bracket_position, bracket_position_number, round, weight)
|
||||||
weight.tournament.matches.create!(
|
{
|
||||||
w1: w1,
|
w1: w1,
|
||||||
w2: w2,
|
w2: w2,
|
||||||
|
tournament_id: weight.tournament_id,
|
||||||
weight_id: weight.id,
|
weight_id: weight.id,
|
||||||
round: round,
|
round: round,
|
||||||
bracket_position: bracket_position,
|
bracket_position: bracket_position,
|
||||||
bracket_position_number: bracket_position_number
|
bracket_position_number: bracket_position_number
|
||||||
)
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Calculates the sequence of seeds for the first round of a power-of-two bracket.
|
# Calculates the sequence of seeds for the first round of a power-of-two bracket.
|
||||||
|
|||||||
@@ -10,63 +10,183 @@ class GenerateTournamentMatches
|
|||||||
|
|
||||||
def generate_raw
|
def generate_raw
|
||||||
standardStartingActions
|
standardStartingActions
|
||||||
PoolToBracketMatchGeneration.new(@tournament).generatePoolToBracketMatches if @tournament.tournament_type == "Pool to bracket"
|
generation_context = preload_generation_context
|
||||||
ModifiedSixteenManMatchGeneration.new(@tournament).generate_matches if @tournament.tournament_type.include? "Modified 16 Man Double Elimination"
|
seed_wrestlers_in_memory(generation_context)
|
||||||
DoubleEliminationMatchGeneration.new(@tournament).generate_matches if @tournament.tournament_type.include? "Regular Double Elimination"
|
match_rows = build_match_rows(generation_context)
|
||||||
|
post_process_match_rows_in_memory(generation_context, match_rows)
|
||||||
|
persist_generation_rows(generation_context, match_rows)
|
||||||
postMatchCreationActions
|
postMatchCreationActions
|
||||||
PoolToBracketMatchGeneration.new(@tournament).assignLoserNames if @tournament.tournament_type == "Pool to bracket"
|
advance_bye_matches_after_insert
|
||||||
ModifiedSixteenManGenerateLoserNames.new(@tournament).assign_loser_names if @tournament.tournament_type.include? "Modified 16 Man Double Elimination"
|
|
||||||
DoubleEliminationGenerateLoserNames.new(@tournament).assign_loser_names if @tournament.tournament_type.include? "Regular Double Elimination"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def standardStartingActions
|
def standardStartingActions
|
||||||
@tournament.curently_generating_matches = 1
|
@tournament.curently_generating_matches = 1
|
||||||
@tournament.save
|
@tournament.save
|
||||||
WipeTournamentMatches.new(@tournament).setUpMatchGeneration
|
WipeTournamentMatches.new(@tournament).setUpMatchGeneration
|
||||||
TournamentSeeding.new(@tournament).set_seeds
|
end
|
||||||
|
|
||||||
|
def preload_generation_context
|
||||||
|
weights = @tournament.weights.includes(:wrestlers).order(:max).to_a
|
||||||
|
wrestlers = weights.flat_map(&:wrestlers)
|
||||||
|
{
|
||||||
|
weights: weights,
|
||||||
|
wrestlers: wrestlers,
|
||||||
|
wrestlers_by_weight_id: wrestlers.group_by(&:weight_id)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def seed_wrestlers_in_memory(generation_context)
|
||||||
|
TournamentSeeding.new(@tournament).set_seeds(weights: generation_context[:weights], persist: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_match_rows(generation_context)
|
||||||
|
return PoolToBracketMatchGeneration.new(
|
||||||
|
@tournament,
|
||||||
|
weights: generation_context[:weights],
|
||||||
|
wrestlers_by_weight_id: generation_context[:wrestlers_by_weight_id]
|
||||||
|
).generatePoolToBracketMatches if @tournament.tournament_type == "Pool to bracket"
|
||||||
|
|
||||||
|
return ModifiedSixteenManMatchGeneration.new(@tournament, weights: generation_context[:weights]).generate_matches if @tournament.tournament_type.include? "Modified 16 Man Double Elimination"
|
||||||
|
|
||||||
|
return DoubleEliminationMatchGeneration.new(@tournament, weights: generation_context[:weights]).generate_matches if @tournament.tournament_type.include? "Regular Double Elimination"
|
||||||
|
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_generation_rows(generation_context, match_rows)
|
||||||
|
persist_wrestlers(generation_context[:wrestlers])
|
||||||
|
persist_matches(match_rows)
|
||||||
|
end
|
||||||
|
|
||||||
|
def post_process_match_rows_in_memory(generation_context, match_rows)
|
||||||
|
move_finals_rows_to_last_round(match_rows) unless @tournament.tournament_type.include?("Regular Double Elimination")
|
||||||
|
assign_bouts_in_memory(match_rows, generation_context[:weights])
|
||||||
|
assign_loser_names_in_memory(generation_context, match_rows)
|
||||||
|
assign_bye_outcomes_in_memory(generation_context, match_rows)
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_wrestlers(wrestlers)
|
||||||
|
return if wrestlers.blank?
|
||||||
|
|
||||||
|
timestamp = Time.current
|
||||||
|
rows = wrestlers.map do |w|
|
||||||
|
{
|
||||||
|
id: w.id,
|
||||||
|
bracket_line: w.bracket_line,
|
||||||
|
pool: w.pool,
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
Wrestler.upsert_all(rows)
|
||||||
|
end
|
||||||
|
|
||||||
|
def persist_matches(match_rows)
|
||||||
|
return if match_rows.blank?
|
||||||
|
|
||||||
|
timestamp = Time.current
|
||||||
|
rows_with_timestamps = match_rows.map do |row|
|
||||||
|
row.to_h.symbolize_keys.merge(created_at: timestamp, updated_at: timestamp)
|
||||||
|
end
|
||||||
|
|
||||||
|
all_keys = rows_with_timestamps.flat_map(&:keys).uniq
|
||||||
|
normalized_rows = rows_with_timestamps.map do |row|
|
||||||
|
all_keys.each_with_object({}) { |key, normalized| normalized[key] = row[key] }
|
||||||
|
end
|
||||||
|
|
||||||
|
Match.insert_all!(normalized_rows)
|
||||||
end
|
end
|
||||||
|
|
||||||
def postMatchCreationActions
|
def postMatchCreationActions
|
||||||
moveFinalsMatchesToLastRound if ! @tournament.tournament_type.include? "Regular Double Elimination"
|
|
||||||
assignBouts
|
|
||||||
@tournament.reset_and_fill_bout_board
|
@tournament.reset_and_fill_bout_board
|
||||||
@tournament.curently_generating_matches = nil
|
@tournament.curently_generating_matches = nil
|
||||||
@tournament.save!
|
@tournament.save!
|
||||||
Tournament.broadcast_up_matches_board(@tournament.id)
|
Tournament.broadcast_up_matches_board(@tournament.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def move_finals_rows_to_last_round(match_rows)
|
||||||
|
finals_round = match_rows.map { |row| row[:round] }.compact.max
|
||||||
|
return unless finals_round
|
||||||
|
|
||||||
|
match_rows.each do |row|
|
||||||
|
row[:round] = finals_round if ["1/2", "3/4", "5/6", "7/8"].include?(row[:bracket_position])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_bouts_in_memory(match_rows, weights)
|
||||||
|
bout_counts = Hash.new(0)
|
||||||
|
weight_max_by_id = weights.each_with_object({}) { |w, memo| memo[w.id] = w.max }
|
||||||
|
|
||||||
|
match_rows
|
||||||
|
.sort_by { |row| [row[:round].to_i, weight_max_by_id[row[:weight_id]].to_f, row[:weight_id].to_i, row[:bracket_position_number].to_i] }
|
||||||
|
.each do |row|
|
||||||
|
round = row[:round].to_i
|
||||||
|
row[:bout_number] = round * 1000 + bout_counts[round]
|
||||||
|
bout_counts[round] += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_loser_names_in_memory(generation_context, match_rows)
|
||||||
|
if @tournament.tournament_type == "Pool to bracket"
|
||||||
|
service = PoolToBracketGenerateLoserNames.new(@tournament)
|
||||||
|
generation_context[:weights].each { |weight| service.assign_loser_names_in_memory(weight, match_rows) }
|
||||||
|
elsif @tournament.tournament_type.include?("Modified 16 Man Double Elimination")
|
||||||
|
service = ModifiedSixteenManGenerateLoserNames.new(@tournament)
|
||||||
|
generation_context[:weights].each { |weight| service.assign_loser_names_in_memory(weight, match_rows) }
|
||||||
|
elsif @tournament.tournament_type.include?("Regular Double Elimination")
|
||||||
|
service = DoubleEliminationGenerateLoserNames.new(@tournament)
|
||||||
|
generation_context[:weights].each { |weight| service.assign_loser_names_in_memory(weight, match_rows) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_bye_outcomes_in_memory(generation_context, match_rows)
|
||||||
|
if @tournament.tournament_type.include?("Modified 16 Man Double Elimination")
|
||||||
|
service = ModifiedSixteenManGenerateLoserNames.new(@tournament)
|
||||||
|
generation_context[:weights].each { |weight| service.assign_bye_outcomes_in_memory(weight, match_rows) }
|
||||||
|
elsif @tournament.tournament_type.include?("Regular Double Elimination")
|
||||||
|
service = DoubleEliminationGenerateLoserNames.new(@tournament)
|
||||||
|
generation_context[:weights].each { |weight| service.assign_bye_outcomes_in_memory(weight, match_rows) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def advance_bye_matches_after_insert
|
||||||
|
Match.where(tournament_id: @tournament.id, finished: 1, win_type: "BYE")
|
||||||
|
.where.not(winner_id: nil)
|
||||||
|
.find_each(&:advance_wrestlers)
|
||||||
|
end
|
||||||
|
|
||||||
def assignBouts
|
def assignBouts
|
||||||
bout_counts = Hash.new(0)
|
bout_counts = Hash.new(0)
|
||||||
@tournament.matches.reload
|
timestamp = Time.current
|
||||||
@tournament.matches.sort_by{|m| [m.round, m.weight_max]}.each do |m|
|
ordered_matches = Match.joins(:weight)
|
||||||
m.bout_number = m.round * 1000 + bout_counts[m.round]
|
.where(tournament_id: @tournament.id)
|
||||||
bout_counts[m.round] += 1
|
.order("matches.round ASC, weights.max ASC, matches.id ASC")
|
||||||
m.save!
|
.pluck("matches.id", "matches.round")
|
||||||
|
|
||||||
|
updates = []
|
||||||
|
ordered_matches.each do |match_id, round|
|
||||||
|
updates << {
|
||||||
|
id: match_id,
|
||||||
|
bout_number: round * 1000 + bout_counts[round],
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
|
bout_counts[round] += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Match.upsert_all(updates) if updates.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
def moveFinalsMatchesToLastRound
|
def moveFinalsMatchesToLastRound
|
||||||
finalsRound = @tournament.reload.total_rounds
|
finalsRound = @tournament.reload.total_rounds
|
||||||
finalsMatches = @tournament.matches.reload.select{|m| m.bracket_position == "1/2" || m.bracket_position == "3/4" || m.bracket_position == "5/6" || m.bracket_position == "7/8"}
|
@tournament.matches
|
||||||
finalsMatches. each do |m|
|
.where(bracket_position: ["1/2", "3/4", "5/6", "7/8"])
|
||||||
m.round = finalsRound
|
.update_all(round: finalsRound, updated_at: Time.current)
|
||||||
m.save
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def unAssignMats
|
def unAssignMats
|
||||||
matches = @tournament.matches.reload
|
@tournament.matches.update_all(mat_id: nil, updated_at: Time.current)
|
||||||
matches.each do |m|
|
|
||||||
m.mat_id = nil
|
|
||||||
m.save!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def unAssignBouts
|
def unAssignBouts
|
||||||
bout_counts = Hash.new(0)
|
@tournament.matches.update_all(bout_number: nil, updated_at: Time.current)
|
||||||
@tournament.matches.each do |m|
|
|
||||||
m.bout_number = nil
|
|
||||||
m.save!
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,95 +1,91 @@
|
|||||||
class ModifiedSixteenManGenerateLoserNames
|
class ModifiedSixteenManGenerateLoserNames
|
||||||
def initialize( tournament )
|
def initialize(tournament)
|
||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
# Compatibility wrapper. Returns transformed rows and does not persist.
|
||||||
|
def assign_loser_names(match_rows = nil)
|
||||||
|
rows = match_rows || @tournament.matches.where(tournament_id: @tournament.id).map { |m| m.attributes.symbolize_keys }
|
||||||
|
@tournament.weights.each do |weight|
|
||||||
|
assign_loser_names_in_memory(weight, rows)
|
||||||
|
assign_bye_outcomes_in_memory(weight, rows)
|
||||||
|
end
|
||||||
|
rows
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_loser_names_in_memory(weight, match_rows)
|
||||||
|
rows = match_rows.select { |row| row[:weight_id] == weight.id }
|
||||||
|
round_16 = rows.select { |r| r[:bracket_position] == "Bracket Round of 16" }
|
||||||
|
conso_8 = rows.select { |r| r[:bracket_position] == "Conso Round of 8" }.sort_by { |r| r[:bracket_position_number] }
|
||||||
|
|
||||||
|
conso_8.each do |row|
|
||||||
|
if row[:bracket_position_number] == 1
|
||||||
|
m1 = round_16.find { |m| m[:bracket_position_number] == 1 }
|
||||||
|
m2 = round_16.find { |m| m[:bracket_position_number] == 2 }
|
||||||
|
row[:loser1_name] = "Loser of #{m1[:bout_number]}" if m1
|
||||||
|
row[:loser2_name] = "Loser of #{m2[:bout_number]}" if m2
|
||||||
|
elsif row[:bracket_position_number] == 2
|
||||||
|
m3 = round_16.find { |m| m[:bracket_position_number] == 3 }
|
||||||
|
m4 = round_16.find { |m| m[:bracket_position_number] == 4 }
|
||||||
|
row[:loser1_name] = "Loser of #{m3[:bout_number]}" if m3
|
||||||
|
row[:loser2_name] = "Loser of #{m4[:bout_number]}" if m4
|
||||||
|
elsif row[:bracket_position_number] == 3
|
||||||
|
m5 = round_16.find { |m| m[:bracket_position_number] == 5 }
|
||||||
|
m6 = round_16.find { |m| m[:bracket_position_number] == 6 }
|
||||||
|
row[:loser1_name] = "Loser of #{m5[:bout_number]}" if m5
|
||||||
|
row[:loser2_name] = "Loser of #{m6[:bout_number]}" if m6
|
||||||
|
elsif row[:bracket_position_number] == 4
|
||||||
|
m7 = round_16.find { |m| m[:bracket_position_number] == 7 }
|
||||||
|
m8 = round_16.find { |m| m[:bracket_position_number] == 8 }
|
||||||
|
row[:loser1_name] = "Loser of #{m7[:bout_number]}" if m7
|
||||||
|
row[:loser2_name] = "Loser of #{m8[:bout_number]}" if m8
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_loser_names
|
quarters = rows.select { |r| r[:bracket_position] == "Quarter" }
|
||||||
matches_by_weight = nil
|
conso_quarters = rows.select { |r| r[:bracket_position] == "Conso Quarter" }.sort_by { |r| r[:bracket_position_number] }
|
||||||
@tournament.weights.each do |w|
|
conso_quarters.each do |row|
|
||||||
matches_by_weight = @tournament.matches.where(weight_id: w.id)
|
source = case row[:bracket_position_number]
|
||||||
conso_round_2(matches_by_weight)
|
when 1 then quarters.find { |q| q[:bracket_position_number] == 4 }
|
||||||
conso_round_3(matches_by_weight)
|
when 2 then quarters.find { |q| q[:bracket_position_number] == 3 }
|
||||||
third_fourth(matches_by_weight)
|
when 3 then quarters.find { |q| q[:bracket_position_number] == 2 }
|
||||||
seventh_eighth(matches_by_weight)
|
when 4 then quarters.find { |q| q[:bracket_position_number] == 1 }
|
||||||
save_matches(matches_by_weight)
|
end
|
||||||
matches_by_weight = @tournament.matches.where(weight_id: w.id).reload
|
row[:loser1_name] = "Loser of #{source[:bout_number]}" if source
|
||||||
advance_bye_matches_championship(matches_by_weight)
|
|
||||||
save_matches(matches_by_weight)
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def conso_round_2(matches)
|
semis = rows.select { |r| r[:bracket_position] == "Semis" }
|
||||||
matches.select{|m| m.bracket_position == "Conso Round of 8"}.sort_by{|m| m.bracket_position_number}.each do |match|
|
third_fourth = rows.find { |r| r[:bracket_position] == "3/4" }
|
||||||
if match.bracket_position_number == 1
|
if third_fourth
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 1 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
third_fourth[:loser1_name] = "Loser of #{semis.first[:bout_number]}" if semis.first
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position_number == 2 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
third_fourth[:loser2_name] = "Loser of #{semis.second[:bout_number]}" if semis.second
|
||||||
elsif match.bracket_position_number == 2
|
end
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 3 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position_number == 4 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
elsif match.bracket_position_number == 3
|
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 5 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position_number == 6 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
elsif match.bracket_position_number == 4
|
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 7 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position_number == 8 and m.bracket_position == "Bracket Round of 16"}.first.bout_number}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def conso_round_3(matches)
|
conso_semis = rows.select { |r| r[:bracket_position] == "Conso Semis" }
|
||||||
matches.select{|m| m.bracket_position == "Conso Quarter"}.sort_by{|m| m.bracket_position_number}.each do |match|
|
seventh_eighth = rows.find { |r| r[:bracket_position] == "7/8" }
|
||||||
if match.bracket_position_number == 1
|
if seventh_eighth
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 4 and m.bracket_position == "Quarter"}.first.bout_number}"
|
seventh_eighth[:loser1_name] = "Loser of #{conso_semis.first[:bout_number]}" if conso_semis.first
|
||||||
elsif match.bracket_position_number == 2
|
seventh_eighth[:loser2_name] = "Loser of #{conso_semis.second[:bout_number]}" if conso_semis.second
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 3 and m.bracket_position == "Quarter"}.first.bout_number}"
|
end
|
||||||
elsif match.bracket_position_number == 3
|
end
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 2 and m.bracket_position == "Quarter"}.first.bout_number}"
|
|
||||||
elsif match.bracket_position_number == 4
|
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position_number == 1 and m.bracket_position == "Quarter"}.first.bout_number}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def third_fourth(matches)
|
def assign_bye_outcomes_in_memory(weight, match_rows)
|
||||||
matches.select{|m| m.bracket_position == "3/4"}.sort_by{|m| m.bracket_position_number}.each do |match|
|
rows = match_rows.select { |r| r[:weight_id] == weight.id && r[:bracket_position] == "Bracket Round of 16" }
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position == "Semis"}.first.bout_number}"
|
rows.each { |row| apply_bye_to_row(row) }
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position == "Semis"}.second.bout_number}"
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def seventh_eighth(matches)
|
|
||||||
matches.select{|m| m.bracket_position == "7/8"}.sort_by{|m| m.bracket_position_number}.each do |match|
|
|
||||||
match.loser1_name = "Loser of #{matches.select{|m| m.bracket_position == "Conso Semis"}.first.bout_number}"
|
|
||||||
match.loser2_name = "Loser of #{matches.select{|m| m.bracket_position == "Conso Semis"}.second.bout_number}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def advance_bye_matches_championship(matches)
|
def apply_bye_to_row(row)
|
||||||
matches.select{|m| m.bracket_position == "Bracket Round of 16"}.sort_by{|m| m.bracket_position_number}.each do |match|
|
return unless [row[:w1], row[:w2]].compact.size == 1
|
||||||
if match.w1 == nil or match.w2 == nil
|
|
||||||
match.finished = 1
|
row[:finished] = 1
|
||||||
match.win_type = "BYE"
|
row[:win_type] = "BYE"
|
||||||
if match.w1 != nil
|
if row[:w1]
|
||||||
match.winner_id = match.w1
|
row[:winner_id] = row[:w1]
|
||||||
match.loser2_name = "BYE"
|
row[:loser2_name] = "BYE"
|
||||||
match.score = ""
|
else
|
||||||
match.save
|
row[:winner_id] = row[:w2]
|
||||||
match.advance_wrestlers
|
row[:loser1_name] = "BYE"
|
||||||
elsif match.w2 != nil
|
end
|
||||||
match.winner_id = match.w2
|
row[:score] = ""
|
||||||
match.loser1_name = "BYE"
|
end
|
||||||
match.score = ""
|
end
|
||||||
match.save
|
|
||||||
match.advance_wrestlers
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_matches(matches)
|
|
||||||
matches.each do |m|
|
|
||||||
m.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -1,70 +1,75 @@
|
|||||||
class ModifiedSixteenManMatchGeneration
|
class ModifiedSixteenManMatchGeneration
|
||||||
def initialize( tournament )
|
def initialize( tournament, weights: nil )
|
||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
@number_of_placers = @tournament.number_of_placers
|
@number_of_placers = @tournament.number_of_placers
|
||||||
|
@weights = weights
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_matches
|
def generate_matches
|
||||||
@tournament.weights.each do |weight|
|
rows = []
|
||||||
generate_matches_for_weight(weight)
|
generation_weights.each do |weight|
|
||||||
|
rows.concat(generate_match_rows_for_weight(weight))
|
||||||
end
|
end
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_matches_for_weight(weight)
|
def generate_match_rows_for_weight(weight)
|
||||||
round_one(weight)
|
rows = []
|
||||||
round_two(weight)
|
round_one(weight, rows)
|
||||||
round_three(weight)
|
round_two(weight, rows)
|
||||||
round_four(weight)
|
round_three(weight, rows)
|
||||||
round_five(weight)
|
round_four(weight, rows)
|
||||||
|
round_five(weight, rows)
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_one(weight)
|
def round_one(weight, rows)
|
||||||
create_matchup_from_seed(1,16, "Bracket Round of 16", 1, 1,weight)
|
rows << create_matchup_from_seed(1,16, "Bracket Round of 16", 1, 1,weight)
|
||||||
create_matchup_from_seed(8,9, "Bracket Round of 16", 2, 1,weight)
|
rows << create_matchup_from_seed(8,9, "Bracket Round of 16", 2, 1,weight)
|
||||||
create_matchup_from_seed(5,12, "Bracket Round of 16", 3, 1,weight)
|
rows << create_matchup_from_seed(5,12, "Bracket Round of 16", 3, 1,weight)
|
||||||
create_matchup_from_seed(4,14, "Bracket Round of 16", 4, 1,weight)
|
rows << create_matchup_from_seed(4,14, "Bracket Round of 16", 4, 1,weight)
|
||||||
create_matchup_from_seed(3,13, "Bracket Round of 16", 5, 1,weight)
|
rows << create_matchup_from_seed(3,13, "Bracket Round of 16", 5, 1,weight)
|
||||||
create_matchup_from_seed(6,11, "Bracket Round of 16", 6, 1,weight)
|
rows << create_matchup_from_seed(6,11, "Bracket Round of 16", 6, 1,weight)
|
||||||
create_matchup_from_seed(7,10, "Bracket Round of 16", 7, 1,weight)
|
rows << create_matchup_from_seed(7,10, "Bracket Round of 16", 7, 1,weight)
|
||||||
create_matchup_from_seed(2,15, "Bracket Round of 16", 8, 1,weight)
|
rows << create_matchup_from_seed(2,15, "Bracket Round of 16", 8, 1,weight)
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_two(weight)
|
def round_two(weight, rows)
|
||||||
create_matchup(nil,nil,"Quarter",1,2,weight)
|
rows << create_matchup(nil,nil,"Quarter",1,2,weight)
|
||||||
create_matchup(nil,nil,"Quarter",2,2,weight)
|
rows << create_matchup(nil,nil,"Quarter",2,2,weight)
|
||||||
create_matchup(nil,nil,"Quarter",3,2,weight)
|
rows << create_matchup(nil,nil,"Quarter",3,2,weight)
|
||||||
create_matchup(nil,nil,"Quarter",4,2,weight)
|
rows << create_matchup(nil,nil,"Quarter",4,2,weight)
|
||||||
create_matchup(nil,nil,"Conso Round of 8",1,2,weight)
|
rows << create_matchup(nil,nil,"Conso Round of 8",1,2,weight)
|
||||||
create_matchup(nil,nil,"Conso Round of 8",2,2,weight)
|
rows << create_matchup(nil,nil,"Conso Round of 8",2,2,weight)
|
||||||
create_matchup(nil,nil,"Conso Round of 8",3,2,weight)
|
rows << create_matchup(nil,nil,"Conso Round of 8",3,2,weight)
|
||||||
create_matchup(nil,nil,"Conso Round of 8",4,2,weight)
|
rows << create_matchup(nil,nil,"Conso Round of 8",4,2,weight)
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_three(weight)
|
def round_three(weight, rows)
|
||||||
create_matchup(nil,nil,"Semis",1,3,weight)
|
rows << create_matchup(nil,nil,"Semis",1,3,weight)
|
||||||
create_matchup(nil,nil,"Semis",2,3,weight)
|
rows << create_matchup(nil,nil,"Semis",2,3,weight)
|
||||||
create_matchup(nil,nil,"Conso Quarter",1,3,weight)
|
rows << create_matchup(nil,nil,"Conso Quarter",1,3,weight)
|
||||||
create_matchup(nil,nil,"Conso Quarter",2,3,weight)
|
rows << create_matchup(nil,nil,"Conso Quarter",2,3,weight)
|
||||||
create_matchup(nil,nil,"Conso Quarter",3,3,weight)
|
rows << create_matchup(nil,nil,"Conso Quarter",3,3,weight)
|
||||||
create_matchup(nil,nil,"Conso Quarter",4,3,weight)
|
rows << create_matchup(nil,nil,"Conso Quarter",4,3,weight)
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_four(weight)
|
def round_four(weight, rows)
|
||||||
create_matchup(nil,nil,"Conso Semis",1,4,weight)
|
rows << create_matchup(nil,nil,"Conso Semis",1,4,weight)
|
||||||
create_matchup(nil,nil,"Conso Semis",2,4,weight)
|
rows << create_matchup(nil,nil,"Conso Semis",2,4,weight)
|
||||||
end
|
end
|
||||||
|
|
||||||
def round_five(weight)
|
def round_five(weight, rows)
|
||||||
create_matchup(nil,nil,"1/2",1,5,weight)
|
rows << create_matchup(nil,nil,"1/2",1,5,weight)
|
||||||
create_matchup(nil,nil,"3/4",1,5,weight)
|
rows << create_matchup(nil,nil,"3/4",1,5,weight)
|
||||||
create_matchup(nil,nil,"5/6",1,5,weight)
|
rows << create_matchup(nil,nil,"5/6",1,5,weight)
|
||||||
if @number_of_placers >= 8
|
if @number_of_placers >= 8
|
||||||
create_matchup(nil,nil,"7/8",1,5,weight)
|
rows << create_matchup(nil,nil,"7/8",1,5,weight)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def wrestler_with_seed(seed,weight)
|
def wrestler_with_seed(seed,weight)
|
||||||
wrestler = Wrestler.where("weight_id = ? and bracket_line = ?", weight.id, seed).first
|
wrestler = weight.wrestlers.find { |w| w.bracket_line == seed }
|
||||||
if wrestler
|
if wrestler
|
||||||
return wrestler.id
|
return wrestler.id
|
||||||
else
|
else
|
||||||
@@ -79,13 +84,18 @@ class ModifiedSixteenManMatchGeneration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create_matchup(w1, w2, bracket_position, bracket_position_number,round,weight)
|
def create_matchup(w1, w2, bracket_position, bracket_position_number,round,weight)
|
||||||
@tournament.matches.create(
|
{
|
||||||
w1: w1,
|
w1: w1,
|
||||||
w2: w2,
|
w2: w2,
|
||||||
|
tournament_id: @tournament.id,
|
||||||
weight_id: weight.id,
|
weight_id: weight.id,
|
||||||
round: round,
|
round: round,
|
||||||
bracket_position: bracket_position,
|
bracket_position: bracket_position,
|
||||||
bracket_position_number: bracket_position_number
|
bracket_position_number: bracket_position_number
|
||||||
)
|
}
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
def generation_weights
|
||||||
|
@weights || @tournament.weights.to_a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -12,18 +12,19 @@ class PoolBracketGeneration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def generateBracketMatches()
|
def generateBracketMatches()
|
||||||
|
@rows = []
|
||||||
if @pool_bracket_type == "twoPoolsToSemi"
|
if @pool_bracket_type == "twoPoolsToSemi"
|
||||||
return twoPoolsToSemi()
|
twoPoolsToSemi()
|
||||||
elsif @pool_bracket_type == "twoPoolsToFinal"
|
elsif @pool_bracket_type == "twoPoolsToFinal"
|
||||||
return twoPoolsToFinal()
|
twoPoolsToFinal()
|
||||||
elsif @pool_bracket_type == "fourPoolsToQuarter"
|
elsif @pool_bracket_type == "fourPoolsToQuarter"
|
||||||
return fourPoolsToQuarter()
|
fourPoolsToQuarter()
|
||||||
elsif @pool_bracket_type == "fourPoolsToSemi"
|
elsif @pool_bracket_type == "fourPoolsToSemi"
|
||||||
return fourPoolsToSemi()
|
fourPoolsToSemi()
|
||||||
elsif @pool_bracket_type == "eightPoolsToQuarter"
|
elsif @pool_bracket_type == "eightPoolsToQuarter"
|
||||||
return eightPoolsToQuarter()
|
eightPoolsToQuarter()
|
||||||
end
|
end
|
||||||
return []
|
@rows
|
||||||
end
|
end
|
||||||
|
|
||||||
def twoPoolsToSemi()
|
def twoPoolsToSemi()
|
||||||
@@ -86,14 +87,15 @@ class PoolBracketGeneration
|
|||||||
end
|
end
|
||||||
|
|
||||||
def createMatchup(w1_name, w2_name, bracket_position, bracket_position_number)
|
def createMatchup(w1_name, w2_name, bracket_position, bracket_position_number)
|
||||||
@tournament.matches.create(
|
@rows << {
|
||||||
loser1_name: w1_name,
|
loser1_name: w1_name,
|
||||||
loser2_name: w2_name,
|
loser2_name: w2_name,
|
||||||
|
tournament_id: @tournament.id,
|
||||||
weight_id: @weight.id,
|
weight_id: @weight.id,
|
||||||
round: @round,
|
round: @round,
|
||||||
bracket_position: bracket_position,
|
bracket_position: bracket_position,
|
||||||
bracket_position_number: bracket_position_number
|
bracket_position_number: bracket_position_number
|
||||||
)
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,35 +1,46 @@
|
|||||||
class PoolGeneration
|
class PoolGeneration
|
||||||
def initialize(weight)
|
def initialize(weight, wrestlers: nil)
|
||||||
@weight = weight
|
@weight = weight
|
||||||
@tournament = @weight.tournament
|
@tournament = @weight.tournament
|
||||||
@pool = 1
|
@pool = 1
|
||||||
|
@wrestlers = wrestlers
|
||||||
end
|
end
|
||||||
|
|
||||||
def generatePools
|
def generatePools
|
||||||
GeneratePoolNumbers.new(@weight).savePoolNumbers
|
GeneratePoolNumbers.new(@weight).savePoolNumbers(wrestlers: wrestlers_for_weight, persist: false)
|
||||||
|
rows = []
|
||||||
pools = @weight.pools
|
pools = @weight.pools
|
||||||
while @pool <= pools
|
while @pool <= pools
|
||||||
roundRobin
|
rows.concat(roundRobin)
|
||||||
@pool += 1
|
@pool += 1
|
||||||
end
|
end
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
def roundRobin
|
def roundRobin
|
||||||
wrestlers = @weight.wrestlers_in_pool(@pool)
|
rows = []
|
||||||
|
wrestlers = wrestlers_for_weight.select { |w| w.pool == @pool }
|
||||||
pool_matches = RoundRobinTournament.schedule(wrestlers).reverse
|
pool_matches = RoundRobinTournament.schedule(wrestlers).reverse
|
||||||
pool_matches.each_with_index do |b, index|
|
pool_matches.each_with_index do |b, index|
|
||||||
round = index + 1
|
round = index + 1
|
||||||
bouts = b.map
|
bouts = b.map
|
||||||
bouts.each do |bout|
|
bouts.each do |bout|
|
||||||
if bout[0] != nil and bout[1] != nil
|
if bout[0] != nil and bout[1] != nil
|
||||||
@tournament.matches.create(
|
rows << {
|
||||||
w1: bout[0].id,
|
w1: bout[0].id,
|
||||||
w2: bout[1].id,
|
w2: bout[1].id,
|
||||||
|
tournament_id: @tournament.id,
|
||||||
weight_id: @weight.id,
|
weight_id: @weight.id,
|
||||||
bracket_position: "Pool",
|
bracket_position: "Pool",
|
||||||
round: round)
|
round: round
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wrestlers_for_weight
|
||||||
|
@wrestlers || @weight.wrestlers.to_a
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,80 +1,97 @@
|
|||||||
class PoolToBracketGenerateLoserNames
|
class PoolToBracketGenerateLoserNames
|
||||||
def initialize( tournament )
|
def initialize(tournament)
|
||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
end
|
|
||||||
|
|
||||||
def assignLoserNamesWeight(weight)
|
|
||||||
matches_by_weight = @tournament.matches.where(weight_id: weight.id)
|
|
||||||
if weight.pool_bracket_type == "twoPoolsToSemi"
|
|
||||||
twoPoolsToSemiLoser(matches_by_weight)
|
|
||||||
elsif (weight.pool_bracket_type == "fourPoolsToQuarter") or (weight.pool_bracket_type == "eightPoolsToQuarter")
|
|
||||||
fourPoolsToQuarterLoser(matches_by_weight)
|
|
||||||
elsif weight.pool_bracket_type == "fourPoolsToSemi"
|
|
||||||
fourPoolsToSemiLoser(matches_by_weight)
|
|
||||||
end
|
|
||||||
saveMatches(matches_by_weight)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def assignLoserNames
|
# Compatibility wrapper. Returns transformed rows and does not persist.
|
||||||
matches_by_weight = nil
|
def assignLoserNamesWeight(weight, match_rows = nil)
|
||||||
@tournament.weights.each do |w|
|
rows = match_rows || @tournament.matches.where(weight_id: weight.id).map { |m| m.attributes.symbolize_keys }
|
||||||
matches_by_weight = @tournament.matches.where(weight_id: w.id)
|
assign_loser_names_in_memory(weight, rows)
|
||||||
if w.pool_bracket_type == "twoPoolsToSemi"
|
rows
|
||||||
twoPoolsToSemiLoser(matches_by_weight)
|
|
||||||
elsif (w.pool_bracket_type == "fourPoolsToQuarter") or (w.pool_bracket_type == "eightPoolsToQuarter")
|
|
||||||
fourPoolsToQuarterLoser(matches_by_weight)
|
|
||||||
elsif w.pool_bracket_type == "fourPoolsToSemi"
|
|
||||||
fourPoolsToSemiLoser(matches_by_weight)
|
|
||||||
end
|
|
||||||
saveMatches(matches_by_weight)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def twoPoolsToSemiLoser(matches_by_weight)
|
|
||||||
match1 = matches_by_weight.select{|m| m.loser1_name == "Winner Pool 1"}.first
|
|
||||||
match2 = matches_by_weight.select{|m| m.loser1_name == "Winner Pool 2"}.first
|
|
||||||
matchChange = matches_by_weight.select{|m| m.bracket_position == "3/4"}.first
|
|
||||||
matchChange.loser1_name = "Loser of #{match1.bout_number}"
|
|
||||||
matchChange.loser2_name = "Loser of #{match2.bout_number}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fourPoolsToQuarterLoser(matches_by_weight)
|
# Compatibility wrapper. Returns transformed rows and does not persist.
|
||||||
quarters = matches_by_weight.select{|m| m.bracket_position == "Quarter"}
|
def assignLoserNames
|
||||||
consoSemis = matches_by_weight.select{|m| m.bracket_position == "Conso Semis"}
|
@tournament.weights.each_with_object([]) do |weight, all_rows|
|
||||||
semis = matches_by_weight.select{|m| m.bracket_position == "Semis"}
|
all_rows.concat(assignLoserNamesWeight(weight))
|
||||||
thirdFourth = matches_by_weight.select{|m| m.bracket_position == "3/4"}.first
|
end
|
||||||
seventhEighth = matches_by_weight.select{|m| m.bracket_position == "7/8"}.first
|
end
|
||||||
consoSemis.each do |m|
|
|
||||||
if m.bracket_position_number == 1
|
def assign_loser_names_in_memory(weight, match_rows)
|
||||||
m.loser1_name = "Loser of #{quarters.select{|m| m.bracket_position_number == 1}.first.bout_number}"
|
rows = match_rows.select { |row| row[:weight_id] == weight.id }
|
||||||
m.loser2_name = "Loser of #{quarters.select{|m| m.bracket_position_number == 2}.first.bout_number}"
|
if weight.pool_bracket_type == "twoPoolsToSemi"
|
||||||
elsif m.bracket_position_number == 2
|
two_pools_to_semi_loser_rows(rows)
|
||||||
m.loser1_name = "Loser of #{quarters.select{|m| m.bracket_position_number == 3}.first.bout_number}"
|
elsif (weight.pool_bracket_type == "fourPoolsToQuarter") || (weight.pool_bracket_type == "eightPoolsToQuarter")
|
||||||
m.loser2_name = "Loser of #{quarters.select{|m| m.bracket_position_number == 4}.first.bout_number}"
|
four_pools_to_quarter_loser_rows(rows)
|
||||||
|
elsif weight.pool_bracket_type == "fourPoolsToSemi"
|
||||||
|
four_pools_to_semi_loser_rows(rows)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def two_pools_to_semi_loser_rows(rows)
|
||||||
|
match1 = rows.find { |m| m[:loser1_name] == "Winner Pool 1" }
|
||||||
|
match2 = rows.find { |m| m[:loser1_name] == "Winner Pool 2" }
|
||||||
|
match_change = rows.find { |m| m[:bracket_position] == "3/4" }
|
||||||
|
return unless match1 && match2 && match_change
|
||||||
|
|
||||||
|
match_change[:loser1_name] = "Loser of #{match1[:bout_number]}"
|
||||||
|
match_change[:loser2_name] = "Loser of #{match2[:bout_number]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def four_pools_to_quarter_loser_rows(rows)
|
||||||
|
quarters = rows.select { |m| m[:bracket_position] == "Quarter" }
|
||||||
|
conso_semis = rows.select { |m| m[:bracket_position] == "Conso Semis" }
|
||||||
|
semis = rows.select { |m| m[:bracket_position] == "Semis" }
|
||||||
|
third_fourth = rows.find { |m| m[:bracket_position] == "3/4" }
|
||||||
|
seventh_eighth = rows.find { |m| m[:bracket_position] == "7/8" }
|
||||||
|
|
||||||
|
conso_semis.each do |m|
|
||||||
|
if m[:bracket_position_number] == 1
|
||||||
|
q1 = quarters.find { |q| q[:bracket_position_number] == 1 }
|
||||||
|
q2 = quarters.find { |q| q[:bracket_position_number] == 2 }
|
||||||
|
m[:loser1_name] = "Loser of #{q1[:bout_number]}" if q1
|
||||||
|
m[:loser2_name] = "Loser of #{q2[:bout_number]}" if q2
|
||||||
|
elsif m[:bracket_position_number] == 2
|
||||||
|
q3 = quarters.find { |q| q[:bracket_position_number] == 3 }
|
||||||
|
q4 = quarters.find { |q| q[:bracket_position_number] == 4 }
|
||||||
|
m[:loser1_name] = "Loser of #{q3[:bout_number]}" if q3
|
||||||
|
m[:loser2_name] = "Loser of #{q4[:bout_number]}" if q4
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
thirdFourth.loser1_name = "Loser of #{semis.select{|m| m.bracket_position_number == 1}.first.bout_number}"
|
|
||||||
thirdFourth.loser2_name = "Loser of #{semis.select{|m| m.bracket_position_number == 2}.first.bout_number}"
|
if third_fourth
|
||||||
consoSemis = matches_by_weight.select{|m| m.bracket_position == "Conso Semis"}
|
s1 = semis.find { |s| s[:bracket_position_number] == 1 }
|
||||||
seventhEighth.loser1_name = "Loser of #{consoSemis.select{|m| m.bracket_position_number == 1}.first.bout_number}"
|
s2 = semis.find { |s| s[:bracket_position_number] == 2 }
|
||||||
seventhEighth.loser2_name = "Loser of #{consoSemis.select{|m| m.bracket_position_number == 2}.first.bout_number}"
|
third_fourth[:loser1_name] = "Loser of #{s1[:bout_number]}" if s1
|
||||||
|
third_fourth[:loser2_name] = "Loser of #{s2[:bout_number]}" if s2
|
||||||
|
end
|
||||||
|
|
||||||
|
if seventh_eighth
|
||||||
|
c1 = conso_semis.find { |c| c[:bracket_position_number] == 1 }
|
||||||
|
c2 = conso_semis.find { |c| c[:bracket_position_number] == 2 }
|
||||||
|
seventh_eighth[:loser1_name] = "Loser of #{c1[:bout_number]}" if c1
|
||||||
|
seventh_eighth[:loser2_name] = "Loser of #{c2[:bout_number]}" if c2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fourPoolsToSemiLoser(matches_by_weight)
|
def four_pools_to_semi_loser_rows(rows)
|
||||||
semis = matches_by_weight.select{|m| m.bracket_position == "Semis"}
|
semis = rows.select { |m| m[:bracket_position] == "Semis" }
|
||||||
thirdFourth = matches_by_weight.select{|m| m.bracket_position == "3/4"}.first
|
conso_semis = rows.select { |m| m[:bracket_position] == "Conso Semis" }
|
||||||
consoSemis = matches_by_weight.select{|m| m.bracket_position == "Conso Semis"}
|
third_fourth = rows.find { |m| m[:bracket_position] == "3/4" }
|
||||||
seventhEighth = matches_by_weight.select{|m| m.bracket_position == "7/8"}.first
|
seventh_eighth = rows.find { |m| m[:bracket_position] == "7/8" }
|
||||||
thirdFourth.loser1_name = "Loser of #{semis.select{|m| m.bracket_position_number == 1}.first.bout_number}"
|
|
||||||
thirdFourth.loser2_name = "Loser of #{semis.select{|m| m.bracket_position_number == 2}.first.bout_number}"
|
if third_fourth
|
||||||
seventhEighth.loser1_name = "Loser of #{consoSemis.select{|m| m.bracket_position_number == 1}.first.bout_number}"
|
s1 = semis.find { |s| s[:bracket_position_number] == 1 }
|
||||||
seventhEighth.loser2_name = "Loser of #{consoSemis.select{|m| m.bracket_position_number == 2}.first.bout_number}"
|
s2 = semis.find { |s| s[:bracket_position_number] == 2 }
|
||||||
|
third_fourth[:loser1_name] = "Loser of #{s1[:bout_number]}" if s1
|
||||||
|
third_fourth[:loser2_name] = "Loser of #{s2[:bout_number]}" if s2
|
||||||
|
end
|
||||||
|
|
||||||
|
if seventh_eighth
|
||||||
|
c1 = conso_semis.find { |c| c[:bracket_position_number] == 1 }
|
||||||
|
c2 = conso_semis.find { |c| c[:bracket_position_number] == 2 }
|
||||||
|
seventh_eighth[:loser1_name] = "Loser of #{c1[:bout_number]}" if c1
|
||||||
|
seventh_eighth[:loser2_name] = "Loser of #{c2[:bout_number]}" if c2
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
def saveMatches(matches)
|
|
||||||
matches.each do |m|
|
|
||||||
m.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -1,44 +1,92 @@
|
|||||||
class PoolToBracketMatchGeneration
|
class PoolToBracketMatchGeneration
|
||||||
def initialize( tournament )
|
def initialize(tournament, weights: nil, wrestlers_by_weight_id: nil)
|
||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
|
@weights = weights
|
||||||
|
@wrestlers_by_weight_id = wrestlers_by_weight_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def generatePoolToBracketMatches
|
def generatePoolToBracketMatches
|
||||||
@tournament.weights.order(:max).each do |weight|
|
rows = []
|
||||||
PoolGeneration.new(weight).generatePools()
|
generation_weights.each do |weight|
|
||||||
last_match = @tournament.matches.where(weight: weight).order(round: :desc).limit(1).first
|
wrestlers = wrestlers_for_weight(weight)
|
||||||
highest_round = last_match.round
|
pool_rows = PoolGeneration.new(weight, wrestlers: wrestlers).generatePools
|
||||||
PoolBracketGeneration.new(weight, highest_round).generateBracketMatches()
|
rows.concat(pool_rows)
|
||||||
|
|
||||||
|
highest_round = pool_rows.map { |row| row[:round] }.max || 0
|
||||||
|
bracket_rows = PoolBracketGeneration.new(weight, highest_round).generateBracketMatches
|
||||||
|
rows.concat(bracket_rows)
|
||||||
end
|
end
|
||||||
movePoolSeedsToFinalPoolRound
|
|
||||||
|
movePoolSeedsToFinalPoolRound(rows)
|
||||||
|
rows
|
||||||
end
|
end
|
||||||
|
|
||||||
def movePoolSeedsToFinalPoolRound
|
def movePoolSeedsToFinalPoolRound(match_rows)
|
||||||
@tournament.weights.each do |w|
|
generation_weights.each do |w|
|
||||||
setOriginalSeedsToWrestleLastPoolRound(w)
|
setOriginalSeedsToWrestleLastPoolRound(w, match_rows)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def setOriginalSeedsToWrestleLastPoolRound(weight)
|
def setOriginalSeedsToWrestleLastPoolRound(weight, match_rows)
|
||||||
pool = 1
|
pool = 1
|
||||||
until pool > weight.pools
|
wrestlers = wrestlers_for_weight(weight)
|
||||||
wrestler1 = weight.pool_wrestlers_sorted_by_bracket_line(pool).first
|
weight_pools = weight.pools
|
||||||
wrestler2 = weight.pool_wrestlers_sorted_by_bracket_line(pool).second
|
until pool > weight_pools
|
||||||
match = wrestler1.pool_matches.sort_by{|m| m.round}.last
|
pool_wrestlers = wrestlers.select { |w| w.pool == pool }.sort_by(&:bracket_line)
|
||||||
if match.w1 != wrestler2.id or match.w2 != wrestler2.id
|
wrestler1 = pool_wrestlers.first
|
||||||
if match.w1 == wrestler1.id
|
wrestler2 = pool_wrestlers.second
|
||||||
SwapWrestlers.new.swap_wrestlers_bracket_lines(match.w2,wrestler2.id)
|
if wrestler1 && wrestler2
|
||||||
elsif match.w2 == wrestler1.id
|
pool_matches = match_rows.select { |row| row[:weight_id] == weight.id && row[:bracket_position] == "Pool" && (row[:w1] == wrestler1.id || row[:w2] == wrestler1.id) }
|
||||||
SwapWrestlers.new.swap_wrestlers_bracket_lines(match.w1,wrestler2.id)
|
match = pool_matches.max_by { |row| row[:round] }
|
||||||
end
|
if match && (match[:w1] != wrestler2.id || match[:w2] != wrestler2.id)
|
||||||
|
if match[:w1] == wrestler1.id
|
||||||
|
swap_wrestlers_in_memory(match_rows, wrestlers, match[:w2], wrestler2.id)
|
||||||
|
elsif match[:w2] == wrestler1.id
|
||||||
|
swap_wrestlers_in_memory(match_rows, wrestlers, match[:w1], wrestler2.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
pool += 1
|
pool += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def swap_wrestlers_in_memory(match_rows, wrestlers, wrestler1_id, wrestler2_id)
|
||||||
|
w1 = wrestlers.find { |w| w.id == wrestler1_id }
|
||||||
|
w2 = wrestlers.find { |w| w.id == wrestler2_id }
|
||||||
|
return unless w1 && w2
|
||||||
|
|
||||||
|
w1_bracket_line, w1_pool = w1.bracket_line, w1.pool
|
||||||
|
w1.bracket_line, w1.pool = w2.bracket_line, w2.pool
|
||||||
|
w2.bracket_line, w2.pool = w1_bracket_line, w1_pool
|
||||||
|
|
||||||
|
swap_match_rows(match_rows, wrestler1_id, wrestler2_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def swap_match_rows(match_rows, wrestler1_id, wrestler2_id)
|
||||||
|
match_rows.each do |row|
|
||||||
|
row[:w1] = swap_id(row[:w1], wrestler1_id, wrestler2_id)
|
||||||
|
row[:w2] = swap_id(row[:w2], wrestler1_id, wrestler2_id)
|
||||||
|
row[:winner_id] = swap_id(row[:winner_id], wrestler1_id, wrestler2_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def swap_id(value, wrestler1_id, wrestler2_id)
|
||||||
|
return wrestler2_id if value == wrestler1_id
|
||||||
|
return wrestler1_id if value == wrestler2_id
|
||||||
|
|
||||||
|
value
|
||||||
|
end
|
||||||
|
|
||||||
|
def generation_weights
|
||||||
|
@weights || @tournament.weights.order(:max).to_a
|
||||||
|
end
|
||||||
|
|
||||||
|
def wrestlers_for_weight(weight)
|
||||||
|
@wrestlers_by_weight_id&.fetch(weight.id, nil) || weight.wrestlers.to_a
|
||||||
|
end
|
||||||
|
|
||||||
def assignLoserNames
|
def assignLoserNames
|
||||||
PoolToBracketGenerateLoserNames.new(@tournament).assignLoserNames
|
PoolToBracketGenerateLoserNames.new(@tournament).assignLoserNames
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,16 +3,22 @@ class TournamentSeeding
|
|||||||
@tournament = tournament
|
@tournament = tournament
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_seeds
|
def set_seeds(weights: nil, persist: true)
|
||||||
@tournament.weights.each do |weight|
|
weights_to_seed = weights || @tournament.weights.includes(:wrestlers)
|
||||||
|
updated_wrestlers = []
|
||||||
|
|
||||||
|
weights_to_seed.each do |weight|
|
||||||
wrestlers = weight.wrestlers
|
wrestlers = weight.wrestlers
|
||||||
bracket_size = weight.calculate_bracket_size
|
bracket_size = weight.calculate_bracket_size
|
||||||
|
|
||||||
wrestlers = reset_bracket_line_for_lines_higher_than_bracket_size(wrestlers, bracket_size)
|
wrestlers = reset_bracket_line_for_lines_higher_than_bracket_size(wrestlers, bracket_size)
|
||||||
wrestlers = set_original_seed_to_bracket_line(wrestlers)
|
wrestlers = set_original_seed_to_bracket_line(wrestlers)
|
||||||
wrestlers = random_seeding(wrestlers, bracket_size)
|
wrestlers = random_seeding(wrestlers, bracket_size)
|
||||||
wrestlers.each(&:save)
|
updated_wrestlers.concat(wrestlers)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
persist_bracket_lines(updated_wrestlers) if persist
|
||||||
|
updated_wrestlers
|
||||||
end
|
end
|
||||||
|
|
||||||
def random_seeding(wrestlers, bracket_size)
|
def random_seeding(wrestlers, bracket_size)
|
||||||
@@ -96,4 +102,19 @@ class TournamentSeeding
|
|||||||
end
|
end
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
def persist_bracket_lines(wrestlers)
|
||||||
|
return if wrestlers.blank?
|
||||||
|
|
||||||
|
timestamp = Time.current
|
||||||
|
updates = wrestlers.map do |wrestler|
|
||||||
|
{
|
||||||
|
id: wrestler.id,
|
||||||
|
bracket_line: wrestler.bracket_line,
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
Wrestler.upsert_all(updates)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ class GeneratePoolNumbers
|
|||||||
@weight = weight
|
@weight = weight
|
||||||
end
|
end
|
||||||
|
|
||||||
def savePoolNumbers
|
def savePoolNumbers(wrestlers: nil, persist: true)
|
||||||
@weight.wrestlers.each do |wrestler|
|
wrestlers_to_update = wrestlers || @weight.wrestlers.to_a
|
||||||
|
wrestlers_to_update.each do |wrestler|
|
||||||
wrestler.pool = get_wrestler_pool_number(@weight.pools, wrestler.bracket_line)
|
wrestler.pool = get_wrestler_pool_number(@weight.pools, wrestler.bracket_line)
|
||||||
wrestler.save
|
|
||||||
end
|
end
|
||||||
|
persist_pool_numbers(wrestlers_to_update) if persist
|
||||||
|
wrestlers_to_update
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_wrestler_pool_number(number_of_pools, wrestler_seed)
|
def get_wrestler_pool_number(number_of_pools, wrestler_seed)
|
||||||
@@ -36,4 +38,20 @@ class GeneratePoolNumbers
|
|||||||
|
|
||||||
pool
|
pool
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def persist_pool_numbers(wrestlers)
|
||||||
|
return if wrestlers.blank?
|
||||||
|
|
||||||
|
timestamp = Time.current
|
||||||
|
rows = wrestlers.map do |w|
|
||||||
|
{
|
||||||
|
id: w.id,
|
||||||
|
pool: w.pool,
|
||||||
|
updated_at: timestamp
|
||||||
|
}
|
||||||
|
end
|
||||||
|
Wrestler.upsert_all(rows)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user