mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-04-03 13:30:02 +00:00
Refactored match generation so I can eventually support multiple types of tournaments
This commit is contained in:
@@ -163,7 +163,7 @@ class TournamentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def generate_matches
|
def generate_matches
|
||||||
@tournament.generateMatchups
|
GenerateTournamentMatches.new(@tournament).generate
|
||||||
end
|
end
|
||||||
|
|
||||||
def brackets
|
def brackets
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
module GeneratesTournamentMatches
|
|
||||||
|
|
||||||
def generateMatchups
|
|
||||||
self.curently_generating_matches = 1
|
|
||||||
self.save
|
|
||||||
resetSchoolScores
|
|
||||||
setSeedsAndRandomSeedingWrestlersWithoutSeeds
|
|
||||||
poolToBracket() if tournament_type == "Pool to bracket"
|
|
||||||
self.curently_generating_matches = nil
|
|
||||||
self.save
|
|
||||||
end
|
|
||||||
if Rails.env.production?
|
|
||||||
handle_asynchronously :generateMatchups
|
|
||||||
end
|
|
||||||
|
|
||||||
def poolToBracket
|
|
||||||
destroyAllMatches
|
|
||||||
generatePoolToBracketMatches
|
|
||||||
poolToBracketPostMatchCreation
|
|
||||||
end
|
|
||||||
|
|
||||||
def generatePoolToBracketMatches
|
|
||||||
weights.order(:max).each do |weight|
|
|
||||||
Pool.new(weight).generatePools()
|
|
||||||
last_match = matches.where(weight: weight).order(round: :desc).limit(1).first
|
|
||||||
highest_round = last_match.round
|
|
||||||
PoolBracket.new(weight, highest_round).generateBracketMatches()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def poolToBracketPostMatchCreation
|
|
||||||
moveFinalsMatchesToLastRound
|
|
||||||
assignBouts
|
|
||||||
assignLoserNames
|
|
||||||
assignFirstMatchesToMats
|
|
||||||
movePoolSeedsToFinalPoolRound
|
|
||||||
end
|
|
||||||
|
|
||||||
def moveFinalsMatchesToLastRound
|
|
||||||
finalsRound = self.totalRounds
|
|
||||||
finalsMatches = self.matches.select{|m| m.bracket_position == "1/2" || m.bracket_position == "3/4" || m.bracket_position == "5/6" || m.bracket_position == "7/8"}
|
|
||||||
finalsMatches. each do |m|
|
|
||||||
m.round = finalsRound
|
|
||||||
m.save
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def setSeedsAndRandomSeedingWrestlersWithoutSeeds
|
|
||||||
weights.each do |w|
|
|
||||||
w.setSeeds
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def movePoolSeedsToFinalPoolRound
|
|
||||||
self.weights.each do |w|
|
|
||||||
w.setOriginalSeedsToWrestleLastPoolRound
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
class Tournament < ActiveRecord::Base
|
class Tournament < ActiveRecord::Base
|
||||||
|
|
||||||
include GeneratesLoserNames
|
|
||||||
include GeneratesTournamentMatches
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :schools, dependent: :destroy
|
has_many :schools, dependent: :destroy
|
||||||
has_many :weights, dependent: :destroy
|
has_many :weights, dependent: :destroy
|
||||||
@@ -24,10 +22,6 @@ class Tournament < ActiveRecord::Base
|
|||||||
time
|
time
|
||||||
end
|
end
|
||||||
|
|
||||||
def resetSchoolScores
|
|
||||||
schools.update_all("score = 0.0")
|
|
||||||
end
|
|
||||||
|
|
||||||
def tournament_types
|
def tournament_types
|
||||||
["Pool to bracket"]
|
["Pool to bracket"]
|
||||||
end
|
end
|
||||||
@@ -51,19 +45,6 @@ class Tournament < ActiveRecord::Base
|
|||||||
matches.joins(:weight).where(round: round).order("weights.max")
|
matches.joins(:weight).where(round: round).order("weights.max")
|
||||||
end
|
end
|
||||||
|
|
||||||
def assignBouts
|
|
||||||
bout_counts = Hash.new(0)
|
|
||||||
matches.each do |m|
|
|
||||||
m.bout_number = m.round * 1000 + bout_counts[m.round]
|
|
||||||
bout_counts[m.round] += 1
|
|
||||||
m.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def assignFirstMatchesToMats
|
|
||||||
assignMats(mats)
|
|
||||||
end
|
|
||||||
|
|
||||||
def totalRounds
|
def totalRounds
|
||||||
self.matches.sort_by{|m| m.round}.last.round
|
self.matches.sort_by{|m| m.round}.last.round
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -46,22 +46,6 @@ class Weight < ActiveRecord::Base
|
|||||||
wrestlersForPool(pool).sort_by{|w| [w.original_seed ? 0 : 1, w.original_seed || 0]}
|
wrestlersForPool(pool).sort_by{|w| [w.original_seed ? 0 : 1, w.original_seed || 0]}
|
||||||
end
|
end
|
||||||
|
|
||||||
def setOriginalSeedsToWrestleLastPoolRound
|
|
||||||
pool = 1
|
|
||||||
until pool > self.pools
|
|
||||||
wrestler1 = poolSeedOrder(pool).first
|
|
||||||
wrestler2 = poolSeedOrder(pool).second
|
|
||||||
match = wrestler1.poolMatches.sort_by{|m| m.round}.last
|
|
||||||
if match.w1 != wrestler2.id or match.w2 != wrestler2.id
|
|
||||||
if match.w1 == wrestler1.id
|
|
||||||
swapWrestlers(match.w2,wrestler2.id)
|
|
||||||
elsif match.w2 == wrestler1.id
|
|
||||||
swapWrestlers(match.w1,wrestler2.id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
pool += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def swapWrestlers(wrestler1_id,wrestler2_id)
|
def swapWrestlers(wrestler1_id,wrestler2_id)
|
||||||
SwapWrestlers.new.swapWrestlers(wrestler1_id,wrestler2_id)
|
SwapWrestlers.new.swapWrestlers(wrestler1_id,wrestler2_id)
|
||||||
@@ -181,37 +165,4 @@ class Weight < ActiveRecord::Base
|
|||||||
PoolOrder.new(wrestlersForPool(pool)).getPoolOrder
|
PoolOrder.new(wrestlersForPool(pool)).getPoolOrder
|
||||||
end
|
end
|
||||||
|
|
||||||
def randomSeeding
|
|
||||||
wrestlerWithSeeds = self.wrestlers.select{|w| w.original_seed != nil }.sort_by{|w| w.original_seed}
|
|
||||||
if wrestlerWithSeeds.size > 0
|
|
||||||
highestSeed = wrestlerWithSeeds.last.seed
|
|
||||||
seed = highestSeed + 1
|
|
||||||
else
|
|
||||||
seed = 1
|
|
||||||
end
|
|
||||||
wrestlersWithoutSeed = self.wrestlers.select{|w| w.original_seed == nil }
|
|
||||||
wrestlersWithoutSeed.shuffle.each do |w|
|
|
||||||
w.seed = seed
|
|
||||||
w.save
|
|
||||||
seed += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def setSeeds
|
|
||||||
resetAllSeeds
|
|
||||||
wrestlerWithSeeds = self.wrestlers.select{|w| w.original_seed != nil }
|
|
||||||
wrestlerWithSeeds.each do |w|
|
|
||||||
w.seed = w.original_seed
|
|
||||||
w.save
|
|
||||||
end
|
|
||||||
randomSeeding
|
|
||||||
end
|
|
||||||
|
|
||||||
def resetAllSeeds
|
|
||||||
self.wrestlers.each do |w|
|
|
||||||
w.seed = nil
|
|
||||||
w.save
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
class GenerateTournamentMatches
|
||||||
|
def initialize( tournament )
|
||||||
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate
|
||||||
|
standardStartingActions
|
||||||
|
PoolToBracketMatchGeneration.new(@tournament).generatePoolToBracketMatches if @tournament.tournament_type == "Pool to bracket"
|
||||||
|
postMatchCreationActions
|
||||||
|
PoolToBracketMatchGeneration.new(@tournament).assignLoserNames if @tournament.tournament_type == "Pool to bracket"
|
||||||
|
end
|
||||||
|
|
||||||
|
def standardStartingActions
|
||||||
|
@tournament.curently_generating_matches = 1
|
||||||
|
@tournament.save
|
||||||
|
WipeTournamentMatches.new(@tournament).setUpMatchGeneration
|
||||||
|
TournamentSeeding.new(@tournament).setSeeds
|
||||||
|
end
|
||||||
|
|
||||||
|
def postMatchCreationActions
|
||||||
|
moveFinalsMatchesToLastRound
|
||||||
|
assignBouts
|
||||||
|
assignFirstMatchesToMats
|
||||||
|
@tournament.curently_generating_matches = nil
|
||||||
|
@tournament.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def assignBouts
|
||||||
|
bout_counts = Hash.new(0)
|
||||||
|
@tournament.matches.each do |m|
|
||||||
|
m.bout_number = m.round * 1000 + bout_counts[m.round]
|
||||||
|
bout_counts[m.round] += 1
|
||||||
|
m.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def moveFinalsMatchesToLastRound
|
||||||
|
finalsRound = @tournament.totalRounds
|
||||||
|
finalsMatches = @tournament.matches.select{|m| m.bracket_position == "1/2" || m.bracket_position == "3/4" || m.bracket_position == "5/6" || m.bracket_position == "7/8"}
|
||||||
|
finalsMatches. each do |m|
|
||||||
|
m.round = finalsRound
|
||||||
|
m.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assignFirstMatchesToMats
|
||||||
|
matsToAssign = @tournament.mats
|
||||||
|
if matsToAssign.count > 0
|
||||||
|
until matsToAssign.sort_by{|m| m.id}.last.matches.count == 4
|
||||||
|
matsToAssign.sort_by{|m| m.id}.each do |m|
|
||||||
|
m.assignNextMatch
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
class PoolBracket
|
class PoolBracketGeneration
|
||||||
|
|
||||||
def initialize(weight, highest_round)
|
def initialize(weight, highest_round)
|
||||||
@weight = weight
|
@weight = weight
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
class Pool
|
class PoolGeneration
|
||||||
def initialize(weight)
|
def initialize(weight)
|
||||||
@weight = weight
|
@weight = weight
|
||||||
@tournament = @weight.tournament
|
@tournament = @weight.tournament
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
module GeneratesLoserNames
|
class PoolToBracketGenerateLoserNames
|
||||||
def assignLoserNames
|
def initialize( tournament )
|
||||||
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
def assignLoserNames
|
||||||
matches_by_weight = nil
|
matches_by_weight = nil
|
||||||
weights.each do |w|
|
@tournament.weights.each do |w|
|
||||||
matches_by_weight = matches.where(weight_id: w.id)
|
matches_by_weight = @tournament.matches.where(weight_id: w.id)
|
||||||
if w.pool_bracket_type == "twoPoolsToSemi"
|
if w.pool_bracket_type == "twoPoolsToSemi"
|
||||||
twoPoolsToSemiLoser(matches_by_weight)
|
twoPoolsToSemiLoser(matches_by_weight)
|
||||||
elsif w.pool_bracket_type == "fourPoolsToQuarter"
|
elsif w.pool_bracket_type == "fourPoolsToQuarter"
|
||||||
@@ -12,7 +16,7 @@ module GeneratesLoserNames
|
|||||||
end
|
end
|
||||||
saveMatches(matches_by_weight)
|
saveMatches(matches_by_weight)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def twoPoolsToSemiLoser(matches_by_weight)
|
def twoPoolsToSemiLoser(matches_by_weight)
|
||||||
match1 = matches_by_weight.select{|m| m.loser1_name == "Winner Pool 1"}.first
|
match1 = matches_by_weight.select{|m| m.loser1_name == "Winner Pool 1"}.first
|
||||||
@@ -60,4 +64,5 @@ module GeneratesLoserNames
|
|||||||
m.save!
|
m.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
class PoolToBracketMatchGeneration
|
||||||
|
def initialize( tournament )
|
||||||
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def generatePoolToBracketMatches
|
||||||
|
@tournament.weights.order(:max).each do |weight|
|
||||||
|
PoolGeneration.new(weight).generatePools()
|
||||||
|
last_match = @tournament.matches.where(weight: weight).order(round: :desc).limit(1).first
|
||||||
|
highest_round = last_match.round
|
||||||
|
PoolBracketGeneration.new(weight, highest_round).generateBracketMatches()
|
||||||
|
end
|
||||||
|
movePoolSeedsToFinalPoolRound
|
||||||
|
end
|
||||||
|
|
||||||
|
def movePoolSeedsToFinalPoolRound
|
||||||
|
@tournament.weights.each do |w|
|
||||||
|
setOriginalSeedsToWrestleLastPoolRound(w)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setOriginalSeedsToWrestleLastPoolRound(weight)
|
||||||
|
pool = 1
|
||||||
|
until pool > weight.pools
|
||||||
|
wrestler1 = weight.poolSeedOrder(pool).first
|
||||||
|
wrestler2 = weight.poolSeedOrder(pool).second
|
||||||
|
match = wrestler1.poolMatches.sort_by{|m| m.round}.last
|
||||||
|
if match.w1 != wrestler2.id or match.w2 != wrestler2.id
|
||||||
|
if match.w1 == wrestler1.id
|
||||||
|
SwapWrestlers.new.swapWrestlers(match.w2,wrestler2.id)
|
||||||
|
elsif match.w2 == wrestler1.id
|
||||||
|
SwapWrestlers.new.swapWrestlers(match.w1,wrestler2.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
pool += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def assignLoserNames
|
||||||
|
PoolToBracketGenerateLoserNames.new(@tournament).assignLoserNames
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
44
app/services/tournament_services/tournament_seeding.rb
Normal file
44
app/services/tournament_services/tournament_seeding.rb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
class TournamentSeeding
|
||||||
|
def initialize( tournament )
|
||||||
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
def setSeeds
|
||||||
|
@tournament.weights.each do |w|
|
||||||
|
resetAllSeeds(w)
|
||||||
|
setOriginalSeeds(w)
|
||||||
|
randomSeeding(w)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def randomSeeding(weight)
|
||||||
|
wrestlerWithSeeds = weight.wrestlers.select{|w| w.original_seed != nil }.sort_by{|w| w.original_seed}
|
||||||
|
if wrestlerWithSeeds.size > 0
|
||||||
|
highestSeed = wrestlerWithSeeds.last.seed
|
||||||
|
seed = highestSeed + 1
|
||||||
|
else
|
||||||
|
seed = 1
|
||||||
|
end
|
||||||
|
wrestlersWithoutSeed = weight.wrestlers.select{|w| w.original_seed == nil }
|
||||||
|
wrestlersWithoutSeed.shuffle.each do |w|
|
||||||
|
w.seed = seed
|
||||||
|
w.save
|
||||||
|
seed += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setOriginalSeeds(weight)
|
||||||
|
wrestlerWithSeeds = weight.wrestlers.select{|w| w.original_seed != nil }
|
||||||
|
wrestlerWithSeeds.each do |w|
|
||||||
|
w.seed = w.original_seed
|
||||||
|
w.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def resetAllSeeds(weight)
|
||||||
|
weight.wrestlers.each do |w|
|
||||||
|
w.seed = nil
|
||||||
|
w.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
19
app/services/tournament_services/wipe_tournament_matches.rb
Normal file
19
app/services/tournament_services/wipe_tournament_matches.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
class WipeTournamentMatches
|
||||||
|
|
||||||
|
def initialize( tournament )
|
||||||
|
@tournament = tournament
|
||||||
|
end
|
||||||
|
|
||||||
|
def setUpMatchGeneration
|
||||||
|
wipeMatches
|
||||||
|
resetSchoolScores
|
||||||
|
end
|
||||||
|
|
||||||
|
def wipeMatches
|
||||||
|
@tournament.matches.destroy_all
|
||||||
|
end
|
||||||
|
|
||||||
|
def resetSchoolScores
|
||||||
|
@tournament.schools.update_all("score = 0.0")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -34,6 +34,8 @@ module Wrestling
|
|||||||
config.to_prepare do
|
config.to_prepare do
|
||||||
DeviseController.respond_to :html, :json
|
DeviseController.respond_to :html, :json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.autoload_paths += %W(#{config.root}/app/services/tournament_services)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ class PoolAdvancementTest < ActionDispatch::IntegrationTest
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
tournament = Tournament.find(1)
|
tournament = Tournament.find(1)
|
||||||
|
|
||||||
# WHY DOES THIS NOT WORK WITHOUT GENERATING MATCHUPS BEFORE EVERY TEST?
|
|
||||||
# FIXTURES FOR MATCHES ARE FILLED OUT AND WORK FOR OTHER TESTS
|
|
||||||
# tournament.generateMatchups
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def singlePoolNotFinished
|
def singlePoolNotFinished
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ require 'test_helper'
|
|||||||
class PoolbracketMatchupsTest < ActionDispatch::IntegrationTest
|
class PoolbracketMatchupsTest < ActionDispatch::IntegrationTest
|
||||||
def setup
|
def setup
|
||||||
@tournament = Tournament.find(1)
|
@tournament = Tournament.find(1)
|
||||||
@tournament.generateMatchups
|
GenerateTournamentMatches.new(@tournament).generate
|
||||||
end
|
end
|
||||||
|
|
||||||
def createTournament(numberOfWrestlers)
|
def createTournament(numberOfWrestlers)
|
||||||
@@ -69,7 +69,7 @@ class PoolbracketMatchupsTest < ActionDispatch::IntegrationTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
def checkForByeInPool(tournament)
|
def checkForByeInPool(tournament)
|
||||||
tournament.generateMatchups
|
GenerateTournamentMatches.new(tournament).generate
|
||||||
matchups = tournament.matches
|
matchups = tournament.matches
|
||||||
tournament.weights.each do |w|
|
tournament.weights.each do |w|
|
||||||
w.wrestlers.each do |wr|
|
w.wrestlers.each do |wr|
|
||||||
|
|||||||
Reference in New Issue
Block a user