Class: BracketTree::Bracket::Base

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/bracket_tree/bracket/base.rb

Overview

Basic bracketing functionality. If you wish to create a custom bracket type, inherit from this class to provide easy access to bracketing.

Example:

class MLGDouble < BracketTree::Bracket::Base
  template BracketTree::Template::DoubleElimination
end

bracket = MLGDouble.by_size 8

This creates a bracket based on the standard double elimination template class. The template parameter can be any class that inherits from BracketTree::Template::Base, though.

class MLGDoubleTemplate < BracketTree::Template::Base
  def self.location
    File.join File.dirname(__FILE__), 'templates', 'mlg_double'
  end
end

class MLGDouble < BracketTree::Bracket::Base
  template MLGDoubleTemplate
end

Direct Known Subclasses

DoubleElimination, SingleElimination

Defined Under Namespace

Classes: NoTemplateError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Base

Returns a new instance of Base.



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/bracket_tree/bracket/base.rb', line 60

def initialize options = {}
  @insertion_order = []
  @matches = []

  if options[:matches]
    options[:matches].each do |m|
      @matches << Match.new(m)
    end
  end

  @seed_order = options[:seed_order] if options[:seed_order]
end

Instance Attribute Details

#insertion_orderObject

Returns the value of attribute insertion_order.



58
59
60
# File 'lib/bracket_tree/bracket/base.rb', line 58

def insertion_order
  @insertion_order
end

#matchesObject

Returns the value of attribute matches.



58
59
60
# File 'lib/bracket_tree/bracket/base.rb', line 58

def matches
  @matches
end

#rootObject

Returns the value of attribute root.



58
59
60
# File 'lib/bracket_tree/bracket/base.rb', line 58

def root
  @root
end

#seed_orderObject

Returns the value of attribute seed_order.



58
59
60
# File 'lib/bracket_tree/bracket/base.rb', line 58

def seed_order
  @seed_order
end

Class Method Details

.by_size(size, options = {}) ⇒ Object



30
31
32
# File 'lib/bracket_tree/bracket/base.rb', line 30

def by_size size, options = {}
  generate_from_template @template, size
end

.generate_from_template(template, size) ⇒ Object

Generates a blank bracket object from the passed Template class for the passed size

Parameters:

  • BracketTree::Template::Base

    template - the Template the bracket is based on

  • Fixnum

    size - bracket size

Returns:

  • BracketTree::Bracket::Base bracket - a blank bracket with hash placeholders



45
46
47
48
49
50
51
52
53
54
# File 'lib/bracket_tree/bracket/base.rb', line 45

def generate_from_template template, size
  template = template.by_size size
  bracket = new(matches: template.matches, seed_order: template.seed_order)

  template.seats.each do |position|
    bracket.add position, {}
  end

  bracket
end

.template(class_name) ⇒ Object



34
35
36
# File 'lib/bracket_tree/bracket/base.rb', line 34

def template class_name
  @template = class_name
end

Instance Method Details

#add(position, data) ⇒ Object

Adds a Node at the given position, setting the data as the payload. Maps to binary tree under the hood. The ‘data` can be any serializable object.

Parameters:

  • Fixnum

    position - Seat position to add

  • Object

    data - the player object to store in the Seat position



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/bracket_tree/bracket/base.rb', line 78

def add position, data
  node = Node.new position, data
  @insertion_order << position

  if @root.nil?
    @root = node
  else
    current = @root
    loop do
      if node.position < current.position
        if current.left.nil?
          current.left = node
          break
        else
          current = current.left
        end
      elsif node.position > current.position
        if current.right.nil?
          current.right = node
          break
        else
          current = current.right
        end
      else
        break
      end
    end
  end
end

#at(position) ⇒ Object



165
166
167
# File 'lib/bracket_tree/bracket/base.rb', line 165

def at position
  find { |n| n.position == position }
end

#each(&block) ⇒ Object



146
147
148
# File 'lib/bracket_tree/bracket/base.rb', line 146

def each(&block)
  in_order(@root, block)
end

#in_order(node, block) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/bracket_tree/bracket/base.rb', line 213

def in_order(node, block)
  if node
    unless node.left.nil?
      in_order(node.left, block)
    end

    block.call(node)

    unless node.right.nil?
      in_order(node.right, block)
    end
  end
end

#match_loser(seat) ⇒ Object

Inverse of ‘match_winner`, progresses the bracket based on seat. See `match_winner` for more details

Parameters:

  • Fixnum

    seat - losing seat position

Returns:

  • Boolean result - result of progression



202
203
204
205
206
207
208
209
210
211
# File 'lib/bracket_tree/bracket/base.rb', line 202

def match_loser seat
  match = @matches.find { |m| m.include? seat }
  
  if match
    winning_seat = match.seats.find { |s| s != seat }
    match_winner winning_seat
  else
    return false
  end
end

#match_winner(seat) ⇒ Object

Progresses the bracket by using the stored ‘matches` to copy data to the winning and losing seats. This facilitates match progression without manually manipulating bracket positions

Parameters:

  • Fixnum

    seat - winning seat position

Returns:

  • Boolean result - result of progression



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/bracket_tree/bracket/base.rb', line 177

def match_winner seat
  match = @matches.find { |m| m.include? seat }

  if match
    losing_seat = match.seats.find { |s| s != seat }

    if match.winner_to
      replace match.winner_to, at(seat).payload
    end

    if match.loser_to
      replace match.loser_to, at(losing_seat).payload
    end

    return true
  else
    return false
  end
end

#replace(position, payload) ⇒ Object

Replaces the data at a given node position with new payload. This is useful for updating bracket data, replacing placeholders with actual data, seeding, etc..

Parameters:

  • position (Fixnum)
    • the node position to replace

  • payload
    • the new payload object to replace



114
115
116
117
118
119
120
121
122
# File 'lib/bracket_tree/bracket/base.rb', line 114

def replace position, payload
  node = at position
  if node
    node.payload = payload
    true
  else
    nil
  end
end

#seatsObject Also known as: to_a

Array of Seats mapping to the individual positions of the bracket tree. The order of the nodes is important, as insertion in this order maintains the binary tree

Returns:

  • Array seats



159
160
161
# File 'lib/bracket_tree/bracket/base.rb', line 159

def seats
  entries.sort_by { |node| @insertion_order.index(node.position) }
end

#seed(players) ⇒ Object

Seeds bracket based on ‘seed_order` value of bracket. Provide an iterator with players that will be inserted in the appropriate location. Will raise a SeedLimitExceededError if too many players are sent, and a NoSeedOrderError if the `seed_order` attribute is nil

Parameters:

  • players (Enumerable)
    • players to be seeded



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/bracket_tree/bracket/base.rb', line 130

def seed players
  if @seed_order.nil?
    raise NoSeedOrderError, 'Bracket does not have a seed order.'
  elsif players.size > @seed_order.size
    raise SeedLimitExceededError, 'cannot seed more players than seed order list.'
  else
    @seed_order.each do |position|
      replace position, players.shift
    end
  end
end

#to_hObject



150
151
152
# File 'lib/bracket_tree/bracket/base.rb', line 150

def to_h
  @root.to_h
end

#winnerObject



142
143
144
# File 'lib/bracket_tree/bracket/base.rb', line 142

def winner
  @root.payload
end