schuurthing / tapi

0 stars 0 forks source link

As a user, I want to provide a list of names so that I can receive a list of matchups for a Round Robin competition. #2

Open schuurthing opened 5 years ago

schuurthing commented 5 years ago

Why

Round Robin is one of the easiest ways to rank N number of competitors in anything. For that reason, it will be our first case. The simplest form of this is to receive a list of names and generate the resulting list of matchups.

Acceptance Criteria

If I pass["Will", "Bobby"] as my competitors, I receive a resulting JSON that tells me there'd be 1 matchup, and it's ["Will", "Bobby"] If I pass ['Will', 'Bobby', 'Joe', 'Tommy', 'Jono'], I receive a resulting JSON that tells me there'd be 10 unique matchups

[["Joe", "Tommy"],
   ["Bobby", "Tommy"],
   ["Joe", "Will"],
   ["Tommy", "Will"],
   ["Bobby", "Jono"],
   ["Jono", "Will"],
   ["Bobby", "Will"],
   ["Joe", "Jono"],
   ["Jono", "Tommy"],
   ["Bobby", "Joe"]]

MVP Assumptions: These fields will soon need to be variable, but let's build the thing with defaults for:

  1. Assume each player will face each other player 1v1. Soon we'll need a variable competitors per matchup, allowing for a 4-player smash game for example.
  2. Assume each player will face each other player as specified above, but in only one match. Soon we'll need a variable games in each matchup. For example: in the world cup, each team plays each other twice.
  3. Assume the inputs will only be player names, and no grouping into teams is required.
schuurthing commented 5 years ago
players =  ['Will', 'Derek', 'Joe', 'Tommy', 'Jono', 'Ryan']
players_in_game = 4
pre_drawn_teams = params[:pre_drawn_teams]
seeded_tournament
games_per_matchup = 1
team_game = false
stay_with_partner = team_game && true
rotate_partners = team_game && !stay_with_partner

def generate_unique_round_robin_matchup(players)
  matchups = []
  players.each do |root_player|
    remaining_players = players - [root_player]
    remaining_players.each_with_index do |remaining_player, index|
      group = [root_player]
      length = players_in_game - 1
      group.concat(remaining_players.slice(index, length))
      if index + length > remaining_players.length
        extras_length = index + length - remaining_players.length
        group.concat(remaining_players.slice(0, extras_length))
      end
      matchups.push(group)
    end
  end

  unique_matchups = matchups.map(&:sort).uniq

  {
    matchup_count: unique_matchups.count,
    matchups: unique_matchups.shuffle,
  }
end

Proof of concept I made this weekend, open for dissection and disembodiment