Class: Playoffs::Series

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/playoffs/series.rb

Overview

A node in a directed acyclic graph which represents a current or future series between two teams. The teams are able to be resolved later in the graph by connecting series together: a contestestant does not have to be a team, it can be the promise of a team via another series (as the winner or loser).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(best_of: BestOf.new) ⇒ Series

Returns a new instance of Series.



31
32
33
34
35
# File 'lib/playoffs/series.rb', line 31

def initialize(best_of: BestOf.new)
  @contestants = T.let([], T::Array[Contestant])
  @best_of = best_of
  @winners_by_game = T.let([], T::Array[Team])
end

Instance Attribute Details

#best_ofObject (readonly)

Returns the value of attribute best_of.



22
23
24
# File 'lib/playoffs/series.rb', line 22

def best_of
  @best_of
end

#contestantsObject (readonly)

Returns the value of attribute contestants.



13
14
15
# File 'lib/playoffs/series.rb', line 13

def contestants
  @contestants
end

#loser_advances_toObject

Returns the value of attribute loser_advances_to.



19
20
21
# File 'lib/playoffs/series.rb', line 19

def loser_advances_to
  @loser_advances_to
end

#winnerObject (readonly)

Returns the value of attribute winner.



28
29
30
# File 'lib/playoffs/series.rb', line 28

def winner
  @winner
end

#winner_advances_toObject

Returns the value of attribute winner_advances_to.



16
17
18
# File 'lib/playoffs/series.rb', line 16

def winner_advances_to
  @winner_advances_to
end

#winners_by_gameObject (readonly)

Returns the value of attribute winners_by_game.



25
26
27
# File 'lib/playoffs/series.rb', line 25

def winners_by_game
  @winners_by_game
end

Instance Method Details

#games_playedObject



75
76
77
# File 'lib/playoffs/series.rb', line 75

def games_played
  winners_by_game.length
end

#loserObject



52
53
54
55
56
# File 'lib/playoffs/series.rb', line 52

def loser
  return unless winner

  (teams - [winner]).first
end

#loser_of(series) ⇒ Object



140
141
142
143
144
# File 'lib/playoffs/series.rb', line 140

def loser_of(series)
  series.loser_advances_to = self

  add(series)
end

#not_over?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/playoffs/series.rb', line 85

def not_over?
  winner.nil?
end

#over?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/playoffs/series.rb', line 80

def over?
  !not_over?
end

#register(team) ⇒ Object



147
148
149
# File 'lib/playoffs/series.rb', line 147

def register(team)
  add(team)
end

#teamsObject



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/playoffs/series.rb', line 38

def teams
  contestants.map do |contestant|
    case contestant
    when Team
      contestant
    when Series
      contestant.winner_advances_to == self ? contestant.winner : contestant.loser
    else
      T.absurd(contestant)
    end
  end.compact
end

#to_sObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/playoffs/series.rb', line 115

def to_s
  team_lines = teams.map do |contestant|
    [contestant.to_s, win_count_for(contestant)]
  end

  team_lines += [['TBD', 0]] * (2 - team_lines.length)

  [
    valid? ? nil : '!INVALID!',
    best_of.to_s,
    self.class.to_s.split('::').last,
    team_lines,
    over? ? 'Done' : nil
  ].compact.flatten.join('::')
end

#valid?Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/playoffs/series.rb', line 90

def valid?
  return false if contestants.length != 2

  contestants.each do |contestant|
    case contestant
    when Team
      # Teams are always valid
    when Series
      # short-circuit because we cant be valid if the previous series (children) aren't.
      return false unless contestant.valid?
    else
      T.absurd(contestant)
    end
  end

  true
end

#win(team) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/playoffs/series.rb', line 59

def win(team)
  raise NotEnoughTeamsError unless teams.length == 2

  saved_team = teams.find { |t| t == team }

  raise InvalidTeamError unless saved_team
  raise SeriesOverError if over?

  winners_by_game << saved_team

  @winner = T.let(saved_team, T.nilable(Team)) if winner?(saved_team)

  self
end

#win_count_for(team) ⇒ Object



109
110
111
# File 'lib/playoffs/series.rb', line 109

def win_count_for(team)
  winners_by_game.select { |winner| winner == team }.length
end

#winner_of(series) ⇒ Object



133
134
135
136
137
# File 'lib/playoffs/series.rb', line 133

def winner_of(series)
  series.winner_advances_to = self

  add(series)
end