Class: RRSchedule::Schedule

Inherits:
Object
  • Object
show all
Defined in:
lib/rrschedule.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Schedule

Returns a new instance of Schedule.



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/rrschedule.rb', line 9

def initialize(params={})
  @gamedays = []
  self.teams = params[:teams] || []
  self.cycles = params[:cycles] || 1
  self.shuffle = params[:shuffle].nil? ? true : params[:shuffle]
  self.balanced_gt = params[:balanced_gt].nil? ? true : params[:balanced_gt]
  self.balanced_ps = params[:balanced_ps].nil? ? true : params[:balanced_ps]      
  self.exclude_dates = params[:exclude_dates] || []
  self.start_date = params[:start_date] || Date.today
  self.group_flights = params[:group_flights].nil? ? true : params[:group_flights]
  self.rules = params[:rules] || []
  self
end

Instance Attribute Details

#balanced_gtObject

Returns the value of attribute balanced_gt.



7
8
9
# File 'lib/rrschedule.rb', line 7

def balanced_gt
  @balanced_gt
end

#balanced_psObject

Returns the value of attribute balanced_ps.



7
8
9
# File 'lib/rrschedule.rb', line 7

def balanced_ps
  @balanced_ps
end

#cyclesObject

Returns the value of attribute cycles.



7
8
9
# File 'lib/rrschedule.rb', line 7

def cycles
  @cycles
end

#exclude_datesObject

Returns the value of attribute exclude_dates.



7
8
9
# File 'lib/rrschedule.rb', line 7

def exclude_dates
  @exclude_dates
end

#flightsObject (readonly)

Returns the value of attribute flights.



6
7
8
# File 'lib/rrschedule.rb', line 6

def flights
  @flights
end

#gamedaysObject (readonly)

Returns the value of attribute gamedays.



6
7
8
# File 'lib/rrschedule.rb', line 6

def gamedays
  @gamedays
end

#group_flightsObject

Returns the value of attribute group_flights.



7
8
9
# File 'lib/rrschedule.rb', line 7

def group_flights
  @group_flights
end

#roundsObject (readonly)

Returns the value of attribute rounds.



6
7
8
# File 'lib/rrschedule.rb', line 6

def rounds
  @rounds
end

#rulesObject

Returns the value of attribute rules.



7
8
9
# File 'lib/rrschedule.rb', line 7

def rules
  @rules
end

#shuffleObject

Returns the value of attribute shuffle.



7
8
9
# File 'lib/rrschedule.rb', line 7

def shuffle
  @shuffle
end

#start_dateObject

Returns the value of attribute start_date.



7
8
9
# File 'lib/rrschedule.rb', line 7

def start_date
  @start_date
end

#teamsObject

Returns the value of attribute teams.



7
8
9
# File 'lib/rrschedule.rb', line 7

def teams
  @teams
end

Instance Method Details

#generate(params = {}) ⇒ Object

This will generate the schedule based on the various parameters



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rrschedule.rb', line 24

def generate(params={})
  raise "You need to specify at least 1 team" if @teams.nil? || @teams.empty?
  raise "You need to specify at least 1 rule" if @rules.nil? || @rules.empty?

  arrange_flights
  init_stats

  @gamedays = []; @rounds = []


  @flights.each_with_index do |teams,flight_id|
    current_cycle = current_round = 0
    teams = teams.sort_by{rand} if @shuffle

    #loop to generate the whole round-robin(s) for the current flight
    begin
      t = teams.clone
      games = []

      #process one round
      while !t.empty? do
        team_a = t.shift
        team_b = t.reverse!.shift
        t.reverse!

        x = (current_cycle % 2) == 0 ? [team_a,team_b] : [team_b,team_a]

        matchup = {:team_a => x[0], :team_b => x[1]}
        games << matchup
      end
      #done processing round

      current_round += 1

      #Team rotation (the first team is fixed)
      teams = teams.insert(1,teams.delete_at(teams.size-1))

      #add the round in memory
      @rounds ||= []
      @rounds[flight_id] ||= []
      @rounds[flight_id] << Round.new(
        :round => current_round,
        :cycle => current_cycle + 1,
        :round_with_cycle => current_cycle * (teams.size-1) + current_round,
        :flight => flight_id,
        :games => games.collect { |g|
          Game.new(
            :team_a => g[:team_a],
            :team_b => g[:team_b]
          )
        }
      )
      #done adding round

      #have we completed a full round-robin for the current flight?
      if current_round == teams.size-1
        current_cycle += 1
        current_round = 0 if current_cycle < self.cycles
      end

    end until current_round == teams.size-1 && current_cycle==self.cycles
  end

  dispatch_games(@rounds)
  self
end

#round_robin?(flight_id = 0) ⇒ Boolean

returns true if the generated schedule is a valid round-robin (for testing purpose)

Returns:

  • (Boolean)


116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rrschedule.rb', line 116

def round_robin?(flight_id=0)
  #each round-robin round should contains n-1 games where n is the nbr of teams (:dummy included if odd)
  return false if self.rounds[flight_id].size != (@flights[flight_id].size*self.cycles)-self.cycles

  #check if each team plays the same number of games against each other
  @flights[flight_id].each do |t1|
    @flights[flight_id].reject{|t| t == t1}.each do |t2|
      return false unless face_to_face(t1,t2).size == self.cycles || [t1,t2].include?(:dummy)
    end
  end
  return true
end

#to_sObject

human readable schedule



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rrschedule.rb', line 101

def to_s
  res = ""
  res << "#{self.gamedays.size.to_s} gamedays\n"
  self.gamedays.each do |gd|
    res << gd.date.strftime("%Y-%m-%d") + "\n"
    res << "==========\n"
    gd.games.sort{|g1,g2| g1.gt == g2.gt ? g1.ps <=> g2.ps : g1.gt <=> g2.gt}.each do |g|
      res << "#{g.ta.to_s} VS #{g.tb.to_s} on playing surface #{g.ps} at #{g.gt.strftime("%I:%M %p")}\n"
    end
    res << "\n"
  end
  res
end

#total_nbr_gamesObject



91
92
93
94
95
96
97
98
# File 'lib/rrschedule.rb', line 91

def total_nbr_games
  total=0

  @flights.each do |teams|
     total += (teams.size / 2) * (teams.size-1)
  end
  total
end