mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-25 01:14:43 +00:00
193 lines
7.2 KiB
Ruby
193 lines
7.2 KiB
Ruby
class GenerateTournamentMatches
|
|
def initialize( tournament )
|
|
@tournament = tournament
|
|
end
|
|
|
|
def generate
|
|
# Use perform_later which will execute based on centralized adapter config
|
|
GenerateTournamentMatchesJob.perform_later(@tournament)
|
|
end
|
|
|
|
def generate_raw
|
|
standardStartingActions
|
|
generation_context = preload_generation_context
|
|
seed_wrestlers_in_memory(generation_context)
|
|
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
|
|
advance_bye_matches_after_insert
|
|
end
|
|
|
|
def standardStartingActions
|
|
@tournament.curently_generating_matches = 1
|
|
@tournament.save
|
|
WipeTournamentMatches.new(@tournament).setUpMatchGeneration
|
|
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
|
|
|
|
def postMatchCreationActions
|
|
@tournament.reset_and_fill_bout_board
|
|
@tournament.curently_generating_matches = nil
|
|
@tournament.save!
|
|
Tournament.broadcast_up_matches_board(@tournament.id)
|
|
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
|
|
bout_counts = Hash.new(0)
|
|
timestamp = Time.current
|
|
ordered_matches = Match.joins(:weight)
|
|
.where(tournament_id: @tournament.id)
|
|
.order("matches.round ASC, weights.max ASC, matches.id ASC")
|
|
.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
|
|
|
|
Match.upsert_all(updates) if updates.any?
|
|
end
|
|
|
|
def moveFinalsMatchesToLastRound
|
|
finalsRound = @tournament.reload.total_rounds
|
|
@tournament.matches
|
|
.where(bracket_position: ["1/2", "3/4", "5/6", "7/8"])
|
|
.update_all(round: finalsRound, updated_at: Time.current)
|
|
end
|
|
|
|
def unAssignMats
|
|
@tournament.matches.update_all(mat_id: nil, updated_at: Time.current)
|
|
end
|
|
|
|
def unAssignBouts
|
|
@tournament.matches.update_all(bout_number: nil, updated_at: Time.current)
|
|
end
|
|
end
|