d834b81003
git-subtree-dir: map-mash git-subtree-mainline:eacc351b17
git-subtree-split:7f16409d12
129 lines
3.1 KiB
Ruby
129 lines
3.1 KiB
Ruby
require 'logger'
|
|
|
|
|
|
class MashTournamentBuilder
|
|
attr_accessor :tournament, :tournament_model, :round_model
|
|
attr_accessor :map_model, :mash_model
|
|
|
|
def initialize(tournament, tournament_model, round_model,
|
|
map_model, mash_model)
|
|
@tournament = tournament
|
|
@tournament_model = tournament_model
|
|
@round_model = round_model
|
|
@map_model = map_model
|
|
@mash_model = mash_model
|
|
@logger = Logger.new(
|
|
File.expand_path(
|
|
'../log/mash-tournament-builder.log', File.dirname(__FILE__)
|
|
)
|
|
)
|
|
end
|
|
|
|
def valid_number_of_contenders?(n_contenders)
|
|
[8, 16, 32, 64, 128].include?(n_contenders)
|
|
end
|
|
|
|
def create_rounds_for_contenders(n_contenders)
|
|
if not valid_number_of_contenders?(n_contenders)
|
|
raise StandardError.new(
|
|
"The number of contenders must be 8, 16, 32, 64, or 128! " +
|
|
"Got '#{n_contenders}'"
|
|
)
|
|
end
|
|
|
|
round = 1
|
|
|
|
while n_contenders > 1
|
|
create_round(round, n_contenders)
|
|
n_contenders = n_contenders / 2
|
|
round += 1
|
|
end
|
|
|
|
@tournament.total_rounds = round - 1
|
|
end
|
|
|
|
def fill_in_next_round
|
|
@tournament.rounds.sort{ |a,b| a.number <=> b.number}.each do |round|
|
|
if not round.done?
|
|
return assign_maps_for_round(round)
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
def create_round(round_number, n_contenders)
|
|
round_options = {
|
|
:mash_tournament_id => @tournament.id,
|
|
:number => round_number,
|
|
:mash_count => n_contenders / 2
|
|
}
|
|
@logger.info("Creating round #{round_number} of #{n_contenders} contenders " +
|
|
"with options: #{round_options.inspect}")
|
|
|
|
round = @round_model.new(round_options)
|
|
round.save!
|
|
|
|
round.mash_count.times do
|
|
@mash_model.new(
|
|
:mash_tournament_id => @tournament.id,
|
|
:mash_tournament_round_id => round.id
|
|
).save!
|
|
end
|
|
end
|
|
|
|
def assign_maps_for_round(round)
|
|
if round.number == 1
|
|
return assign_maps_for_round_one(round)
|
|
end
|
|
|
|
previous = @round_model.find_by_mash_tournament_id_and_number(
|
|
@tournament.id, round.number - 1
|
|
)
|
|
previous_winners = previous.mashes.collect(&:winner_id)
|
|
pool = @map_model.all(
|
|
:order => 'RANDOM()',
|
|
:conditions => {:id => previous_winners}
|
|
)
|
|
|
|
filled_in = []
|
|
|
|
round.mashes.each do |mash|
|
|
mash.map_a = pool.pop
|
|
mash.map_b = pool.pop
|
|
mash.save!
|
|
|
|
filled_in << mash
|
|
end
|
|
|
|
filled_in
|
|
end
|
|
|
|
def assign_maps_for_round_one(round)
|
|
pool_options = {
|
|
:order => 'RANDOM()',
|
|
:limit => round.mash_count * 2
|
|
}
|
|
@logger.info("Allocating pool with options: #{pool_options.inspect}")
|
|
pool = @map_model.all(pool_options)
|
|
|
|
@logger.info("Populating mashes from pool: #{pool.inspect}")
|
|
|
|
filled_in = []
|
|
|
|
round.mashes.each do |mash|
|
|
map_a = pool.pop
|
|
map_b = pool.pop
|
|
@logger.info("Assigning `map_a` from #{map_a.inspect}, " +
|
|
"`map_b` from #{map_b.inspect} to mash #{mash.inspect}")
|
|
|
|
mash.map_a = map_a
|
|
mash.map_b = map_b
|
|
mash.save!
|
|
|
|
filled_in << mash
|
|
end
|
|
|
|
filled_in
|
|
end
|
|
end
|