簡體   English   中英

尋找為迷你比賽創建種子高爾夫隊的方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM