= rrschedule rrschedule makes it easier to generate round-robin schedules for sport leagues. To generate a schedule, it needs a team list, a season start date, the day(s) of the week where the games are played and some other options. It takes into consideration physical constraints such as the number of playing surfaces availables and game times. Each round of the round-robin is splitted into multiple gamedays that respect these constraints. Say for example that you want to generate a round-robin schedule for your 15-teams volleyball league. If there are only 3 volleyball fields available and that games are played each monday at 6PM and 8PM, this is technically impossible to complete one round in a single day. So rrschedule will put the remaining games of this round on the next gameday and will start a new round right after. == Installation gem install rrschedule require 'rrschedule' == Prepare the schedule Time.zone = "America/New_York" teams = ["Rockets","Jetpacks","Snakes","Cobras","Wolves","Huskies","Tigers","Lions", "Moose","Sprinklers","Pacers","Cyclops","Munchkins","Magicians","French Fries"] schedule=RRSchedule::Schedule.new( #array of teams that will compete against each other in the season :teams => teams, #list of available playing surfaces (volleyball fields, curling sheets, tennis courts, etc) :playing_surfaces => ["A","B","C","D"], #day(s) of the week where games are played :wdays => [3], #Season will start on... :start_date => Time.zone.parse("2010/10/13"), #array of dates WITHOUT games :exclude_dates => [ Time.zone.parse("2010/11/24"), Time.zone.parse("2010/12/15"), Time.zone.parse("2010/12/22"), Time.zone.parse("2010/12/29") ], #1 for Round Robin, 2 for Double Round Robin and so on. Default is 1 :cycles => 1, #Shuffle team order before each cycle. Default is true :shuffle_initial_order => true, #Times of the day where the games are played :game_times => ["10:00 AM", "1:00 PM"] ) == Generate the schedule schedule.generate == Playing with the output === human readable schedule puts schedule.to_s === Round by round... without the schedule info #If you have an ODD number of teams you will see a "dummy" opponent in each round schedule.rounds.each do |round| puts "Round ##{round.round}" round.games.each do |g| puts g.team_a.to_s + " Vs " + g.team_b.to_s end puts "\n" end === Team schedule test_team = "Sprinklers" games=schedule.by_team(test_team) puts "Schedule for team ##{test_team.to_s}" games.each do |g| puts "#{g.game_date.strftime("%Y-%m-%d")}: against #{g.team_a == test_team ? g.team_b.to_s : g.team_a.to_s} on playing surface ##{g.playing_surface} at #{g.game_time}" end === Face to Face games=schedule.face_to_face("Lions","Moose") puts "FACE TO FACE: Lions Vs Moose" games.each do |g| puts g.game_date.to_s + " on playing surface " + g.playing_surface.to_s + " at " + g.game_time.to_s end === Iterate through schedule schedule.gamedays.each do |gd,games| puts gd puts "====================" games.each do |g| puts g.team_a.to_s + " Vs " + g.team_b.to_s + " on playing surface ##{g.playing_surface} at #{g.game_time}" end puts "\n" end == Issues / Other Playing surfaces and game times need to be distributed evenly among all competitors. At the moment the same teams will play on the same surfaces and at the same game times most of the time. Note that it only happens when a full round can be completed on a single gameday. Otherwise there will be a natural rotation and teams will play on different surfaces and at different times between gamedays. Hope this gem will be useful to some people! You can read my blog here: www.rubyfleebie.com