[英]Looking for approach to create seeded golf teams for a mini-tournement
我正在尝试编写一个例程,该例程基本上对团队进行“播种”,就像最近的NCAA篮球锦标赛一样,适用于经常有奇数球员的高尔夫团队。 篮球很容易,有64个团队和4个支架,种子最高的球员种子最低。 我的有点复杂。
如果我有13位球员出现在比赛中,那将是4支球队,1个四人组和3个三人组。 玩家将按照配额/让分进行排序。 玩家1是最高的玩家,而玩家13是最低的玩家。 目的是使每个团队的技能尽可能平均地分配。 我实际上已经在工作,但是它确实是丑陋的代码,我试图将其重构为看起来像红宝石而不是基本的东西!
我使用了数组的几种变体。 如果我先从13位玩家开始:
[1,2,3,4,5,6,7,8,9,10,11,12,13]
我可以将其分解为种子,首先要照顾四人组(通常称为ABCD组)
[[1,2,3,4],[5,6,7],[8,9,10],[11,12,13]]
为了获得平均分配,A组中最高的玩家将与B组中最低的玩家,C组中最高的玩家以及D组中的最低玩家一起玩。在四人组形成之后,其余的玩家将被分组为3种子,ABC和某种常规套用应用于3组。 最终团队将是:
[[1,7,8,13]] # foursome, 1st team
[[2,3,4],[5,6,9],[10,11,12]] # remaining players ofter first team formed and seeded into 3 group
在三人组中,我将A组中的最高玩家,B组中的最低玩家和C组中的最高玩家放在了一起。最终结果应该是这样的。
[[1,7,8,13],[2,9,10],[3,6,11],[4,5,12]]
如果您有15位玩家出现,那么将有3个四人组和1个三人组,您会得到类似的球队。
[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15]]
[[1,8,9,15],[2,7,10,14],[3,6,11,13],[4,5,9]]
我的播种方法非常复杂,组成小组的所有移动,弹出和拉平效果都更差。 我只是想知道是否有人对其他方法有任何建议。
def seed_sample(count,make_up='')
players = [] # init an empty array
1.upto(count) do |i|
players << i
end # => [1,2,3,4,5,6,...,count]
abcd = [] #init empty seed array
if make_up == 'foursomes'
4.times{abcd << players.shift(count / 4)}
elsif make_up == 'threesomes'
3.times{abcd << players.shift(count / 3)}
elsif make_up == 'twosomes'
2.times{abcd << players.shift(count / 2)}
else #mixed
a_pop = (count / 4) + 1 # number of a players to put in seed stack
abcd << players.shift(a_pop) # A players, always first
rem = players.count # s array is reduced by a_pop, so get count
if rem.modulo(3).zero?
3.times{abcd << players.shift(rem / 3)} # B & C & D players
elsif rem.modulo(3) == 1
abcd << players.shift(a_pop) # B players
2.times{abcd << players.shift(rem / 3)} # C & D players
else # rem.modulo(3) == 2
2.times{abcd << players.shift(a_pop)}# B & C players
abcd << players # remainder = D players
end
end
@seeds = abcd
return abcd
end
我正在接受RyanK的建议。 下面是也构成团队的测试种子方法。 所有信息都是从Class知道的,所以我只需要用此行替换大约100行代码-除非可以改进。
def test_seed(count,fours=nil,threes=nil,twos=nil)
players = Array(1..count) # => [1,2,3,4,5,6,...,count]
abcd = [] #init empty seed array
fours.times{abcd << players.shift(4)} if fours.present?
threes.times{abcd << players.shift(3)} if threes.present?
twos.times{abcd << players.shift(2)} if twos.present?
abcd.each_index do |s| # reverse odd stacks to distribute skills
unless s.modulo(2).zero?
abcd[s].reverse!
end
end
# shuffle stacks by taking card off top of each stack
seeded = []
abcd.count.times do
abcd.each_index do |i|
seeded << abcd[i].shift if abcd[i].present?
end
end
# now lets put the teams together
@teams = []
fours.times{@teams << seeded.shift(4)} if fours.present?
threes.times{@teams << seeded.shift(3)} if threes.present?
twos.times{@teams << seeded.shift(2)} if twos.present?
return abcd,seeded, @teams
end
好的,因此有以下几种方法可以使您的代码(您说的有效)更好:
def seed_sample(count,make_up='')
players = (1..count).to_a
abcd = [] #init empty seed array
num = 0
if make_up == 'foursomes'
num = 4
elsif make_up == 'threesomes'
num = 3
elsif make_up == 'twosomes'
num = 2
else
return
end
abcd << players.shift((count / num.to_f).ceil) while players.count > 0
abcd[1],abcd[3] = abcd[3],abcd[1] #Flip the second and fourth sub-arrays
#Of course, always assumes 4 groups and max of 16 people
@seeds = [[],[],[],[]]
abcd.each_with_index do |value, index|
4.times {|i| @seeds[i] = value[index]}
end
return @seeds
end
那至少应该让您入门。 最后一部分我不确定,因此请对其进行测试并确保其正常工作。
我采用了不同的方法,首先对所有球员进行了排序(其中#1是最好的,#13是最差的),然后使用分片来输出球队。
# Seed class
# Initialize with count of all players and make up of first team
# Sorts all of the players in pairs with the best and worst player
# as the first pair
class Seed
attr_accessor :count, :make_up
def initialize( count, make_up )
@count = count
@make_up = make_up
end
def run
sorted_array = sort
first_team( sorted_array )
other_teams( sorted_array )
end
def sort
arr = (1..@count).to_a
arr_new = []
sorting_iteration = (@count/2) + 1
sorting_iteration.times do
arr_new << arr.shift
arr_new << arr.pop unless arr.size == 0
end
arr_new
end
def first_team( sorted_array )
p sorted_array.slice(0, @make_up)
end
def other_teams( sorted_array )
all_others = sorted_array.slice(@make_up, @count)
all_others
other_make_up = @make_up - 1
p all_others.each_slice(other_make_up) { |a| p a }
end
end
round = Seed.new( 13, 4 )
round.run
因为我只是在寻求一种方法,所以可能不会有任何最佳答案。 我也遗漏了很多信息。 您不仅可以拥有混合团队,还可以将所有四人,所有三人,所有两人甚至一个人作为一个团队。 您最多可以出现3或4个玩家,而我看过的玩家超过30个。
感谢您的建议。 我编辑过的测试程序遇到了问题,在玩了几天纸牌游戏后,我想到了下一堂课。 它由用户在Teams类中提供并传递给Seed的选项驱动。
class Seed
# usage
# input a set of parameter build from selection of team formation options
# output an ordered array of seeds that match selection options
# params example
# {:team_makeup=>"mixed", :seed_method=>"seeded", :count=>13, :teams=>4, :teetimes=>4,
# :foursomes=>1, :threesomes=>3, :twosomes=>nil, :seed_size=>4, :first_size=>1}
attr_accessor :count, :params, :seeded
def initialize(seed_params)
@params = seed_params
@seeded = []
end
def build_seeded_array
players = Array(1..@params[:count]) # => [1,2,3,4,5,6,...,count]
seeds = seed_players(players)
@seeded = seeds_to_seeded(seeds,@params[:seed_size],@params[:first_size])
end
def seed_players(players,size=nil)
seeds = [] #init empty seed array
size = size ||= @params[:seed_size]
players_count = players.count
shift_size = players_count / size
remaining = players_count.modulo(size)
size.times{seeds << players.shift(shift_size)}
# with mixed teams, there will be players left, shift to last seed, then distribute all seeds
players.count.times{seeds[-1] << players.shift}
seeds = shift_seeds(seeds,remaining) unless remaining.zero?
seeds
end
def seeds_to_seeded(seeds,seed_size,numb)
seeded = seeded_seeds(seeds,numb)
players = seeds.flatten.sort
unless players.blank?
seed_size -= 1
numb = players.count / seed_size
seeds = seed_players(players,seed_size)
seeded << seeded_seeds(seeds,numb)
end
seeded.flatten
end
def seeded_seeds(seeds,numb)
seeds = distribution_swap(seeds)
seeded = []
numb.times do
seeds.each_index do |i|
seeded << seeds[i].shift if seeds[i].present?
end
end
seeded
end
def distribution_swap(seeds)
seeds.each_index do |s| # reverse odd stacks to distribute skills
unless s.modulo(2).zero?
seeds[s].reverse!
end
end
seeds
end
def shift_seeds(seeds,remaining)
# mixed team will stack last seed, need to shift them.
# [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19]]
# [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19]]
return(seeds) if @params[:foursomes].blank?
if remaining == 3
3.times{seeds[-2] << seeds[-1].shift}
2.times{seeds[-3] << seeds[-2].shift}
1.times{seeds[-4] << seeds[-3].shift}
elsif remaining == 2
2.times{seeds[-2] << seeds[-1].shift}
2.times{seeds[-3] << seeds[-2].shift}
1.times{seeds[-4] << seeds[-3].shift}
else
1.times{seeds[-2] << seeds[-1].shift}
1.times{seeds[-3] << seeds[-2].shift}
1.times{seeds[-4] << seeds[-3].shift}
end
seeds
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.